The big picture

How building an app works

Every app you build follows the same path. Use this as your map โ€” the checklist tab walks through each step in detail.

Day 1
๐Ÿ™ GitHub account github.com โ€” free
โ†’
๐Ÿ›  Install tools Git, Node, Docker,
Claude Code
โ†’
๐Ÿ“ Create project folder mkdir my-app
cd my-app
โ†“
Plan
๐Ÿ’ก Your idea 1 sentence
โ†’
๐Ÿค– Grill Me skill AI interviews you
โ†’
๐Ÿ“„ frontend.md React + Vite + shadcn
+
๐Ÿ“„ backend.md Node + Express + Postgres
+
๐Ÿ“„ design.md shadcn defaults
+
๐Ÿ“„ deploy.md Docker + Nginx
โ†“
Build
๐Ÿค– Scaffold project AI creates all
starter files
โ†’
๐Ÿ“‹ AI makes a plan You say "go"
โ†’
๐Ÿ”จ Build one feature You say "next"
after each step
โ†’
๐Ÿ‹ docker compose up Runs everything
in Docker
โ†’
๐ŸŒ Open browser localhost:3000
(Docker's port)
โ†’
๐Ÿ” Repeat per feature Build โ†’ test โ†’
next feature
๐Ÿ”Œ Ports explained: Your app has three parts running at once inside Docker. You only open one URL in your browser โ€” localhost:3000 (the frontend, served by Docker). The frontend talks to the backend at localhost:4000 automatically. The database runs at localhost:5432 โ€” you never open this directly. Vite runs on port 5173 inside the container, but Docker maps it to 3000 on your machine โ€” so you always use 3000.
โ†“
GitHub
๐Ÿ”‘ Access token GitHub โ†’ Settings
โ†’ Dev settings
โ†’
๐Ÿ™ Create repo One per project
โ†’
๐Ÿ’พ git add + commit Save a snapshot
โ†’
โฌ†๏ธ git push Upload to GitHub
โ†“
Deploy
๐Ÿ–ง SSH to VPS ssh [email protected]
โ†’
๐Ÿ“ฅ git clone Download from GitHub
โ†’
๐Ÿ” Create .env Add passwords
+ secrets
โ†’
๐Ÿ‹ docker compose up -d Start in background
โ†’
๐ŸŒ Nginx + Certbot Domain + free HTTPS
โ†’
๐Ÿš€ Live! On the internet
โ†‘ Click any row to jump to that section in the checklist
Day 1 (once ever)
Plan
Build & test (repeats per feature)
Save to GitHub
Deploy to server
Your app when running locally
โ— Frontend โ€” localhost:3000 (React, via Docker)
โ— Backend API โ€” localhost:4000 (Express)
โ— Database โ€” localhost:5432 (PostgreSQL โ€” internal only)

You only ever open localhost:3000 in your browser. The frontend handles talking to the backend for you.
Your default tech stack
Frontend: React + Vite + Tailwind + shadcn/ui
Backend: Node.js + Express + Prisma
Database: PostgreSQL
Deploy: Docker + Nginx + Certbot (free SSL)

See full defaults & answers โ†’
Before you start

Terminal basics

The terminal is a text-based way to control your computer. You'll use it constantly. Here's everything you need to know to get started.

How to open the terminal

On Mac: Press Cmd + Space, type Terminal, press Enter.

On Windows: Press the Windows key, type cmd or PowerShell, press Enter.

What you'll see: A black or white window with a blinking cursor. That cursor is waiting for you to type a command.

The most important concept: you're always "inside" a folder

The terminal always has a "current location" โ€” a folder it's working inside. Think of it like being inside a room. Most commands run relative to where you currently are. You need to navigate to the right folder before running commands.

The commands you'll actually use

See where you are right now
pwd
Prints something like /Users/yourname or C:\Users\yourname โ€” that's your current folder.
See what's inside the current folder
ls
Lists all the files and folders inside your current location. Like opening a folder in Finder/Explorer but in text.
Move into a folder (cd = "change directory")
cd Documents
Moves you into the Documents folder. The folder must exist and be inside your current location.
Tip: Type the first few letters of a folder name and press Tab โ€” the terminal will autocomplete it for you.
Go back up one folder (like clicking the back button)
cd ..
The two dots .. always means "the folder above this one".
Create a new folder
mkdir my-app
Creates a new folder called my-app inside your current location. You still need to cd my-app to go inside it.
Create a folder and immediately go inside it
mkdir my-app && cd my-app
The && means "do this, then do that". You'll use this pattern a lot.
Clear the screen (when it gets messy)
clear

See it in action

Here's what a typical session looks like when starting a new project:

Terminal
~ $ pwd
/Users/yourname
~ $ cd Documents
~/Documents $ mkdir my-expense-app
~/Documents $ cd my-expense-app
~/Documents/my-expense-app $ ls
(empty โ€” nothing here yet)
~/Documents/my-expense-app $ _
Notice how the prompt changes as you move around โ€” it always shows your current location.
One-time setup

Install your tools

Do this once on your computer. You never need to do it again.

1. Install Node.js

Node.js lets your computer run JavaScript outside of a browser โ€” this is how your backend server works.

Go to nodejs.org and download the LTS version (the one that says "Recommended For Most Users"). Run the installer.
Check it installed correctly
node --version
Should print something like v20.11.0. Any number is fine โ€” it just means it's installed.

2. Install Git

Git is the tool that saves your code and talks to GitHub.

Mac: Run git --version in the terminal โ€” Mac will offer to install it automatically if it's missing.

Windows: Go to git-scm.com and download the installer. During install, accept all the defaults.
Check it installed correctly
git --version
Should print something like git version 2.39.0.
Set your name and email (Git uses this to label your saves)
git config --global user.name "Your Name"
git config --global user.email "[email protected]"

3. Install Docker Desktop

Docker packages your app and everything it needs into neat containers โ€” this is how you run and deploy it.

Go to docker.com/products/docker-desktop and download Docker Desktop for your operating system. Run the installer, then open Docker Desktop and let it start up (it runs in the background).
Check it installed correctly
docker --version
Important: Docker Desktop must be open and running (you'll see a whale icon in your menu bar/taskbar) before you can use docker commands.

4. Install Claude Code

Claude Code is the AI agent you'll use to build your app. It runs inside your terminal and can read and write files directly in your project.

Install Claude Code
npm install -g @anthropic-ai/claude-code
Start it (run from inside your project folder)
claude
The first time you run it, Claude Code will ask you to log in with your Anthropic account. Follow the prompts.
Using a different AI? That's fine โ€” Cursor, GitHub Copilot, and ChatGPT all work. The prompts in this guide are tool-agnostic. Just paste them into whatever AI you're using.

5. Install the Grill Me skill

The Grill Me skill teaches Claude Code how to properly interview you about your app idea and generate structured plan files.

Download it from GitHub:
Go to github.com/mattpocock/skills โ†’ productivity/grill-me/SKILL.md
Click the Raw button, then save the page as grill-me.md on your computer.
For Claude Code โ€” run inside your project folder
mkdir -p .claude/skills
# Then move grill-me.md into .claude/skills/
For Cursor: Settings โ†’ Rules for AI โ†’ paste the file contents.
For any other AI: paste the file contents at the top of your first message.
โœ… All done? You're ready to build. Head to the Build checklist and start with Phase 1.
Defaults & answers

When the AI grills you, use these

The AI will ask you questions during the planning phase. Most of them have a sensible default. Use these answers if you're not sure.

๐Ÿ–ฅ Frontend

FrameworkReact
Build toolVite
StylingTailwind CSS
Componentsshadcn/ui
RoutingReact Router v7
Data fetchingTanStack Query
Mobile first?Yes

โš™๏ธ Backend

RuntimeNode.js
FrameworkExpress
DatabasePostgreSQL
ORMPrisma
AuthJWT tokens
ValidationZod
File uploadsMulter

๐Ÿ‹ Deployment

ContainersDocker Compose
Web serverNginx
SSL (https)Certbot (free)
Server OSUbuntu 22.04
Frontend port3000
Backend port4000
DB port5432

๐ŸŽจ Design

FontInter
IconsLucide
Color modeLight (default)
Componentsshadcn/ui defaults
SpacingTailwind default
ResponsiveMobile first
Dark modeNo (for now)
Common questions

Safe answers for the questions you'll be asked

If you get a question you genuinely don't know how to answer, these defaults work for almost every web app.

"Do you need user accounts / login?"
Say yes if people will have their own data. Say no if it's a single-user internal tool.
"What happens when someone isn't logged in?"
Redirect them to a login page.
"Do you need email notifications?"
No for now โ€” easy to add later.
"What should happen if the API is down?"
Show an error message and a Retry button.
"Do you need an admin panel?"
No โ€” manage things directly in the database for now.
"Should data be paginated?"
Yes โ€” 20 items per page.
"Do you need file or image uploads?"
Only say yes if you actually need it. If unsure, say no for now.
"How should the app look?"
Clean and minimal, using shadcn/ui defaults.
If you genuinely don't know the answer to something, just say: "Use whatever is simplest for a small web app." The AI will decide for you.
Per-project checklist

Do this for every app you build

Tick each step as you go. Click any step to expand the full instructions. Your progress saves automatically.

0 of 0 steps completed
Start here
Understand what you're building
Read this before anything else. It takes 5 minutes and will make everything else make sense.
What is a web app? Frontend, backend, and database explained
โ–ผ
Every web app you've ever used โ€” Instagram, Airbnb, your bank's website โ€” is made of the same three pieces. Understanding what they are makes everything in this guide click.
๐Ÿ–ฅ
Frontend
Everything you can see and click. Buttons, forms, pages, menus. Built with React.
โš™๏ธ
Backend
The brain โ€” invisible logic that runs on a server. Handles logins, business rules, sending emails. Built with Node.js + Express.
๐Ÿ—„๏ธ
Database
Where data is stored permanently. Users, posts, orders โ€” everything that needs to be saved and retrieved. We use PostgreSQL.
A real example โ€” logging into Instagram:
1. You type your email and password into a form โ†’ that's the frontend
2. The frontend sends those details to Instagram's server โ†’ the backend checks if they match
3. The backend looks up your account in the database
4. If it matches, the backend tells the frontend "logged in!" and your feed loads
๐Ÿ“š Want to learn more? freeCodeCamp: Frontend vs Backend explained โ€” good 5-minute read.
What does the AI actually do? What do YOU do?
โ–ผ
A common misconception: the AI doesn't just hand you a finished app. You're working together. Here's the division of labour.
๐Ÿค– The AI does
โœ“ Writes all the code
โœ“ Decides the technical approach
โœ“ Fixes errors and bugs
โœ“ Creates files and folders
โœ“ Explains what it built
๐Ÿ‘ค You do
โœ“ Describe what you want
โœ“ Test the app and spot problems
โœ“ Make decisions about features
โœ“ Run commands in the terminal
โœ“ Deploy to the server
The key skill isn't coding โ€” it's learning to describe what you want clearly, test thoroughly, and give good feedback to the AI when something's wrong. That's what this guide teaches.
What to do when you get stuck โ€” the beginner's debugging mindset
โ–ผ
You will get stuck. Everyone does. The difference between people who give up and people who succeed is knowing what to do when that happens. Here's the process.
Step 1 โ€” Read the error message
Error messages look scary but they almost always tell you exactly what went wrong. Read the last few lines carefully. Look for words like "not found", "undefined", "cannot connect", "permission denied". These are clues.
Step 2 โ€” Paste it to your AI
Copy the full error text and tell your AI: "I got this error. What does it mean and how do I fix it?" then paste the error. This fixes 80% of problems instantly.
Step 3 โ€” Google the exact error message
Copy the error message and paste it into Google. Add "fix" or "solution" at the end. Almost every error you'll ever see has been solved by someone on Stack Overflow or GitHub.
Step 4 โ€” Start smaller
If something big isn't working, break it down. Try to get just one tiny piece working first. Ask the AI: "Ignore everything else โ€” let's just make [one small piece] work first."
๐Ÿ“š Learn more: How to think like a programmer โ€” freeCodeCamp. Worth bookmarking.
Day 1
Set up your computer
Do this once ever โ€” you never need to repeat these steps for future projects.
Open the terminal
โ–ผ
The terminal is a text window where you type commands to control your computer. Developers use it for almost everything โ€” installing tools, running apps, managing files. You only need to know about 10 commands to get started.
On Mac: Press Cmd + Space, type Terminal, press Enter.

On Windows: Press the Windows key, type cmd, press Enter. (For a better experience on Windows, consider Windows Terminal โ€” free from the Microsoft Store.)
You'll see a mostly empty window with a blinking cursor. That's completely normal โ€” it's waiting for you to type a command. See the Terminal basics tab to learn the commands you'll actually use.
๐Ÿ“š Learn more: Command line for beginners โ€” freeCodeCamp. Takes about 20 minutes and covers everything you need.
Create a free GitHub account
โ–ผ
GitHub is a website that stores your code safely online โ€” like Google Drive, but specifically for code. Every professional developer uses it. You create your account here first, because the next step (installing Git) needs your GitHub email address.
1. Go to github.com
2. Click Sign up in the top right
3. Enter your email, create a password, choose a username โ€” keep the username professional, people will see it
4. Verify your email address when GitHub sends you a confirmation
5. On the "Tell us about yourself" screen โ€” click Skip personalisation
Why GitHub matters:
โ€ข Safety net โ€” if your laptop dies, all your code is still safe online
โ€ข Deployment bridge โ€” your server downloads code directly from GitHub
โ€ข History โ€” every save is stored, you can undo any mistake
โ€ข Portfolio โ€” other developers (and employers) look at GitHub to see what you've built
๐Ÿ“š Learn more: About GitHub and Git โ€” official GitHub docs, beginner friendly.
Install Git and connect it to your GitHub account
โ–ผ
Git is a program that runs on your computer and tracks changes to your code over time โ€” like "track changes" in a Word document, but for entire projects. It's also what sends your code up to GitHub. You install it once and configure it with your name and email.
Mac: Open the terminal, type git --version and press Enter. If Git isn't installed, Mac will pop up a window offering to install it โ€” click Install and wait for it to finish.

Windows: Go to git-scm.com โ†’ click the big green Download button โ†’ run the installer โ†’ click Next through every screen accepting all defaults. When it asks about the default editor, choose Notepad if you're unsure.
Tell Git your name and email โ€” use the same email as your GitHub account
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Run each line one at a time, pressing Enter after each. Replace the values in quotes with your own details. This labels your saved work so GitHub knows it came from you.
๐Ÿ“š Learn more: What is Git? โ€” Atlassian's beginner guide. The best plain-English explanation of why Git exists.
Install Node.js
โ–ผ
Node.js lets your computer run JavaScript outside a browser โ€” it's the engine that powers your app's backend server. You also need it because most developer tools (including Claude Code) are installed through Node's package manager, called npm. Install it once and forget it.
Go to nodejs.org โ†’ download the version that says LTS โ€” Recommended For Most Users โ†’ run the installer, click through accepting all defaults.
Check it installed โ€” open the terminal and run this
node --version
Should print something like v20.11.0. Any version number means it worked. While you're here, also check npm installed: npm --version โ€” this should also print a number.
What is npm? npm (Node Package Manager) is a tool that comes with Node.js. Developers use it to install tools and libraries with a single command. When you see npm install ... in this guide, it means "download and install this tool".
Install Docker Desktop
โ–ผ
Docker packages your entire app โ€” frontend, backend, and database โ€” into self-contained boxes called "containers". This means your app runs exactly the same way on your laptop as it does on your server. No more "it works on my machine" problems.
Go to docker.com/products/docker-desktop โ†’ download for your operating system โ†’ run the installer โ†’ open Docker Desktop from your Applications folder (Mac) or Start Menu (Windows) and let it fully start up. It runs in the background.
Check it's running
docker --version
Important: Docker Desktop must be open and running โ€” look for the whale ๐Ÿณ icon in your menu bar (Mac) or taskbar (Windows). If it's not there, open Docker Desktop first and wait for it to fully load before running any docker commands.
๐Ÿ“š Learn more: What is a container? โ€” Docker's own beginner explanation, with a good analogy.
Install Claude Code โ€” your AI coding agent
โ–ผ
Claude Code is the AI that will write the code for you. Unlike a normal chatbot where you copy-paste code back and forth, Claude Code runs directly in your terminal โ€” it can read and create files in your project on its own, so you just describe what you want and it builds it.
Install it using npm (the Node tool you installed above)
npm install -g @anthropic-ai/claude-code
The -g means "install globally" โ€” available from any folder on your computer, not just one project. This will take a minute. You'll see a progress bar.
Start it (run from inside your project folder)
claude
The first time you run it, Claude Code opens a browser window and asks you to sign up or log in with an Anthropic account. Do that, then come back to the terminal โ€” it'll be waiting for you.
Using Cursor, Windsurf, or another AI tool instead? That's fine โ€” all the prompts in this guide work with any AI. Just paste them into your tool's chat window. Cursor is a popular alternative that has a visual code editor built in.
Download and install the Grill Me skill
โ–ผ
The Grill Me skill is a small instruction file that teaches your AI how to interview you about your app idea โ€” asking the right questions, one at a time, and then writing up your plan files at the end. Without it, the AI might just start building without understanding what you actually want.
Download it here:
Go to github.com/mattpocock/skills โ†’ productivity/grill-me/SKILL.md
Click the Raw button in the top right โ†’ right-click anywhere on the page โ†’ Save As โ†’ save the file as grill-me.md somewhere you can find it (like your Desktop).

For Claude Code โ€” create a skills folder inside your project and drop the file in:

mkdir -p .claude/skills
Then move grill-me.md into the .claude/skills/ folder you just created. On Mac you can drag it in Finder. On Windows, drag it in File Explorer.

For Cursor โ€” Settings โ†’ Rules for AI โ†’ paste the entire contents of grill-me.md into the text box.

For any other AI chat โ€” paste the entire contents of grill-me.md at the very top of your first message, before anything else.

Phase 1
Plan your app
Don't write any code yet. Use AI to think it through first โ€” this saves hours of frustration later.
Open the terminal and create your project folder
โ–ผ
Every project lives in its own folder on your computer. You navigate to that folder in the terminal and run all your commands from inside it โ€” this tells tools like Claude Code and Docker which project you're working on.
Step 1 โ€” Go to your Documents folder
cd ~/Documents
~ is a shortcut meaning "my home folder". cd means "change directory" (directory = folder). So this command means: go to the Documents folder inside my home folder.
Step 2 โ€” Create a new folder and go inside it
mkdir my-app && cd my-app
Replace my-app with your project name. Rules: no spaces (use hyphens), all lowercase. Good examples: expense-tracker, booking-app, team-portal.
Step 3 โ€” Confirm you're in the right place
pwd
Prints your current location. Should end with your project folder name, e.g. /Users/yourname/Documents/my-app. If it doesn't, go back and check step 1 and 2.
Write your app idea in one sentence
โ–ผ
Before opening any AI, write down what your app does in plain English. Just one sentence, for yourself. This forces you to be clear before you start โ€” if you can't describe it in one sentence, the idea probably needs more thinking first.
Example: "An app where my team submits expense reports and I can approve or reject them."
Example: "A page where customers can book a 30-minute call with me by picking a time slot."
Stuck? Describe the problem instead: "Right now I have to [painful thing]. I want an app that lets me [better thing] instead."
Keep it small. The most common mistake beginners make is trying to build too much in one go. Pick the simplest possible version of your idea. You can always add more later โ€” but you need to finish something first.
Run the planning prompt โ€” AI interviews you and creates your 4 plan files
โ–ผ
Start Claude Code by typing claude in your terminal from inside your project folder, then press Enter. Paste the prompt below and replace the placeholder. The AI will ask you questions โ€” answer in plain English. Check the Defaults & answers tab for ready-made answers to common questions.
What are .md files? The plan files end in .md, which stands for Markdown โ€” a simple format for writing structured text. Think of it like a plain text file with some basic formatting (headings, bullet points). You can open them in any text editor. The AI writes them, you just read them.
Paste this prompt โ€” replace the placeholder with your idea
I want to build a web app. My idea:

[REPLACE THIS WITH YOUR ONE-SENTENCE IDEA]

Please use the grill-me skill to interview me about this.
Ask me one question at a time. For each question, give me your recommended answer first so I know what's normal.

When the interview is done, save 4 markdown files into this project folder:
- frontend.md  โ€” React + Vite + Tailwind + shadcn/ui + React Router v7 + TanStack Query
- backend.md   โ€” Node.js + Express + PostgreSQL + Prisma + Zod + JWT auth
- design.md    โ€” shadcn/ui defaults, Inter font, Lucide icons, mobile-first, light mode
- deploy.md    โ€” Docker Compose + Nginx reverse proxy + Certbot SSL, Ubuntu 22.04 VPS

Use sensible defaults for a small web app wherever I haven't specified something.
How to answer the questions: Plain English only โ€” no technical terms needed. "I want users to be able to log in and see their own data" is a perfect answer. The AI gives you its recommended answer for each question, so if you're unsure just say "use your recommendation".
Read through all 4 plan files before building anything
โ–ผ
Don't skip this. Read each file even if you don't understand everything in it. You're looking for anything that feels wrong โ€” "that's not what I meant" moments.
How to open the files:
Mac: Open Finder โ†’ navigate to your project folder โ†’ double-click any .md file to open it in TextEdit.
Windows: Open File Explorer โ†’ navigate to your project folder โ†’ right-click any .md file โ†’ Open with โ†’ Notepad.
Something doesn't match what you wanted? Go back to your AI and say: "In frontend.md, the part about [X] isn't right โ€” I actually want [Y]. Please update that file." Fix it now. Changing a plan file takes 30 seconds. Changing working code takes 30 minutes.
Phase 2
Scaffold the project
The AI creates all the starter files and folder structure from your plans. No features yet โ€” just the skeleton.
Ask AI to set up the project structure
โ–ผ
Make sure you're in your project folder (type pwd to check). Start Claude Code with claude. If using another AI, drag your 4 .md plan files into the chat window. Then paste this prompt.
What does "scaffolding" mean? It's creating the skeleton of the app before building the actual features โ€” all the folders, config files, and starter code that every project needs. Like laying the foundations of a house before building the rooms. After this step the app technically runs, but it won't do anything useful yet โ€” that's Phase 3.
Paste this prompt
Read my 4 plan files: frontend.md, backend.md, design.md, deploy.md.

Before writing any code, act as a project manager:
1. List every task needed to scaffold this project, numbered in order
2. Show me the list and wait for me to say "go" before starting

Then work through the list one task at a time:
- Complete one task, then stop and tell me what you did
- Wait for me to say "next" before moving to the next task
- After each task, silently run lint and type checks and fix any errors before stopping

Create:
- /frontend  โ€” React + Vite + Tailwind + shadcn/ui, configured and ready to run
- /backend   โ€” Node.js + Express + Prisma + PostgreSQL, configured and ready to run
- docker-compose.yml at the root โ€” runs frontend, backend, and PostgreSQL together
- .env.example at the root โ€” lists every environment variable needed with placeholder values

The whole thing must start with: docker compose up
The AI will list its plan and wait. Read it and type "go" to start. After each task it stops and waits for you to type "next". This keeps things manageable.
Phase 3
Build the app
One feature at a time. Test after each one before moving on.
Build features one at a time โ€” use this prompt for each one
โ–ผ
Pick the single most important feature and build just that first. The AI will plan it out, build one small piece at a time, and wait for your confirmation before continuing. Quality checks happen automatically โ€” you don't need to worry about them.
What's a "feature"? A self-contained piece of functionality. "User login" is a feature. "Submit an expense report" is a feature. "View all pending approvals" is a feature. If you can describe it as one user action, it's probably one feature.
Use this for every feature โ€” replace [FEATURE NAME]
Build the [FEATURE NAME] feature. Refer to the plan files for requirements.

Before writing any code, act as a project manager:
1. Break this feature into small numbered sub-tasks
2. Show me the list and wait for me to say "go"

Then work through the list one sub-task at a time:
- Complete one sub-task, then stop and tell me what you did and what to test
- Wait for me to say "next" before continuing
- After each sub-task, silently run lint and type checks and fix any errors before stopping
- Never move to the next sub-task without my confirmation
Good first features: "user login and registration" โ†’ then the core action of your app โ†’ then secondary features. Always start with login if your app has users.
The golden rule: Finish one feature completely, test it, then start the next. Never build three half-finished features โ€” bugs pile up and become impossible to untangle.
Run the app locally and open it in your browser
โ–ผ
After the AI finishes a feature, you test it by running the app on your own computer and opening it in a browser โ€” exactly like a normal website, except it's only visible to you and running locally.
Before you start: Make sure Docker Desktop is open and running. Look for the whale ๐Ÿณ icon in your menu bar (Mac) or taskbar (Windows). If it's not there, open Docker Desktop and wait for it to fully load โ€” this takes about 30 seconds.
Step 1 โ€” In your terminal, navigate to your project folder
cd ~/Documents/my-app
Replace my-app with your project folder name. If you're already in that folder (your prompt shows the name), skip this step.
Step 2 โ€” Start the app
docker compose up
This starts your frontend, backend, and database simultaneously. You'll see a flood of coloured text โ€” that's completely normal. Each line is a log from one of your containers starting up.

What to wait for: The text will slow down and eventually settle. Look for a line containing "ready", "listening on", or "started". That means the app is up.
Seeing red text? That's an error. Don't panic โ€” read the last few lines carefully, then paste the error into your AI: "I got this error running docker compose up โ€” what does it mean and how do I fix it?"
Step 3 โ€” Open your browser and go to this address
http://localhost:3000
Type that address into Chrome, Safari, or Firefox โ€” just like you'd type google.com. You should see your app.

"localhost" means "this computer". Port 3000 is where Docker exposes your frontend to your browser. This address only works on your own machine โ€” nobody else can see it yet.

Why 3000? Vite (the tool that runs React) uses port 5173 inside Docker, but Docker maps that to 3000 on your machine โ€” so you always use 3000. Your backend runs at localhost:4000 but you never open that directly โ€” your frontend talks to it behind the scenes.
Step 4 โ€” Stop the app when you're done
Ctrl + C
Go back to the terminal window running docker compose and press Ctrl+C (hold Control, press C). You'll see it shut down each service. Then it's safe to close the terminal.
Test it properly โ€” try to break it
โ–ผ
Testing doesn't mean glancing at it and saying "looks fine." Go through the app the way a real user would โ€” and specifically try the things they'd do wrong.
Testing checklist for each feature:
โ€ข Do the happy path โ€” use the feature exactly as intended. Does it work?
โ€ข Try submitting an empty form โ€” does it show a proper error?
โ€ข Try wrong input โ€” letters in a number field, too-short passwords, etc.
โ€ข Log out and log back in โ€” is your data still there?
โ€ข Refresh the page mid-task โ€” does anything break?
Found a bug? Tell your AI: "When I [describe exactly what you did], [describe what happened]. I expected [describe what should have happened]. How do I fix it?"
๐Ÿ“š Learn more about testing: What is User Acceptance Testing? โ€” this is exactly what you're doing, even if you don't call it that.
Phase 4
Save your work to GitHub
Once your app works locally, save it online so it's safe and ready to deploy.
Create a GitHub Personal Access Token โ€” so Git can log in
โ–ผ
When you try to push code to GitHub from the terminal, GitHub needs to verify it's really you. It doesn't accept your regular password โ€” it uses a "Personal Access Token" (a long auto-generated password just for terminal use). You create this once.
1. Go to github.com โ†’ click your profile photo (top right) โ†’ Settings
2. Scroll all the way down the left sidebar โ†’ click Developer settings
3. Click Personal access tokens โ†’ Tokens (classic)
4. Click Generate new token โ†’ Generate new token (classic)
5. Give it a name like "my laptop"
6. Set expiration to No expiration
7. Tick the repo checkbox (this is the only permission you need)
8. Click Generate token at the bottom
9. Copy the token immediately โ€” GitHub only shows it once. Save it in your notes app or password manager.
Critical: Copy the token before closing the page. GitHub will never show it again. If you lose it, you'll need to create a new one โ€” but that's fine, just repeat these steps.
When the terminal later asks for your GitHub password โ€” paste this token instead of your actual password. It won't look like anything is being typed, but it's working.
Create a new repository on GitHub for this project
โ–ผ
A "repository" (or "repo") is just your project folder stored on GitHub. You create one new repo for each app you build.
1. Go to github.com and sign in
2. Click + in the top right corner โ†’ New repository
3. Give it the same name as your project folder (e.g. my-app)
4. Set visibility to Private
5. Do not tick "Add a README file" or any other optional extras
6. Click Create repository
7. Leave this page open โ€” you'll need the URL it shows you in the next step
Push your code to GitHub
โ–ผ
Now you connect your project folder on your laptop to the GitHub repo you just created, and upload everything. Run these commands from inside your project folder in the terminal.
First time only โ€” run these once per project
git init
git add .
git commit -m "first version"
git branch -M main
git remote add origin https://github.com/YOUR-USERNAME/YOUR-REPO.git
git push -u origin main
Replace YOUR-USERNAME and YOUR-REPO with your GitHub username and repo name. GitHub shows you the exact URL to use right after you create the repo.

What each line does:
git init โ€” starts Git tracking in this folder
git add . โ€” selects all files to save (the dot means "everything")
git commit -m "..." โ€” saves a snapshot with a description
git branch -M main โ€” names the main line of your code "main" (just a naming convention)
git remote add origin ... โ€” tells Git where your GitHub repo is
git push -u origin main โ€” uploads everything to GitHub
It asks for a password? Enter your GitHub username when it asks for "Username", then paste your Personal Access Token (from the previous step) when it asks for "Password". You won't see the token as you type โ€” that's normal.
Every time you make changes after that
git add .
git commit -m "describe what you changed"
git push
The message in quotes is for your own reference. Be descriptive: "added login page" or "fixed broken submit button on expense form" is much more useful than "update" when you're looking back later.
๐Ÿ“š Learn more: Git and GitHub for beginners โ€” freeCodeCamp. The best free resource for learning this properly.
Phase 5
Deploy your app to the internet
Put your app online so anyone with the link can use it.
Choose how you want to host your app
โ–ผ
There are several ways to get your app onto the internet. They each suit different situations. Read this before continuing.
๐Ÿ–ฅ Option A โ€” VPS (Virtual Private Server) Recommended
A VPS is a small computer that runs 24/7 in a data centre. You rent it monthly and have full control.

โœ… Works for any app โ€” frontend, backend, database, everything
โœ… Your own domain name
โœ… Free HTTPS included
โš ๏ธ Costs ~$5โ€“8/month
โš ๏ธ More initial setup โ€” follow the steps below
Recommended: Hostinger VPS (cheapest, beginner-friendly) ยท DigitalOcean (excellent docs) ยท Vultr
๐Ÿ“„ Option B โ€” GitHub Pages (free, but limited)
Hosts simple websites directly from your GitHub repo for free.

โœ… Completely free
โœ… Zero setup
โŒ Cannot run a backend or database
โš ๏ธ Important: If your app has user accounts, saves data, or does anything involving a server โ€” GitHub Pages will not work. It only hosts static pages with no logic. Use a VPS instead.
โ˜๏ธ Option C โ€” Managed platforms (Railway, Render, Vercel)
"One-click deploy" platforms. Good middle ground.

โœ… Easier setup than a VPS
โœ… Can run backend + database
โš ๏ธ Free tiers sleep after inactivity โ€” first load takes 30+ seconds
โš ๏ธ Gets expensive quickly as your app grows
Railway is the easiest for full-stack apps with a database.
This guide uses Option A (VPS) โ€” it works for every type of app and is the most valuable skill to learn. The steps below assume you have a VPS with an IP address and root password.
Buy and set up a VPS on Hostinger
โ–ผ
A VPS is a small computer that runs in a data centre 24/7. You rent access to it monthly. Here's how to get one.
Step 1 โ€” Sign up and buy

Go to hostinger.com/vps-hosting โ†’ choose the KVM 1 plan (cheapest, ~$4โ€“6/month) โ†’ complete checkout.
Step 2 โ€” Configure your server

After payment, Hostinger will walk you through server setup:
โ€ข Operating System: choose Ubuntu 22.04 โ€” this is the most common Linux version for servers
โ€ข Server location: pick the region closest to your users
โ€ข Root password: create a strong password and save it in your notes app right now โ€” you'll need it every time you log in
Step 3 โ€” Find your IP address

Once your server is ready (2โ€“5 minutes), go to your Hostinger dashboard โ†’ VPS โ†’ click your server. You'll see an IP address like 123.45.67.89. Copy it somewhere โ€” you'll use it shortly.
Step 4 โ€” Point your domain at your server (optional)

If you have a domain name, log into your DNS provider (Cloudflare, Namecheap, etc.) and add an A record:
โ€ข Name: @ (root domain) or a subdomain like app
โ€ข Value: your server's IP address

DNS changes take a few minutes. No domain yet? Just use your IP address for now โ€” you can add a domain later.
๐Ÿ“š What is Linux? Linux is an operating system (like Windows or macOS) that runs on most servers worldwide. Ubuntu is a beginner-friendly version of Linux. You'll interact with it through the terminal. Linux commands for beginners โ€” freeCodeCamp.
What is SSH โ€” and how to log into your server with it
โ–ผ
SSH (Secure Shell) is a way to remotely control another computer through your terminal. When you SSH into your server, it's like sitting in front of it and typing on its keyboard โ€” except you're doing it from your laptop over the internet.
Analogy: Your laptop is at home. Your server is in a data centre in another city. SSH is a secure tunnel that lets you type commands on your laptop that run on the server โ€” as if you teleported there.
Step 1 โ€” Open a new terminal window on your laptop
This is separate from the terminal you use for your project. You're about to run commands on the server, not your laptop.
Step 2 โ€” Connect to your server
Replace YOUR.SERVER.IP.ADDRESS with your actual IP (e.g. ssh [email protected]). root is the admin username on Linux servers.
Step 3 โ€” Enter your password
The terminal will show: [email protected]'s password:

Type your root password (set when you created the server) and press Enter.

You won't see anything as you type โ€” no dots, no asterisks. That's intentional security behaviour. Just type the password and press Enter.
Step 4 โ€” First connection warning
First time connecting, you'll see: "Are you sure you want to continue connecting? (yes/no)". Type yes and press Enter. This is normal โ€” your computer is just confirming the server's identity.
Step 5 โ€” You're in
Your prompt will change to something like root@srv123456:~#. You're now controlling the server. Everything you type runs there, not on your laptop.

To disconnect: type exit and press Enter. Your terminal goes back to normal.
Check what's installed on your server โ€” install anything missing
โ–ผ
You're now SSH'd into the server. Run these checks. "Command not found" means you need to install it โ€” run the relevant install command below.
Check what's already there (run each line separately)
docker --version
docker compose version
nginx -v
git --version
Install Docker (if missing)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
This downloads and runs Docker's official installer. Takes 1โ€“2 minutes. You'll see a lot of output โ€” that's normal.
Install Nginx and Git (if missing)
sudo apt update
sudo apt install nginx git -y
sudo systemctl enable nginx && sudo systemctl start nginx
apt is Ubuntu's package manager โ€” like an App Store for the server's command line. sudo means "run this as administrator". -y means "yes to all confirmation prompts".
Download your code from GitHub onto the server
โ–ผ
Still SSH'd into the server. Now you'll download your code from GitHub directly onto it. You only do this once โ€” future updates use a shorter command.
Navigate to the web folder and download your project
cd /var/www
git clone https://github.com/YOUR-USERNAME/YOUR-REPO.git
cd YOUR-REPO
/var/www is the standard location on Linux servers for websites. git clone downloads a copy of your GitHub repo. Replace the URL placeholders with your actual GitHub username and repo name.
Create your secrets file on the server
โ–ผ
Your app needs secret configuration values โ€” things like database passwords and API keys. These are called "environment variables" and they live in a file called .env. They're never stored in GitHub (that would be a security risk), so you create this file manually on the server.
What are environment variables? They're settings your app reads when it starts up โ€” things it needs to know that are different between environments (your laptop vs. the server). Passwords, API keys, port numbers. Your .env.example file (created by the AI) lists all the ones your app needs.
Copy the template and fill it in
cp .env.example .env
nano .env
cp copies the template to create a real .env file. nano opens a simple text editor on the server.

Fill in the values. When done:
1. Press Ctrl + X
2. Press Y to confirm saving
3. Press Enter to confirm the filename
Never commit your .env file to GitHub. Your .gitignore file (created by the AI) already prevents this, but never override it. Secrets in GitHub are a serious security issue.
Start the app and set up Nginx
โ–ผ
Start your app in the background
docker compose up -d
The -d flag means "detached" โ€” the app runs in the background and keeps running after you close the terminal or disconnect SSH.
Verify everything started correctly
docker compose ps
All rows should show running. If any show "exited", run docker compose logs to see what went wrong, then paste the error to your AI.
What is Nginx? Nginx (pronounced "engine-x") is a web server. It sits in front of your app and handles incoming web traffic โ€” forwarding requests from the internet to your Docker containers. It also handles your domain name and HTTPS certificate.
Create the Nginx config file
sudo nano /etc/nginx/sites-available/my-app
Paste this config (replace YOUR_DOMAIN_OR_IP with your domain or server IP)
server {
    listen 80;
    server_name YOUR_DOMAIN_OR_IP;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
Save and exit: Ctrl+X โ†’ Y โ†’ Enter.
Enable the config and restart Nginx
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx -t checks your config for typos before applying it. If it says anything other than "test is successful" โ€” there's a mistake. Check for typos in the config before reloading.
Add free HTTPS โ€” the padlock in the browser
โ–ผ
HTTPS encrypts the connection between your users' browsers and your server โ€” it's what gives you https:// instead of http:// and the padlock icon. Browsers now warn users about sites without it. It's free using a tool called Certbot. You need a domain name pointed at your server first.
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
Follow the prompts: enter your email, agree to terms. Certbot updates your Nginx config automatically and renews your certificate before it expires every 90 days โ€” you never need to think about it again.
How to deploy future updates
โ–ผ
Every time you make changes and want them live, follow this two-step process. First push from your laptop, then pull on the server.
On your laptop โ€” save and push to GitHub
git add .
git commit -m "describe what you changed"
git push
On your server (SSH in first) โ€” pull and rebuild
cd /var/www/YOUR-REPO
git pull
docker compose down
docker compose up -d --build
--build rebuilds the Docker containers with your new code. Always include it โ€” without it the old version keeps running even after the pull.

Starting a new project? Reset the checklist.