Getting Started
Setting Up Your Laptop
Welcome. You're about to learn how to build software with AI. You don't need a computer science degree, and you don't need prior experience. You need Cursor, a browser, and a few hours. Let's go.
Do a few things before you start — it should take about 10–15 minutes. Nothing complicated — just follow the steps below.
You don't need to understand what any of this means right now. The rest of this guide explains the ideas. For now, just get through the setup so you can open a project and follow along without friction.
⚠️ Use Your Personal Laptop
Please use your personal laptop for this guide — not your company/work laptop. Work machines often have restrictions that block software installations, and we don't want you stuck fighting IT policies when you could be building.
Step 1: Create a GitHub Account
If you don't already have one, sign up at github.com. The free plan is all you need. If you already have an account, you're done with this step.
Again — don't worry about what GitHub is or why you need it. We'll cover that as you work through this guide.
Step 2: Install Cursor
Cursor is an AI-powered code editor. Think of it as your AI pair programmer.
- Download it from cursor.com
- Install it and open it
- A Pro subscription ($20/month) is strongly recommended. The free tier has usage limits that may cut you off mid-session. You can cancel anytime if it's not for you — but we suspect you'll want to keep it. If you'd rather try the free tier first, that's okay — just know there's a chance you'll hit the limit while you're deep in a build.
- If you already use VS Code, Cursor will offer to import your settings and extensions. Say yes — it makes the switch seamless.
Step 3: Let Cursor Set Up the Rest
This is the fun part — and honestly, your first real lesson before the rest of the guide. You're going to ask an AI to set up your machine for you.
- Create a new folder on your laptop wherever you like. Call it something like
cursor-practice-project. - Open Cursor, then open that folder (File → Open Folder).
- Open the AI chat panel on the right side (press
Cmd+Lon Mac /Ctrl+Lon Windows). - Copy-paste this entire prompt into the chat and hit send:
I'm setting up my machine to learn Cursor and build with AI. I need the following installed on this machine:
- Git — version control software
- Node.js (LTS version) — a JavaScript runtime
Please do the following:
- Check if each of these is already installed
- Install whatever is missing
- After everything is done, run the version check commands and show me the version numbers for git, node, and npm
Important: After you're done with everything, give me a short plain-English summary (2–3 sentences, no jargon) of what you just did and why these tools were needed. I'm new to this, so keep it super simple.
- Let the agent work. It will figure out your operating system, run the right terminal commands, and handle everything. If it asks for permission to run a command, say yes.
- At the end, you should see version numbers for git, node, and npm, plus a simple summary of what was done. Take a screenshot of this — it's your confirmation that everything is working.
If Something Goes Wrong
Don't panic. Installations sometimes throw errors — that's normal, even for experienced developers.
Your move: Ask the Agent in Cursor to fix the error. It is surprisingly good at it.
Quick Checklist
- I'm using my personal laptop (not a work machine)
- GitHub account created
- Cursor installed (Pro subscription strongly recommended)
- Cursor's agent installed Git and Node.js for me
- I have a screenshot showing version numbers for git, node, and npm
That's it. You're ready to keep going.
Introduction to Software Engineering
Who is this section for? If you're a product manager, designer, founder, or anyone who hasn't written code professionally — read this carefully. If you're a developer, skip to Good Coding Practices. You already know all of this.
What you don't need to do: Memorise any of this. This section gives you a mental map so you're not lost when we start building. That's it. Cursor will handle the actual code.
A quick note: Everything in this section (and this guide) is about building for the web — websites and web applications that run in a browser. We're not covering mobile app development (iOS/Android apps you download from the App Store or Play Store). App development is a different stack, significantly more complex to set up, and not what you (usually) need for personal projects and prototyping. The web is where you get the fastest path from idea to something real that anyone can access with just a URL. That's why we're here.
Click on each to know more
The Restaurant AnalogyClient, API, server, database — explained as a restaurant.
This is the single most useful mental model in software engineering. Once you get this, everything else makes sense.
Imagine a restaurant.
You (the customer) are the Client. You sit at a table, you look at a menu, you place an order. You don't walk into the kitchen and cook your own food. You interact with what's in front of you — the table, the menu, the plates. In software, this is the front-end: the website or app you see and interact with. Buttons, forms, pages, colors — that's all front-end.
The Waiter is the API. You tell the waiter what you want. The waiter takes your order to the kitchen and brings back your food. You never talk to the chef directly. In software, the API (Application Programming Interface) is the messenger between the front-end and the back-end. When you click "Sign In" on a website, an API carries your request to the server and brings back the response ("yes, you're logged in" or "wrong password").
The Kitchen is the Server (Back-end). This is where the actual work happens. The chef receives your order, figures out what to do, cooks the food, and hands it back to the waiter. In software, the server runs the logic: processing data, making decisions, running calculations. You never see it as a user, just like you never see the kitchen as a diner.
The Pantry is the Database. The kitchen doesn't conjure ingredients out of thin air. It pulls from the pantry — where all the raw ingredients are stored, organized, and ready to use. In software, the database stores all the data: user accounts, product listings, messages, orders. The server reads from and writes to the database, just like the chef pulls from and restocks the pantry.
The House Rules are Middleware. Before you're seated, the host checks: do you have a reservation? Is there a dress code? Are you old enough to order from the bar? These checks happen between you arriving and you placing an order. In software, middleware handles things like: is this user logged in? Do they have permission to see this page? Is this request legitimate? It sits between the client and the server, filtering and checking.
That's it. That's the architecture of almost every application on the internet:
Client → API → Middleware → Server → Database
Or in restaurant terms:
You → Waiter → House Rules → Kitchen → Pantry
Languages vs. FrameworksLanguages vs frameworks, stacks per layer, what we use Saturday.
Before we talk about frameworks, let's clear up something that confuses everyone at first.
Languages: How You Communicate
A programming language is exactly what it sounds like — a language. It's how you talk to a computer. Just like you'd use English or Hindi or Telugu to communicate with a person, you use Python, JavaScript, or TypeScript to communicate with a machine.
Different languages exist because they're good at different things, just like different natural languages have words and expressions that don't translate perfectly. Python reads almost like English and is great for data, scripts, and back-end logic. JavaScript was built for the web and runs in every browser on the planet. TypeScript is a fancier version of JavaScript with extra safety rails — same language, just stricter. Think of it as JavaScript wearing a seatbelt.
Frameworks: The Pre-Made Base
Here's something every kitchen knows: you don't make every dish from scratch.
Take a tomato. It's a single ingredient — versatile, fundamental, used everywhere. But what you do with that tomato depends on what you're building. An Italian kitchen blends it into a pizza sauce — the base for an entire tradition of dishes. An Indian kitchen cooks it down with onions into a masala gravy — the base for a completely different tradition. Same raw ingredient, two entirely different foundations, two entirely different cuisines.
Software works the same way. A framework is your pre-made base. It's a set of pre-built tools and structures — written in a specific language — that handles the common stuff so you can focus on what's unique to your project.
Here's the key relationship: frameworks are written using languages. The language is the tomato. The framework is the pizza sauce or the masala gravy — a prepared foundation built from that raw ingredient. And just like one ingredient can produce very different bases for very different cuisines, one programming language can have multiple frameworks that serve completely different purposes.
Every Part of the Restaurant Has Its Own Frameworks
Remember our restaurant? Each component — the dining area, the kitchen, the pantry — has frameworks designed specifically for it:
Front-end frameworks (the dining area — what customers see and interact with):
- React — Built with JavaScript/TypeScript. The most popular front-end framework in the world. Used by Instagram, Netflix, Airbnb.
- Vue — Also JavaScript. Lighter and simpler. Popular in Asia and Europe.
- Angular — JavaScript again. Used heavily by large enterprises like Google.
Back-end frameworks (the kitchen — where the logic and processing happens):
- Django — Built with Python. Great for building things fast. Instagram's back-end started with Django.
- FastAPI — Also Python. Newer, faster, designed for building APIs specifically.
- Express — Built with JavaScript/Node.js. Lightweight and flexible.
Database tools (the pantry — where data is stored):
- PostgreSQL, MySQL — Traditional databases. Think of them as well-organized pantries with labelled shelves and inventory lists.
- MongoDB — A more flexible database. Think of it as a pantry where you can throw things in without rigid shelf labels.
- Supabase, Firebase — These are managed database services. Someone else organises and maintains the pantry for you.
Notice how Django and FastAPI are both Python frameworks but serve different purposes — just like the same gravy base can be tweaked for different dishes. Similarly, React, Vue, and Angular are all JavaScript frameworks but take different approaches to building front-ends.
You absolutely do not need to remember any of these names. They're here so that when you hear someone say "I built it in Django" or "it's a React app," you have a rough idea of what layer of the restaurant they're talking about.
What We're Using in This Guide
In this guide, we'll use Next.js. It's a particularly versatile framework — think of it as a base that works for both the dining area and the kitchen. It handles front-end (what users see) and back-end (the server logic) in a single project. It's built on JavaScript/TypeScript, which means you write one language for everything.
The calculator demo at the end of this section is built with Next.js. When you click a button on the calculator (front-end), it sends a request to the server (back-end), the server does the calculation, and sends back the result. You'll be able to open the browser console and actually see these requests and responses happening in real time — the waiter going back and forth between your table and the kitchen.
A Few More Terms You'll See
- Node.js — You installed this in the setup guide. It lets JavaScript run outside the browser — on servers, on your laptop, anywhere. Without Node, JavaScript could only work inside a web browser. Think of it as the gas supply to the kitchen — the kitchen (your framework) can't run without it.
- npm — Node Package Manager. The grocery delivery service for your project. When your project needs a tool or library someone else has built, npm fetches it for you.
- package.json — Your project's shopping list. It lists every dependency (ingredient) your project needs. When you run
npm install, npm reads this list and fetches everything.
You'll see these words in your project files as you build. Now they won't scare you.
Your Laptop vs. The World: Development and ProductionLocal vs deployed; dev vs prod; why you don’t edit production live.
Right now, when you write code on your laptop and run it, only you can see it. It's running locally — on your machine, using your machine's resources. If you close your laptop, it stops. Nobody else can access it.
This is actually great for building. Your laptop is your personal test kitchen — experiment freely, taste as you go, mess up a recipe, try again. Nothing you do locally affects anyone else. This is important. You cannot break anything that matters by experimenting on your own laptop.
When you're happy with what you've built and you want others to see it, you deploy it. Deploying means taking your code and running it on a computer somewhere else — a server that's always on, always connected to the internet, and has a public address (a URL) that anyone can visit.
That's all deployment is. Your code, running on someone else's computer, accessible to the world.
Development vs. Production
In the real world, these two environments have names:
Development (dev) — Your laptop. Where you experiment, build, break things, and fix them. Nobody sees this but you. The test kitchen.
Production (prod) — The live server. Where real users visit your site. The restaurant floor during dinner service. This needs to work. Always.
Here's why this distinction matters. Let's say you've built a website and deployed it. 100 people visit it every day. It works beautifully. Now you want to add a new feature — maybe a dark mode toggle.
You do NOT open the live production code and start editing. That would be like remodelling the kitchen while customers are eating dinner. If something goes wrong mid-edit, those 100 daily visitors see a broken site. Or worse, the whole thing crashes.
Instead, you work on your development copy — your laptop. You add the dark mode feature there. You test it. You click around, make sure nothing is broken. You try edge cases. You hate the shade of grey you picked, so you change it. All of this happens safely on your machine while the 100 real users continue using the perfectly working production version.
Only when you're satisfied that the new feature works do you push it to production. The live site updates. Nobody experienced any downtime or bugs. The kitchen remodel happened off-hours.
This is exactly why local and remote exist as separate things — and it's the perfect segue into version control, because version control is how you manage the flow from dev to production without losing your mind.
When you deploy, Vercel is a great default for Next.js projects. It's almost absurdly simple — connect your project, click deploy, get a URL. Your prototype will be live on the internet in under a minute.
Version Control: Save Points for Your CodeGit vs GitHub, push/pull, commits, branches — the basics.
So you're working in development, building features, experimenting. How do you keep track of what's working, what changed, and how to undo something if it breaks?
Here's a mistake I made when I first started building: I didn't use version control. I'd write code for hours, things would work, I'd keep going, break something, try to fix it, break it more, and then realise I couldn't get back to the version that was working. Hours of work, gone. I had no save points. I couldn't go back.
Version control is save points in a video game. You save at a point where things work. If you die (break your code), you reload the save and try again. That's Git.
Git vs. GitHub: Two Different Things
Git is the tool that runs on your laptop. It tracks changes to your files. Every time you "commit," you're creating a save point. Git lives locally — it works even without the internet.
GitHub is a website where you store a copy of your project online. Think of it as cloud storage for your code, but smarter — it keeps track of every save point, lets others see your work, and makes collaboration possible.
Local is your laptop. It's where you write code and make save points (commits).
Remote is GitHub. It's where you store a backup and, eventually, where deployment tools like Vercel pull your code from.
Why Both Exist
You might wonder: why not just work directly on GitHub? Why do I need a local copy?
Same reason a chef doesn't cook in the pantry. You work in the kitchen (local), experiment, taste, adjust. When the dish is ready, you put it on the shelf (remote). If you tried to cook in the pantry, you'd make a mess of the stored ingredients and anyone else trying to access them.
Working locally means you can break things freely without affecting the stored, working version. When you're happy, you push your changes to the remote. If someone else has made changes on the remote, you pull them to your local.
The Commands You'll Use
You don't need to memorise these — Cursor can run them for you. But it helps to know what they mean when you see them:
git add .→ "Hey Git, I want to save the current state of all my files."git commit -m "added login page"→ "Create a save point with this description."git push→ "Send my save points to GitHub."git pull→ "Get the latest changes from GitHub to my laptop."
The one habit to build: Commit early, commit often. Every time something works — even something small — commit it. A save point every 10–15 minutes is not too often. A save point once in 2 hours is a disaster waiting to happen.
Branches (Quick Mention)
Most beginners work on a single branch called main at first. That's fine.
But in real projects with multiple people, you don't want everyone editing the same branch simultaneously. Imagine five chefs all reaching into the same pot at once — chaos. So developers create branches — separate copies of the code where they can work on a feature without disturbing everyone else. When the feature is done, the branch gets merged back into main.
You don't need to use branches at first unless you want to. But now you know what they are when someone mentions them.
What You Don't Need to Know (Yet)DNS, deep SQL, DevOps — intentionally out of scope for day one.
A few things you might be wondering about that we're deliberately skipping:
- How the internet actually works (DNS, IP addresses, TCP/IP) — not needed for building a prototype.
- Databases in detail (SQL, schemas, tables) — if your project needs to store data, Cursor will set it up for you. You just need to know the concept.
- CSS, HTML in depth — Cursor writes this for you. You'll point and say "make that button bigger" and it will.
- DevOps, CI/CD, Docker — these are important in professional engineering but completely irrelevant for going from idea to prototype.
- System design, scaling, performance — you're building for 1 user right now (you). Worry about 1 million users later.
Choosing the Right Tool: What's What in the AI Building Landscape
Before you open Cursor, it's worth understanding that Cursor is not the only tool for building with AI — and it's not always the best one for every job. Different tools are built for different use cases, and picking the right one saves you hours of frustration.
Here's how the landscape breaks down into three broad categories.
Code Editors with AI Agents — Cursor, Claude Code
Full-featured code editors (IDEs) where an AI agent sits alongside you, writing and editing code in real files on your machine. You see every file, every line, every change. You have full control.
- Building applications with both front-end and back-end logic
- Projects where you need fine-grained control over the codebase
- API integrations, server-side logic, database connections
- Projects that will grow in complexity over time
- Working with existing codebases and repos
- Developers who want to understand and own every piece of their code
- Quick, visually polished landing pages (functional but rarely beautiful)
- Non-technical users who don't want to see any code at all
- Simple automations that don't require custom code
Cursor vs. Claude Code — what's the difference?
They're similar in philosophy but different in interface. Cursor is a visual editor (built on VS Code) — you see your files, your folder tree, your terminal, all in a GUI. Claude Code is terminal-first — you interact with it entirely through the command line. Both use AI agents to write and edit code, both support planning and execution workflows.
AI App Builders — Lovable, Bolt (by Replit)
Browser-based tools that generate complete web applications from natural language descriptions. You describe what you want, the tool builds it, and you get a live preview in seconds. You can iterate by describing changes, and the tool updates the app in real time.
- Landing pages, portfolio sites, marketing pages
- Quick prototypes and MVPs where visual polish matters more than back-end complexity
- Designers who want to see results immediately without a code editor
- When you need something that *looks* great fast — stronger design sense than Cursor
- Internal tools with simple forms, dashboards, and CRUD operations
- Complex back-end logic, custom APIs, or sophisticated server-side processing
- Projects that need deep integration with external services or databases
- When you need full control over the codebase and deployment infrastructure
- Projects that will scale to production-grade applications
- Situations where you want to understand how the code works under the hood
The key distinction: Lovable and Bolt optimize for speed and visual quality. They're incredible at going from "I want a landing page for my chai brand" to a beautiful, deployed site in minutes. But the moment you need something that goes beyond front-end — authentication logic, payment processing, database queries, API rate limiting — you start hitting walls.
Think of it this way: Lovable/Bolt are like ordering from a restaurant. Fast, beautiful, but you eat what's on the menu. Cursor is like having a fully equipped kitchen — slower to start, but you can cook anything.
AI Workflow Automation — n8n, Gumloop
Visual, no-code platforms for building automated workflows. You connect apps, data sources, and AI models using drag-and-drop nodes on a canvas. Instead of writing code, you wire together triggers, actions, and logic blocks.
- Automating repetitive business processes (lead scoring, ticket triage, data enrichment)
- Connecting multiple SaaS tools (Slack → Google Sheets → CRM → Email)
- Workflows that need AI reasoning — sentiment analysis, content generation, data classification
- Non-technical teams who want to automate without any code
- Scheduled tasks, webhooks, and event-driven automations
- Scraping, processing, and routing data across systems
- Building user-facing applications (websites, web apps, mobile apps)
- Custom front-end interfaces or interactive UIs
- Projects that need a codebase, version control, or deployment pipeline
- Anything that requires a user to visit a URL and interact with something you built
n8n vs. Gumloop — what's the difference?
n8n is the more established, open-source option with a massive integration library (1000+ connectors). It's self-hostable, which makes it popular with developers and privacy-conscious teams. Gumloop is newer, AI-native from the ground up, and positions itself as the "AI agent platform" rather than just a workflow tool. Gumloop's visual builder includes AI reasoning nodes natively — every step can use an LLM — while n8n added AI capabilities on top of its existing automation framework. Gumloop is easier to start with; n8n is more powerful for complex, custom automations.
So Which Tool Should You Use?
| I want to... | Use this |
|---|---|
| Build a full application with front-end and back-end | Cursor or Claude Code |
| Build a beautiful landing page or portfolio fast | Lovable or Bolt |
| Automate a business workflow (no UI needed) | n8n or Gumloop |
| Prototype an idea quickly to see if it works | Lovable for visual, Cursor for functional |
| Connect Slack + Sheets + CRM + AI together | n8n or Gumloop |
| Build something I'll maintain and grow long-term | Cursor or Claude Code |
Good Coding Practices (& Common Mistakes That Will Make You Cry)
Who is this for? Everyone. Developers already know most of this but might pick up a thing or two. If you're new to coding, this section will save you hours of pain. Read it before you start building.
1. The .env File — Your Secrets DrawerKeep API keys out of source; use environment variables.
What it is
A .env file is a simple text file that stores sensitive information your project needs to run — API keys, database passwords, secret tokens. It lives in the root of your project and looks like this:
OPENAI_API_KEY=sk-abc123xyz789
DATABASE_URL=postgres://user:password@localhost:5432/mydb
NEXT_PUBLIC_SITE_URL=http://localhost:3000
Why it matters
These are credentials. They're like your house keys, your bank PIN, and your email password — all sitting in a plain text file. If someone gets access to them, they can use your API accounts (and rack up charges on your credit card), access your database, or impersonate your app.
The mistake people make
They put API keys directly in their code:
// ❌ NEVER DO THIS
const apiKey = "sk-abc123xyz789";
This means the key is visible in every file, and worse — when you push your code to GitHub, it's visible to the entire internet. Bots actively scan public GitHub repos for leaked API keys. You will get compromised. It's not a matter of if.
What to do instead
Put secrets in .env and reference them in your code:
// ✅ DO THIS
const apiKey = process.env.OPENAI_API_KEY;
Now your code just says "get the key from the environment." The actual key lives in .env, which you never push to GitHub (more on that next).
2. The .gitignore File — What NOT to UploadNever commit .env, node_modules, or build output.
What it is
A .gitignore file tells Git which files and folders to ignore when you commit. Anything listed in .gitignore will not be tracked, committed, or pushed to GitHub. It lives in the root of your project and looks like this:
node_modules/
.env
.env.local
.DS_Store
dist/
.next/
Why it matters
There are things in your project folder that should never leave your laptop:
.env— Your secrets. We just covered this. Never push it.node_modules/— The folder where npm installs all your dependencies. It can be hundreds of megabytes and contain tens of thousands of files. It's regenerated frompackage.jsonwhenever anyone runsnpm install, so there's no reason to upload it. Pushing node_modules to GitHub is like shipping the entire grocery store instead of just the shopping list..DS_Store— A hidden Mac file that tracks folder display settings. Useless, clutters your repo.dist/or.next/— Built/compiled output. Generated from your source code, not the source code itself.
The mistake people make
They either don't have a .gitignore (so everything gets pushed) or they add .gitignore after they've already committed sensitive files. Here's the thing: Git has a memory. Even if you add .env to .gitignore after you've already committed it once, the old commit still contains your secrets in the Git history. Someone can go back through your commits and find them.
What to do instead
Set up .gitignore as the very first thing when creating a new project — before you write any code, before you add any secrets. Most frameworks generate a sensible .gitignore by default, but always double-check that .env is in there.
3. Committing: The Art of When to SaveCommit when a unit of work works; avoid noisy history.
The mistake: not committing enough
This is the most common beginner mistake, and it's the one that hurts the most. You code for two hours straight. Everything is working beautifully. You make one more change. Something breaks. You try to undo it. You can't remember what you changed. You try to fix it. Now three things are broken. There's no save point to go back to. Two hours of work, gone.
The other mistake: committing too much noise
On the flip side, committing after every single line change creates a history that looks like:
"fixed typo"
"fixed another typo"
"actually fixed it this time"
"why isn't this working"
"okay now it works"
"no it doesn't"
"FINALLY"
This isn't useful to anyone — including future you.
The right rhythm
Commit when a unit of work is complete. A "unit of work" is the smallest change that makes sense on its own. Some examples:
- ✅ "Added login form with email and password fields"
- ✅ "Connected weather API and displaying current temperature"
- ✅ "Fixed bug where form submitted without validation"
- ✅ "Set up project scaffolding and initial folder structure"
A good rule of thumb: commit every time something works that didn't work before. If you just got the login form to render, commit. If you just hooked up the API and data is flowing, commit. If you just fixed a bug, commit. You're creating a trail of breadcrumbs you can follow back.
For solo developers vs. teams
Solo: You're the only one working on the code, so your commit rhythm is for your own safety. Commit to your local often. Push to remote (GitHub) at the end of a working session or when you've completed a meaningful chunk. There's less urgency to push constantly because nobody else is waiting for your changes.
Teams: Push to remote frequently because others depend on your changes. Pull from remote before starting work each day so you have the latest code. Commit and push at least once per meaningful feature — don't go dark for three days and then push a massive dump of changes. Your teammates will not be happy.
When to raise a PR
A Pull Request should represent a complete feature or fix. Not half a feature. Not "I'm done for the day." A PR says: "This thing works, I've tested it, it's ready to be merged into the main codebase." For solo projects while you're learning, you probably won't need PRs — just commit and push to main. But it's good to know the concept for when you work with others.
4. Folder Structure — Don't Throw Everything in One PileOrganize by concern so you and Cursor stay sane.
The mistake
Your project looks like this:
my-project/
├── index.js
├── app.js
├── server.js
├── login.js
├── signup.js
├── dashboard.js
├── api.js
├── helpers.js
├── utils.js
├── styles.css
├── more-styles.css
├── test.js
├── data.json
├── old-backup.js
├── old-backup-2.js
└── TODO.txt
15 files in the root. No folders. No organization. You spend more time finding files than editing them. And when Cursor's agent looks at this project, it has no structural clues about what goes where — so it starts creating files in random places too, and the mess compounds.
What to do instead
Organize by concern. A typical Next.js project should look something like:
my-project/
├── src/
│ ├── app/ ← Pages and routing
│ │ ├── page.tsx
│ │ ├── layout.tsx
│ │ └── dashboard/
│ │ └── page.tsx
│ ├── components/ ← Reusable UI pieces
│ │ ├── Button.tsx
│ │ ├── Navbar.tsx
│ │ └── LoginForm.tsx
│ ├── lib/ ← Utility functions & helpers
│ │ ├── api.ts
│ │ └── utils.ts
│ └── styles/ ← Stylesheets
│ └── globals.css
├── public/ ← Static files (images, icons)
├── .env ← Secrets (not committed)
├── .gitignore
├── package.json
└── README.md
You don't need to memorize this. The boilerplate repos for the projects below already have this structure set up. The point is: when you ask Cursor to create a new component, it should know where to put it. Good structure gives the AI (and you) clear conventions.
5. Documentation — Your Future Self Will Thank YouREADME, brief, comments on non-obvious logic.
The mistake
You build something. It works. You move on. Three weeks later, you come back to add a feature. You open the project and think: "What the hell does any of this do?"
This is bad enough for you. It's even worse for Cursor. Every time you start a new Cursor session or a new agent is spawned, it has zero memory of what happened before. It looks at your codebase fresh. If there's no documentation, the agent has to infer everything from the code itself — which burns tokens, takes longer, and produces worse results because it's guessing at your intent.
What to document
README.md — Every project should have one. It should answer: What is this project? How do I run it? What's the folder structure? What are the key technologies used? This is the first thing both humans and AI agents read when they encounter your project.
Project brief / PRD — A short document (even just a few paragraphs) that describes what you're building, who it's for, and what the key features are. This is gold for Cursor's planning mode — when the agent has a clear project brief, it makes dramatically better decisions about architecture and implementation.
Inline comments for tricky logic — If you've written (or Cursor has written) something non-obvious, add a comment explaining why, not what. The code shows what's happening; the comment explains the reasoning.
What NOT to document
Don't over-document. You don't need a comment on every line. You don't need a 10-page architecture doc for a personal project. A good README, a short project brief, and comments on the non-obvious stuff — that's the sweet spot.
Exercise: Investigate the Calculator App
Time to get your hands dirty. We've built a simple calculator app for you to explore. This is not a "build from scratch" exercise — the app is already built. Your job is to investigate it, understand how it works, and make a small change.
Clone the calculator repo and follow the instructions in the README:
👉 github.com/kupsas/learn-cursor-s0-calculator
The README has everything you need — setup steps, investigation prompts for Cursor's Ask mode, and suggestions for your first code change. When you've made a change and it works, commit it. That's your first real act of software engineering.
Building With Cursor
Who is this section for? Everyone. If you completed the previous section, you now know what a web app looks like, what languages and frameworks are, and how version control works. If you're a developer, you already knew all that — you're starting here. Either way, this section is where you learn how to actually build things with an AI coding agent.
What this section is NOT: A prompting tips-and-tricks list. There are a thousand blog posts about that. This section teaches you a workflow — a repeatable system for going from "I have an idea" to "I have a working prototype." The workflow matters more than any individual prompt.
The Vibe Coding Death Spiral (What NOT to Do)
Here's how most people use Cursor when they first discover it:
- Open Cursor
- Type "build me a [thing]"
- Watch it generate a bunch of code
- It doesn't quite work
- Type "fix it"
- It fixes one thing and breaks another
- Type "no, fix the other thing too"
- Repeat steps 5–7 for an hour
- Give up or end up with something you don't understand
This is vibe coding. It works for tiny things. It falls apart completely for anything with more than one moving part. The rest of this section teaches you what to do instead.
The Core Workflow: Plan → Build → Validate → Commit
This is the workflow that actually works. It has four stages, three different AI models, and one human (you) making the final call.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 1. PLAN │ → │ 2. BUILD │ → │ 3. VALIDATE │ → │ 4. COMMIT │
│ │ │ │ │ │ │ │
│ Smart model │ │ Cheap model │ │ Different │ │ Human checks │
│ in browser │ │ in Cursor │ │ smart model │ │ then commits │
│ │ │ │ │ in Cursor │ │ │
│ Claude Opus │ │ Auto / │ │ GPT 5.4 │ │ You, clicking│
│ or GPT 5.4 │ │ Composer 2 │ │ or Gemini │ │ around the │
│ │ │ │ │ 3.1 │ │ actual app │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
Let's break each stage down.
Stage 1: Plan (In Your Browser, Not Cursor)
Before you write a single prompt in Cursor, you need to know what you're building. Not vaguely — specifically.
Open Claude (claude.ai) or ChatGPT in your browser. Have a conversation. Not a one-line prompt — an actual back-and-forth where you figure out:
- What am I building? (A portfolio site? A dashboard? An API integration?)
- Who is it for? (Me? My team? Public users?)
- What are the core features? (List 3–5. Not 15. Three to five.)
- What does the tech stack look like? (For this guide: Next.js, TypeScript, Tailwind CSS)
- What's the design direction? (Colors, tone, reference sites you like)
- What does the folder structure look like?
The output of this conversation should be a project brief or PRD — a single document that captures all of this clearly. You'll put this document in your project repo.
Here's a template to start the conversation:
"I want to build [type of app]. It's for [who]. The main features are [list 3-5]. I want it to feel like [reference sites/apps]. The tech stack is Next.js, TypeScript, and Tailwind CSS. Can you help me create a structured project brief that I can give to an AI coding agent? Ask me any clarifying questions before writing it."
Why plan in the browser and not in Cursor?
Economics. Planning is a long, exploratory conversation — you're going back and forth, brainstorming, refining ideas, debating approaches. This burns a lot of tokens. If you do this inside Cursor using an API-billed model like Claude Opus, you're paying API rates for what is essentially a thinking session. Your Claude or ChatGPT subscription in the browser gives you far more generous usage for this kind of extended conversation. Save your Cursor tokens for building. Use your browser subscription for thinking.
One document, not five
A learning from experience: keep your project brief as one single document, even if it gets long. You might be tempted to split it into separate files — a design brief, a tech brief, a product brief. Don't. Here's why: when you have multiple documents, you have to update all of them every time something changes. You will forget. And then your documents will contradict each other, and the AI will get confused because it's reading conflicting instructions. One document, one source of truth. Update it in one place. Done.
Stage 2: Build (In Cursor, Step by Step)
Now you move to Cursor. But you don't just start typing "build everything." There's a specific sequence.
Step 1: Switch to Plan Mode
Open the agent chat panel in Cursor (Cmd+L / Ctrl+L). Switch to Plan mode (not Agent mode — Plan mode specifically). Point it at your project brief:
"Read the project brief in [filename]. Create a detailed implementation plan for building this project. Break it down into steps, where each step produces a working, testable piece of the application."
Use a smart model for planning. Switch your model to Claude Opus 4.6, GPT 5.4, or Gemini 3.1. These are thinking models — they're better at strategy, architecture, and breaking a big project into logical steps. They cost more per token, but planning is a short conversation with high leverage. A good plan saves you hours of building.
Step 2: Evaluate the plan size
Look at what the planning model produced. This is where you make a judgment call:
- If the plan has 5–8 steps, it's probably the right size. Proceed as a single plan.
- If the plan has 15+ steps, the PRD is too big for one pass. Break it into phases. Ask the planning model: "This is too many steps for one session. Can you group these into 3–4 phases, where each phase produces something independently testable?" Then execute one phase at a time.
Over time, you'll develop intuition for what "too big" looks like. For now, err on the side of smaller plans. It's much easier to combine two small plans than to recover from a massive plan that went sideways in step 11.
Step 3: Execute the plan
Now switch to Agent mode and switch your model to a cheaper execution model. Composer 2 is preferred — it consumes the least tokens. These are fast, capable coding models that excel at implementation when given a clear plan.
A critical note on Cursor's usage model: Cursor has two categories of usage:
- Composer and Auto usage — Very generous allocation. This is where most of your execution-level coding should happen. It's cheap, it's fast, and it handles most coding tasks well.
- Premium model usage (Opus 4.6, GPT 5.4, Gemini 3.1) — More limited. Use these for planning, validation, and genuinely tricky execution problems. Don't burn premium tokens on routine code generation.
Feed the plan to the agent one step at a time:
"Execute step 1 of the plan: [description of step 1]. Follow the conventions in .cursorrules."
Let the agent work. When it's done with that step, verify it works (run the app, check the output), then move to step 2.
Don't skip the verification between steps. If step 1 is broken and you pile steps 2, 3, and 4 on top, you now have four layers of code built on a broken foundation. Debugging that is miserable. Catch problems while they're small.
Step 4: Handle tricky execution
Sometimes the cheap model struggles — it can't figure out a complex API integration, it keeps producing the wrong logic, or it's going in circles. This is when you escalate:
- First try with Sonnet or one of the mid-tier models. Often that's enough.
- If Sonnet can't handle it, bring in Opus 4.6 or GPT 5.4. The big guns. They're more expensive but they solve the hard problems.
- Very rarely, even the best models get stuck. This usually means something is fundamentally wrong with the approach, not just the implementation. This is when talking to a human developer helps — they can spot architectural issues that no amount of LLM token-burning will fix.
Stage 3: Validate (Before You Commit)
A step has been executed. The code looks right. The agent says everything is fine. Don't commit yet.
Here's the key move: use a different smart model than the one you used for planning to review the work. If you planned with Claude Opus, validate with GPT 5.4 or Gemini 3.1. If you planned with GPT 5.4, validate with Opus or Gemini. The reason: a different model brings a different perspective. It catches things the planning model's "thinking style" might have missed.
Ask the validation model to look at the git diff:
"Look at the changes I've made (the git diff). Compare them against the plan and the project brief. Be strict. Check: are all requirements from this step met? Are there any bugs, edge cases, or missing error handling? Is the code consistent with the .cursorrules conventions?"
This is your validation agent. It's the code reviewer that catches problems before they reach production.
Then You Step In
Once the validation model gives the green light, you personally check the app. Open it. Click around. Try to break it. Enter weird input. Resize the browser. Do the things a user would do.
Why? Because agents check code. They read logic, trace execution paths, verify syntax. What they don't do is use the app as a human. They won't notice that the button color clashes with the background. They won't feel that the loading state is too slow. They won't catch that the form "works" but the success message appears behind a div. Human testing catches UX issues that code review misses.
When to do a human check vs. when to skip it:
- Finishing a major feature? Always check.
- Fixed a significant bug? Always check.
- Completed a minor sub-step within a larger feature (like adding one field to a form that isn't functional yet)? You can skip the human check and move to the next sub-step. But commit anyway.
Stage 4: Commit
The validation agent approved. You clicked around and it works. Now commit.
git add .
git commit -m "Added hero section with name, tagline, and CTA button"
Descriptive message. Not "update." Not "fix." What did you actually add or change?
Then move to the next step in the plan and repeat the cycle.
When Things Break: The Debugging Escalation Ladder
Things will break. Code will error. Features won't work as expected. This is normal — it's not failure, it's coding. Here's how to handle it efficiently:
Step 1: Read the error message
Start from the last line. It usually tells you what went wrong in plain English. (See the Good Coding Practices doc for more on this.)
Step 2: Give Cursor context
Switch to Debug Mode (press Shift+Tab in the Cursor chat). Debug Mode is purpose-built to streamline the debugging process: it leverages in-app logging to surface execution traces, helping you pinpoint where things may be going wrong. The agent will automatically generate hypotheses about potential causes, guide you through reproducing the bug, and use trace evidence to validate or eliminate each hypothesis. This structured approach accelerates troubleshooting and leads to faster, more accurate fixes.
While using Debug mode, don't just say "fix this." Say:
"The signup form renders correctly, but when I click Submit, nothing happens. No error in the console either. The form should send data to /api/signup and show a success message. Can you check why the button's onClick isn't firing?"
Context makes the fix faster and more accurate.
Step 3: Escalate through models
If the fix isn't working, move up the model ladder:
- Start with Auto / Composer 2 — The cheapest option. Handles most straightforward bugs.
- Move to Sonnet — If the cheap model is going in circles or the bug is more complex.
- Escalate to Opus 4.6 / GPT 5.4 — The rocket launcher. For genuinely tricky bugs where the logic is subtle or the issue spans multiple files.
- Talk to a human developer — If even the best models can't solve it, something is likely wrong at an architectural level. A human can spot structural issues that LLMs miss. Honestly, this almost never happens — Opus usually solves it — but it's worth knowing the option exists.
Step 4: If you're going in circles
If you've been pasting the same error back and forth for 10+ minutes and it's not converging, stop. Undo back to your last working commit and try a different approach entirely. Sometimes the path is wrong, not the fix.
Context Engineering: The Skill That Makes Everything Else Work
The quality of what Cursor builds for you is almost entirely determined by the quality of context you give it. Same model, same tool, same capabilities — but one person gets a polished, working app and another gets generic garbage. The difference is context.
Context engineering is the practice of deliberately giving your AI agent all the information it needs to do good work. Think of it like briefing a contractor. If you say "build me a house," you'll get something. If you say "build me a 3-bedroom house in Kerala, single story, with a courtyard in the center, budget of ₹40 lakhs, and here are three houses I like the style of," you'll get something dramatically better.
Layer 1: The Project Brief
This is the document you created during the planning phase. It lives in your repo (as project-brief.md or PRD.md or whatever you want to call it) and describes:
- What the project is
- Who it's for
- What the core features are
- What the tech stack is
- What the design direction is (colors, tone, reference sites)
- Any constraints or requirements
- Technical architecture and data models
This is the single most important piece of context in your entire project. When you tell Cursor "read the project brief and build the hero section," the agent has the full picture. Without this file, every prompt requires you to re-explain the context from scratch. With it, every prompt builds on a shared understanding.
Remember: one document, not five. Keep it all in one place. Update one file. No contradictions.
Layer 2: The Cursor Rules File
The project brief tells Cursor what to build. The rules file tells it how to build — your coding conventions, preferences, and constraints that apply to every interaction.
A .cursorrules file (or files in .cursor/rules/) lives in your project root and is automatically read by Cursor for every prompt.
Don't write this file manually. Instead, create a plain markdown file describing your conventions and preferences in normal English. Then ask Cursor:
"Here's a markdown file with my coding conventions and preferences. Can you create a proper .cursorrules file from this?"
Cursor knows the format. Let it handle the YAML structure and syntax. You focus on the content — what rules you actually want enforced.
What goes in a rules file:
- Language and framework preferences (TypeScript, not JavaScript; Tailwind, not CSS modules)
- Folder structure conventions (components go here, pages go there)
- Code style (functional components, named exports, comment non-obvious logic)
- Git conventions (descriptive commit messages, never commit .env)
- Behavior rules (don't install packages without mentioning it, read existing code before creating new files)
This is your employee handbook for the AI. Without it, Cursor makes its own decisions about style and conventions. With it, every session starts from the same playbook.
Layer 3: In-Prompt Context (Iterative Refinements)
Layers 1 and 2 are set up once and apply to everything. Layer 3 is where you refine and fix things as you go.
After the first pass from the project brief is built, you step in. You use the app. You notice things. The authentication works, but there's no validation on the email field. The dashboard renders, but the cards look cramped on mobile. The API returns data, but there's no loading state.
This is when your prompts get precise:
"I just tested the login form. A few issues to fix: 1. If I enter an email without an @ sign, the form still submits. Add email format validation. 2. The password field should require at least 8 characters and show an error if it's shorter. 3. When I submit an invalid form, show a toast notification listing what's wrong. 4. The 'Sign In' button should show a loading spinner while the API call is in progress."
These targeted, specific refinements are where the app goes from "it runs" to "it actually works well." Each fix-set gets its own build → validate → commit cycle.
Layer 4: External Context via MCPs (Advanced — Covered in Advanced Workflows)
There's a fourth layer that we'll cover in the advanced section: Model Context Protocol (MCP) integrations. These let you pull context from outside your codebase — from Linear or Jira tickets, Slack threads, Figma designs, Notion docs, and more. Instead of copy-pasting information from those tools into your prompts, MCPs pipe it directly into Cursor's context.
This is a genuine power move for teams — imagine your Cursor agent automatically reading the acceptance criteria from a Linear ticket and the design specs from Figma, then implementing the feature with all that context baked in. We'll cover how to set this up in Advanced Workflows.
Tips That Will Save You Time
Use Ask mode to understand code you didn't write. Select any block of code, press Cmd+L, and ask "What does this do?" Cursor will explain it in plain English. Invaluable when the agent generates something and you want to understand it before moving on.
Don't accept code you don't understand. It's tempting to let Cursor generate everything and move on. Resist this. If it creates a file and you don't know what it does, ask. You don't need to understand every line, but you should understand every file and its purpose. Otherwise, when something breaks, you won't know where to look.
Keep your context window clean. If you've been going back and forth with Cursor for 20+ messages and it's starting to get confused or repeat mistakes, start a new chat. Long conversations accumulate stale context and the agent starts contradicting itself. A fresh chat with a clear prompt often works better than message #47 in a tangled thread.
Commit before you experiment. Want to try a different approach? Commit what you have first. Now you can experiment freely. If the experiment fails, roll back. If it works, commit again. Your save points are your safety net.
Pick Your Project and Start Building
You've got the workflow. You've got the context engineering fundamentals. Now it's time to build something.
Choose one (or more) of the five projects below based on what interests you:
| Project | What You Build | Best For | Repo |
|---|---|---|---|
| 1. Portfolio / Landing Page | A personal website with hero, about, projects, and contact sections | Designers, founders, anyone wanting a web presence | Clone repo → |
| 2. Personal Dashboard | A tracker for habits, tasks, reading, or anything you want to monitor | PMs, founders, spreadsheet lovers | Clone repo → |
| 3. API-Powered App | An app that pulls real data from a public API (weather, movies, news) | Developers, technically curious PMs | Clone repo → |
| 4. Script / Automation | A command-line tool that processes data files — no front-end needed | PMs who automate, data-curious people | Clone repo → |
| 5. AI-Powered Mini App | A web app with an LLM integration (chatbot, summarizer, tone adjuster) | Anyone who wants the "wow" factor | Clone repo → |
Each project has its own repo with boilerplate code, a detailed README with setup instructions, a .cursorrules file, and context files. Clone the one you want and follow the README to get started.
The workflow for every project is the same:
- Clone the repo and run
npm install→npm run dev - Create your project brief (use Claude/ChatGPT in the browser)
- Drop the brief into the repo
- Open Cursor → Plan mode → Smart model → Create implementation plan
- Switch to Agent mode → Cheap model → Execute step by step
- Validate each step → Different smart model reviews the diff
- You check the app → Commit → Next step
Remember: Plan → Build → Validate → Commit. Use cheap models for execution, smart models for planning and review. Commit after every working step.
Go build something.
Advanced Workflows
Who is this section for? People who already know how to use Cursor. You've built things. You've used the plan-build-validate loop. You have a personal project or a work codebase. This section is about going from "I can build things with Cursor" to "I have a genuinely powerful AI-augmented development workflow."
If you're still working through Building With Cursor, stay there. This section will be here when you're ready. There's no rush.
What This Section Covers
Five features that, when combined, turn Cursor from a smart code editor into something closer to an AI development team:
- Hooks — Automated checks that run before or after the agent acts
- MCPs — Pulling external context from tools like Linear, Figma, Slack, and Jira into Cursor
- Subagents — Specialized AI agents that handle specific tasks in parallel
- Skills — Reusable workflows the agent can invoke when relevant
- Git Worktrees — Parallelizing work across multiple branches simultaneously
Each of these is independently useful. Together, they compound.
1. Hooks: Automated Guardrails for Your Agent
What They Are
Hooks are scripts that run automatically at specific points in the agent's workflow — before it submits a prompt, before or after it uses a tool, or when it finishes a task. They're guardrails. They run checks, enforce rules, and catch mistakes without you having to remember to do it manually every time.
Why They Matter
Think about the things you do repeatedly after the agent finishes a step: you run the linter, you check if tests pass, you verify the build doesn't break, you check that documentation was updated. Hooks automate all of this. Instead of you remembering "oh wait, I should run tests," the hook fires automatically and catches the problem before you even see the output.
Real Use Cases
Auto-lint after every code edit. The agent writes code, the hook runs ESLint, and if there are issues, they get flagged immediately — before you accept the changes.
Run tests before committing. A pre-commit hook runs your test suite. If tests fail, the commit is blocked. You never push broken code.
Update documentation after major changes. After a significant code edit, a hook can prompt the agent to update the relevant README or docs. Documentation stays in sync with code — the thing every team says they'll do and nobody actually does.
Validate that .env keys aren't exposed. A hook scans the staged files for hardcoded API keys or secrets before allowing a commit. Catches the most common vibe-coding mistake automatically.
How to Set Them Up
Hooks are defined in .cursor/hooks/ as JSON files. Each hook specifies when it runs and what script to execute. Here's a simple example of a post-edit linting hook:
{
"event": "afterEdit",
"command": "npx eslint --fix {{filePath}}",
"description": "Auto-fix lint issues after every file edit"
}
The best approach: start with zero hooks and add them reactively. When you notice yourself doing the same manual check for the third time, that's a hook. Don't over-engineer from day one.
Guide exercise: Set up a pre-commit hook that runs
npm run lintbefore allowing any commit. Break the lint rule on purpose (remove a semicolon, usevarinstead ofconst). Watch the hook catch it.
2. MCPs: Pulling the Outside World Into Cursor
What They Are
MCP stands for Model Context Protocol. It's a standard that lets Cursor connect to external tools and pull data directly into the agent's context. Instead of copy-pasting a Jira ticket description into your prompt, an MCP integration lets Cursor read the ticket itself.
Why They Matter
Remember the context engineering layers from Building With Cursor? Layer 4 was external context. MCPs are how you actually implement it. They're the bridge between your codebase and the rest of your workflow — project management, design tools, communication, documentation.
Without MCPs, your workflow looks like:
- Read the Linear ticket in your browser
- Copy the requirements
- Paste them into Cursor
- Hope you didn't miss anything
With MCPs:
- Tell Cursor: "Read Linear ticket ENG-342 and implement it"
- The agent fetches the ticket, reads the requirements, and starts building
That's it. The context flows automatically.
What You Can Connect
MCPs exist for a growing list of tools. Some of the most useful ones:
- Linear / Jira / Asana — Pull ticket details, acceptance criteria, and linked issues directly into Cursor. The agent reads the ticket and implements it.
- Figma — Pull design specs, component dimensions, color values, and layout information. The agent builds what the designer designed, not its own interpretation.
- Slack — Pull conversation threads for context. "Here's the Slack thread where the team discussed the approach for this feature."
- Notion / Confluence — Pull documentation, specs, meeting notes. Great for project briefs that live outside the codebase.
- GitHub — Pull issue details, PR comments, review feedback. The agent reads the code review and addresses the comments.
How to Set Them Up
MCP servers are configured in .cursor/mcp.json in your project (or globally in your Cursor settings). Here's an example connecting a Linear MCP:
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@anthropic/linear-mcp-server"],
"env": {
"LINEAR_API_KEY": "your-api-key-here"
}
}
}
}
Once connected, the agent can access Linear tools — searching issues, reading ticket details, updating statuses — all from within Cursor's chat.
You can also install MCPs from the Cursor Marketplace using /add-plugin in the agent chat. This is the fastest way to get started — browse what's available and install with one click. Partners include Figma, Linear, Stripe, AWS, Amplitude, and many more.
Guide exercise: If you use Linear, Jira, or GitHub Issues for your work, set up the corresponding MCP. Pick a real ticket and ask Cursor to implement it by reading the ticket directly. Notice how much better the output is when the agent has the actual requirements versus your paraphrased version.
3. Subagents: Specialized AI Workers in Parallel
What They Are
Subagents are independent AI agents that run alongside the main Cursor agent. Each subagent has its own context window, its own instructions, and can be given specific tool access. They run in parallel — one subagent can be writing tests while another generates documentation while you discuss architecture with the main agent.
Why They Matter
Without subagents, the Cursor agent is serial — it does one thing at a time. Read a file, think, write code, run a command, wait, repeat. For simple tasks, that's fine. For complex work across multiple files and concerns, it becomes a bottleneck.
Subagents break that bottleneck. They're like having a small team instead of a single assistant. Each one is specialized, each one works independently, and the main agent orchestrates them.
Built-In Subagents
Cursor ships with three subagents out of the box:
- Explore — Navigates large repos, finds relevant files, and builds context without polluting the main conversation. Useful when you need to understand a codebase before making changes.
- Bash — Runs shell commands in isolation. The main agent doesn't have to stop and wait for terminal output.
- Browser — Handles browser interactions (screenshots, testing, visual verification) in a separate context, filtering down to relevant results.
Custom Subagents
This is where it gets powerful. You can define your own specialized agents as markdown files in .cursor/agents/:
---
name: security-auditor
description: Reviews code changes for security vulnerabilities.
Use when new endpoints, auth logic, or data handling are added.
model: inherit
readonly: true
is_background: false
---
You are a security auditor. Review all code changes for:
- SQL injection vulnerabilities
- Missing input validation
- Exposed API keys or secrets
- Insecure authentication patterns
- Missing rate limiting on public endpoints
Be specific about the file, line, and issue. Suggest fixes.
A few key fields:
- description — Critical. The main agent reads this to decide when to delegate. Write it like a job description: specific about when to use this subagent. Vague descriptions mean the agent either delegates everything or nothing.
- model —
inherituses whatever model the main agent is using.fastuses a cheaper model. You can also specify a model explicitly. - readonly — If
true, the subagent can read code but not modify files. Perfect for reviewers and auditors. - is_background — If
true, the subagent works in the background without blocking the main conversation.
Practical Patterns
Code + Tests in parallel. The main agent implements a feature. A test-writer subagent generates tests for the new code simultaneously. Both finish around the same time.
Implementation + Documentation. The main agent builds the feature. A documentation subagent updates the README and inline docs. Documentation never falls behind.
Build + Security audit. While the main agent implements, a readonly security auditor subagent reviews every change for vulnerabilities. Issues are flagged in real time.
Common Mistakes
Vague descriptions. "Helps with code" tells the main agent nothing. Be specific: "Reviews API endpoints for security vulnerabilities. Use when new routes, auth logic, or database queries are added."
Too many subagents. Three to four custom subagents is a sweet spot. Ten subagents creates chaos — the main agent spends more time delegating than working.
Not setting readonly where appropriate. A review subagent that can edit files will start "fixing" things on its own. If its job is to review, make it readonly.
Guide exercise: Create a documentation-writer subagent in
.cursor/agents/doc-writer.md. Set it asis_background: true. Make a code change to your project and watch the subagent automatically update documentation in parallel.
4. Skills: Reusable Workflows for Your Agent
What They Are
Skills are packaged bundles of domain-specific knowledge, workflows, and scripts that the agent can invoke when relevant. They're defined in SKILL.md files and can include custom commands (triggered with / in the agent input), scripts, and specialized instructions.
How They Differ from Rules
Rules are always active — they apply to every interaction. Skills are dynamic — the agent loads them only when it decides they're relevant. This keeps your context window clean while giving the agent access to specialized capabilities when needed.
Think of it this way: Rules are your employee handbook (always in effect). Skills are specialized training manuals (pulled off the shelf when a specific task comes up).
Real Use Cases
Deployment skill. You define a SKILL.md that describes your deployment process — which commands to run, in what order, what checks to perform, how to handle rollbacks. When you say "deploy to staging," the agent invokes this skill and follows the workflow exactly.
Database migration skill. A skill that knows how to create migrations, run them, verify data integrity, and rollback if something goes wrong. Instead of you remembering the 8-step process, the agent follows the skill.
Code review skill. A skill that defines what to look for during review — performance implications, security concerns, consistency with team patterns, test coverage. Invoke it with /review and get a structured review.
Creating a Skill
Create a SKILL.md file in your project root or in .cursor/skills/:
# Deploy to Staging
## When to Use
Use this skill when the user asks to deploy, push to staging,
or prepare a release.
## Steps
1. Run `npm run build` and verify no errors
2. Run `npm run test` and verify all tests pass
3. Check that all environment variables are set in `.env.staging`
4. Run `vercel deploy --prebuilt` to deploy to staging
5. Verify the deployment by opening the staging URL
6. Report the staging URL and any warnings
## Rollback
If deployment fails, run `vercel rollback` and report the error.
You can also invoke skills directly using the / slash command menu in the agent chat.
Guide exercise: Create a skill for a workflow you do repeatedly in your project. It could be deployment, database seeding, generating test data, or running a full CI check locally. Test it by invoking it with
/.
5. Git Worktrees: Parallel Development Across Branches
What They Are
A git worktree is an additional working directory linked to the same repository. Each worktree has its own files, its own branch, and its own state — but they all share the same git history. You can have main in one directory, feature/auth in another, and feature/dashboard in a third — all editable, all active, all at the same time.
Why They Matter for AI-Powered Development
This is where things get genuinely exciting. Without worktrees, the Cursor agent works on one thing at a time in one directory. With worktrees, you can:
- Open multiple Cursor windows, each pointed at a different worktree
- Run a separate agent in each window, working on a different feature simultaneously
- Each agent has complete isolation — no file conflicts, no context pollution
- When both features are done, you merge the branches
You're essentially running a team of AI developers in parallel, each with their own workspace.
How to Set Them Up
# Create a worktree for a new feature branch
git worktree add ../my-project-auth -b feature/auth
# Create another worktree for a second feature
git worktree add ../my-project-dashboard -b feature/dashboard
# Now you have three directories:
# ./my-project → main branch
# ../my-project-auth → feature/auth branch
# ../my-project-dashboard → feature/dashboard branch
Open each directory in a separate Cursor window. Each gets its own agent, its own terminal, its own context. They work independently.
When done:
# Merge and clean up
cd my-project
git merge feature/auth
git merge feature/dashboard
git worktree remove ../my-project-auth
git worktree remove ../my-project-dashboard
Cursor 3 also has a built-in /worktree command that automates this — it creates the worktree, spawns an agent, and manages the lifecycle for you. You can run up to 8 parallel agents this way.
When to Use Worktrees
Worktrees shine when you have two or more tasks that are genuinely independent — they touch different files, different parts of the codebase, different concerns. Examples:
- Front-end feature + back-end API (different directories, minimal overlap)
- New feature + writing tests for an existing feature
- Feature work + documentation update
- Two bug fixes in unrelated parts of the codebase
When NOT to Use Worktrees
When the tasks touch the same files. Two agents editing page.tsx simultaneously will create merge conflicts. That's not a tooling problem — that's a fundamental constraint of parallel work on shared resources.
When the codebase shares state that isn't isolated. Databases, Docker volumes, cache directories — these are shared across worktrees. Two agents running migrations simultaneously is a recipe for corrupted data.
For small tasks that the main agent handles in minutes. Worktrees have overhead — setup, context for each agent, merging, cleanup. If the task is "add a button," don't spin up a worktree. Just do it.
Risks to Be Aware Of
Disk space. Each worktree is a full checkout of your codebase. A 2GB repo with three worktrees is 6GB+ on disk. Build artifacts and node_modules multiply this. Clean up worktrees you're done with.
Merge conflicts with yourself. If two worktrees accidentally touch the same file, you'll have to resolve conflicts when merging. This is confusing because you're both sides of the conflict.
Cost. Running multiple agents with premium models in parallel burns tokens fast. Use cheaper models for execution in worktrees and save premium models for planning and review in your main branch.
Guide exercise: If you have an existing project, create two worktrees for two independent tasks — one for tests, one for documentation. Open each in a separate Cursor window. Run agents simultaneously. Merge both when done.
A Note on Cloud Agents
Cursor also offers Cloud Agents — agents that run on remote machines in the cloud rather than on your laptop. They clone your repo, get their own isolated environment, and work autonomously. In theory, this means you could fire off a task, close your laptop, and come back to a completed PR.
I'm mentioning this for completeness, but I have not personally used Cloud Agents extensively. The concept is compelling — especially for long-running tasks or when you want true parallelism without your laptop heating up — but I'm not comfortable teaching something I haven't battle-tested.
If you want to explore it, check out Cursor's docs on Cloud Agents. And if you try it and it's amazing, tell me — I'd love to hear about your experience.
Similarly, Cursor has CLI tools, team/enterprise features, and a growing plugin marketplace that I won't cover in depth here. They're worth exploring on your own, but they're not in my daily workflow yet, and I'd rather be honest about that than pretend to be an expert.
Putting It All Together
These five features aren't meant to be used in isolation. The real power comes from combining them:
- MCPs feed external context into your agent → better planning, more accurate implementation
- Subagents parallelize the work → tests, docs, and security reviews happen alongside coding
- Skills codify repeatable workflows → deployment, migration, and review become one-command operations
- Hooks enforce quality automatically → linting, testing, and security checks run without you remembering
- Worktrees multiply everything → run the entire setup across multiple features simultaneously
Start with whichever one solves your biggest pain point today. Add the others as you need them. Don't try to set up all five at once — that's a recipe for spending an afternoon configuring tools instead of building things.