How I Ship With Cursor

March 4, 2026 -- 8 min read

I'm El Mehdi Choukri, a software engineer who builds across backend, frontend, and sometimes the whole stack. I've shipped GPU-backed moderation at scale, full marketplace systems with real money flows, and medical SaaS with RAG and document pipelines. I don't say that to flex. I say it because the way I build has changed completely, and I want to be specific about how.

The progression is easier to show in numbers than words. School years: low-level C and system projects, a few hundred lines a month. GitHub Copilot pushed it to a few thousand. Then Cursor, March 2025. Six months in, the average was around 8,000 net lines a week. The three months after December nearly doubled the three before that. I'm not sure the numbers fully capture it, but they're the closest thing to proof I have.

This is how I use Cursor and why. Some of it might feel obvious. Some of it took me a while to figure out. All of it is what I actually do.

The Setup

You architect. The agent programs. Your job is the mental model and the design calls. Its job is implementation. A solid PRD and clear context beat everything else.

Linus Torvalds and Andrej Karpathy have both said we're past the threshold. As of late 2025, the agent writes better code than most engineers in non-critical systems. If you're not building this way, you're slow. That sounds harsh. I think it's true.

Core Ideas

The agent knows more than you (about code)

In non-critical systems, the agent knows more about good code than I do. I let it handle the details. I focus on what to build and why, not how the loops work.

That doesn't mean I go passive. I still catch when it drifts from my mental model, misunderstands the domain, or picks the wrong abstraction. The agent is a programmer, not a software developer. It doesn't have product judgment. I do. I keep that.

Your value is the mental model

Your value is in the real-world picture: problem domain, user flows, constraints, trade-offs. The agent can't know which button matters more, how the business logic maps to reality, or why we made that call last quarter. That's on you.

Give it specs. Make everything visible. Design is yours; implementation is theirs. The more you bring, the less it guesses, the better the output.

Assumptions Compound

Bad vibe code happens when the LLM guesses. Every assumption is a potential mismatch with your intent. Give it specs, not freedom. A solid PRD is the floor. Not optional.

Don't be lazy. Read the codebase first. Pull in docs. Ask clarifying questions in Plan mode before you let it run. Lacking context leads straight to assumptions. One wrong guess early turns into five wrong files later. I've done this. It sucks.

Tell the agent to ask you. Before big tasks, have it surface everything it needs clarified before writing a line. This one habit cuts most revision loops.

Code quality matters more than ever

Bad code tanks AI productivity by at least 10x. The agent pattern-matches on everything it sees. Bloat, inconsistency, half-finished ideas? It will copy them with confidence. There is no "code that gets shit done" in an AI-assisted codebase. That trade is gone. Sharp, clean code only.

Dead code and dissonance kill agents. Stale code, commented-out blocks, API/doc mismatches. The model trusts what it reads. Dead paths send it wrong. Docs that don't match the code make it hallucinate. Delete dead code aggressively. Fix misleading comments. When code and docs disagree, the agent picks one and won't tell you. Clean the dissonance before you lose three sessions to debugging.

Small bloat ruins everything. You have tools. Use them.

TDD lets the agent self-correct

TDD gives the agent ways to check its own output. Without tests, you're the only feedback loop. Slow and error-prone.

Write tests first, or ask the agent to write them before the implementation. For stuff you can't automate, ask for a test plan: a step-by-step checklist. Then run through it. Hardware, physical UI flows, business logic against the real world. That's how you help it do things it can't do alone.

Give it ways to check itself. ESLint, type checks, unit tests, CI. Every automated check is a feedback loop that doesn't need you.

How I Work With Cursor

Append docs whenever available

Use @docs to attach library and API docs before asking the agent to use them. It reasons over the spec instead of guessing from training data, which can be outdated. Do it liberally. Fewer hallucinations, fewer wrong method signatures, fewer sessions debugging a call that was never right.

For UI: use the in-app browser

Cursor's in-app browser lets the agent navigate, snapshot, and interact with your live app. You don't describe layout or paste screenshots. @ the components or take a snapshot. The agent sees what you see. You point at the problem instead of describing it.

Use @-mentions strategically

Context is the main input. Cursor's @-mentions control what the agent sees.

  • @codebase — Project-wide context when it needs structure or related code.
  • @docs — Official docs for libraries and APIs.
  • @web — Live lookups, recent API changes, outdated docs.
  • @files — Specific paths when scope is narrow.
  • @git — Commit history and recent changes.
  • @terminal — Last terminal output. Paste errors into context instead of describing them.

For standing context (PRDs, architecture notes, coding standards), use Cursor Rules or Memories so the agent sees them without re-pasting. Notepads were deprecated; Rules and Memories replaced them.

Plan mode for complex work

For any task that touches multiple files or needs decisions, start in Plan mode. The agent decomposes the work, surfaces ambiguities, and asks clarifying questions before writing. Answer fully. Output quality scales with how much you resolve upfront. Five minutes in Plan mode saves an hour of back-and-forth.

MCP / Tools

MCP servers extend what the agent can do: APIs, databases, browsers, file systems. If a task needs something the editor can't do natively, there's probably an MCP server for it already.

Keep relevant tabs open

The agent sees your open editors. Open related files when working on a feature. They enter context without explicit @-mentions. Low effort, high signal.

Skills

Skills are packaged knowledge for specific tasks. They tell the agent how to approach work, not just what to do. Use existing ones. Build your own for anything you do more than twice. The agent will stop producing output that could belong to anyone and start producing output that fits how you actually work.

Cursor Rules

Models are good enough that rules matter less, but codebase-specific stuff still needs them. i18n, naming, file structure, import ordering. Anything the model won't infer from the codebase. Keep rules narrow.

Automate pipelines

Give code ways to check itself. ESLint, CI, type checks, test runners. The more you automate, the less time you spend on correctness. Set up CI that blocks on failures. Automation compounds.

Review changelists

Cursor groups edits into changelists. Scan them before accepting. The agent can be wrong. It can change stuff you didn't ask for, delete what you wanted, or introduce bugs in files it didn't need to touch. Tests and linters catch some. Your review catches the rest. You're the final gate.

Some odds and ends

Model selection: Gemini for UI and design. Codex for core code generation. Opus for end-to-end execution when the agent needs to make decisions. Re-evaluate as models change — this will keep shifting.

Write clearly. The agent parses prompts literally. "Make the button better" is bad. "Change the label to 'Save draft' and disable it while the form is submitting" is good. Precision in language produces precision in output.

Get full context before you start. When I onboard to a new domain, I run /genesis (or something like it) so I understand the problem space. The agent knows the tech. It doesn't know that I don't know the domain. A domain primer covers jargon, regulations, ecosystem. Then I can communicate without misalignment. Health tech, fintech, legal — anything with its own language.

Use widely adopted tech. AI was trained on public data. React, TypeScript, Python, Go: strong. Niche stacks: weaker. Pick what the model has seen when you can.

Your way is usually not optimal. That's fine. No one's is. The agent converges on patterns from a bigger sample than any individual. Let it propose before you prescribe. Evaluate on merit, not familiarity.

Wrap

You architect. The agent programs. Provide context, keep the codebase clean, use Cursor's features. If you're not shipping way faster than before, something in this workflow is broken. Find it. The velocity is real. Use it.