The Beginner's Guide › Understanding How Apps Work
How Do Apps Work?
The essential concepts every vibecoder needs to know
The Big Picture
When you build an app, you're really building two things that talk to each other: a frontend (what users see) and a backend (where data lives and logic happens). Think of it like a restaurant: the frontend is the dining room where customers interact, and the backend is the kitchen where the real work gets done.
Where Does Your Data Live?
This is the #1 source of confusion. Your data exists in three different places, and understanding this is critical:
Browser Memory
Temporary data while the page is open. Disappears on refresh.
Session Storage
Temporary data for your browsing session. Gone when you close the tab.
Database
Permanent storage. Data persists forever (until you delete it).
The Todo List Example
Imagine you're building a todo list app:
// This only lives in browser memory let todos = ["Buy milk", "Walk dog"]; // When you refresh the page... POOF! It's gone.
To make it permanent, you need to save it to a database. That's what databases do - they remember things even after you close your app.
Warning
If you're building something and refreshing the page loses your data, you haven't connected to a database yet. Your data is only living in browser memory.
Frontend vs Backend: The Restaurant Analogy
| Frontend (Dining Room) | Backend (Kitchen) |
|---|---|
| What users see and interact with | Where data is stored and processed |
| Runs in the browser | Runs on a server |
| HTML, CSS, JavaScript | Node.js, Python, databases |
| Makes requests for data | Responds with data |
| Cannot directly access databases | Has full database access |
Why They're Separate
Your frontend code runs on the user's computer (in their browser). Your backend runs on your server. This means:
- The frontend has to ask the backend for data
- The backend decides if the request is allowed
- The frontend waits for the response
- The backend sends data back
This is called the request/response cycle, and it's fundamental to how the web works.
The Request/Response Cycle
Here's what actually happens when you click a button in an app:
User Action
You click "Show my todos"
Frontend Sends Request
Browser sends: GET /api/todos
Backend Processes
Server receives request, queries database
Database Returns Data
Database sends todos back to backend
Backend Sends Response
Backend sends JSON data to frontend
Frontend Displays
Browser renders the todos on screen
This happens in milliseconds, but it's not instant. That's why you see loading spinners - the frontend is waiting for the backend to respond.
Code Example
// Frontend code async function getTodos() { // This ASKS the backend for data const response = await fetch('/api/todos'); const todos = await response.json(); // Now we can display them displayTodos(todos); }
// Backend code (Node.js/Express) app.get('/api/todos', async (req, res) => { // Backend queries the database const todos = await database.collection('todos').find(); // Backend sends data back to frontend res.json(todos); });
Info
Notice how the frontend cannot directly access the database. It must go through the backend. This is a security feature - you don't want users able to access your database directly from their browser.
What Is a Database?
A database is permanent storage for your app's data. Think of it like a super-organized filing cabinet that never forgets.
MongoDB Basics
MongoDB stores data in collections of documents. Think of it like this:
- Database = The entire filing cabinet
- Collection = A drawer in the cabinet (e.g., "users", "todos", "posts")
- Document = An individual file/record in that drawer
Documents Look Like JavaScript Objects
// This is a document in your "users" collection { _id: "507f1f77bcf86cd799439011", // MongoDB's auto-generated ID name: "Sarah", email: "sarah@example.com", age: 28, todos: [ { task: "Buy milk", done: false }, { task: "Walk dog", done: true } ] }
Success
If you know how to work with JavaScript objects, you already know how to work with MongoDB documents!
CRUD: The Four Things You Do With Data
Every app is basically doing these four operations in different combinations:
Create
Add new data (signup, create post, add todo)
Read
Get existing data (login, view profile, show todos)
Update
Change existing data (edit profile, mark todo done)
Delete
Remove data (delete account, remove todo)
Once you realize that 90% of your app is just CRUD operations, everything becomes much clearer.
How Code Actually Runs
Frontend Code (Browser)
// This runs on the USER'S computer console.log("Hello from the browser!"); // Users can see this code if they open dev tools const apiKey = "secret123"; // NEVER DO THIS
Warning
Everything in your frontend code is visible to users. Never put passwords, API keys, or secrets in frontend code. Users can read every line.
Backend Code (Server)
// This runs on YOUR server console.log("Hello from the server!"); // Users CANNOT see this code const secretKey = process.env.DATABASE_PASSWORD; // This is safe
The backend is where you:
- Connect to databases
- Store secrets and API keys
- Validate data before saving
- Control who can access what
Environment Variables: Keeping Secrets Secret
Your database password, API keys, and other secrets go in a special file called .env:
# .env file (never commit this to GitHub!) DATABASE_URL=mongodb://username:password@host:27017 API_SECRET_KEY=your-secret-key-here
In your code, you access them like this:
const dbPassword = process.env.DATABASE_URL;
Warning
Always add .env to your .gitignore file so it's never uploaded to GitHub. If you accidentally expose your database password, change it immediately.
Collections and Relationships
What Is a Collection?
A collection is a group of similar documents. Common collections include:
users- All your user accountsposts- All blog posts or contentcomments- All comments on poststodos- All todo items
Connecting Related Data
Let's say you have users and posts. How do you know which posts belong to which user?
// User document { _id: "user123", name: "Alex" } // Post document { _id: "post456", title: "My First Post", authorId: "user123", // This links to the user! content: "Hello world..." }
When you want to show a post with the author's name, you:
- Get the post
- Look up the user by
authorId - Display both together
This is called referencing or relational data.
The Schema Question
MongoDB doesn't enforce a schema (structure) by default, which means you can do this:
// These are both valid in MongoDB { name: "Alex", age: 30 } { name: "Sarah", age: "twenty-eight", favoriteColor: "blue" }
But you shouldn't. Your app expects consistent data structures. This is why, in the Emergent environment, you should prompt the agent to maintain consistent schema.
Tip
Even though MongoDB is "schema-less", treat it like it has a schema. Your future self will thank you when debugging.
Async/Await: Why Things Don't Happen Instantly
When you fetch data from a database or API, it takes time. You need to wait for the response:
// This doesn't work const todos = fetch('/api/todos'); console.log(todos); // This runs before data arrives! // This works const todos = await fetch('/api/todos'); console.log(todos); // Now we have the data
The await keyword says "pause here until the data arrives". Any function using await must be marked async as a best practice.
async function getTodos() { const response = await fetch('/api/todos'); const data = await response.json(); return data; }
Putting It All Together
Here's the complete flow of a typical app feature, using the same example of the to-do app:
User Interacts
Clicks "Add Todo" button in the frontend
Frontend Sends Request
POST request to /api/todos with todo data
Backend Validates
Checks if the request is valid and allowed
Backend Saves to Database
Inserts the new todo into the todos collection
Database Confirms
Returns the saved document with its new _id
Backend Responds
Sends success response back to frontend
Frontend Updates
Displays the new todo on screen
Key Takeaways
Frontend = Display
Shows data and collects input. Runs in the browser.
Backend = Logic
Processes requests and stores data. Runs on your server.
Database = Memory
Permanent storage. Survives refreshes and restarts.
API = Middleman
Connects frontend and backend through endpoints.
Note
The hardest part about learning to code isn't the syntax - it's understanding where code runs, where data lives, and how it all connects. Master these concepts and everything else falls into place.
