I went to school for computer science back in the day when you could build a startup with PHP and HTML and have been working as a Product Manager for 17+ years. While I haven’t done a ton writing code, as a PM you kinda have to know at least a little about everything; architecture, security, usability UI/UX, testing, analytics etc. I started “vibe coding” as a sort of mandate at my job for several work related projects early on, about 2021/22, back when GitHub released the “tab-complete entire functions”, and then moved to copy/paste from LLMs. So, vibe coding was sorta my job to not necessarily build faster but to learn through prototyping.

I have seen how LLMs have evolved and I have adapted my workflow over the years to build efficiently, have a better understanding for what has been built and how to identify pitfalls and traps. I thought sharing my workflow and what has worked for me may help others to not only better understand what you are building, but save a shit load of tokens in the process. Eventually LLMs and other AI services will solve most of the friction and manual processes needed to build an app or SaaS but for now, they just aren’t there yet.

I build a lot and have never gone over my $20 a month token limit, not even close.

The is by no means “the way” to do things but it works for me. I’m sure others have better, more efficient processes I would love to hear. And, this is not AI slop as you can tell by my terrible writing. 98% of this is my own with the exception of some of the prompt examples.

Market research: Unless you’re building something for yourself or a small group of people, please for the love of jeebus do at least some market research.

It amazes me the vibe coded apps I see that clearly did absolutely zero market research. And, market research isn’t asking on r/vibecoding, “would you use this?.”

Validate the problem actually exists before planning and building. LLMs, good ol’ interwebs search, forums, talk to potential users/customers and your human brain are the best tools at this stage.

At minimum, you should try to answer:

  • Who has this problem?
  • How often do they have it?
  • How painful is it?
  • What are they doing today instead?
  • Are they already paying for a solution?
  • What sucks about the existing solutions?
  • Is this a real problem or just a cool idea? <- Probably the most important question to answer.

Use AI to help you research, but don’t outsource your judgment. Ask an LLM to identify competitors, summarize reviews, find common complaints, generate customer interview questions, and map potential user segments. But then read the actual source material yourself. LLMs are good at summarizing. They are not a replacement for giving a shit.

Define the problem and scope: Before you build, write down what you are actually building. This sounds simple but I’m willing to bet 80% of apps go from idea to start building and then iterate as they build. This is where most of your tokens are going to waste. Something as simple as:

I am building a simple feedback tracker for solo founders and product builders so they can collect, categorize, and review user feedback without using a spreadsheet.

That one sentence tells you who it’s for, what it does, and what it is replacing.

You should also define what is not included to avoid going from a simple web-app to suddenly needing authentication, billing, admin roles, team workspaces, file uploads, AI summaries, Slack integration, a Chrome extension, and a mobile app. Congrats, you now have six unfinished products instead of one working product. Write an out of scope list.

Plan before you build: One of the biggest traps I have seen people make is going straight from idea to building and then iterating on the idea as they build. The result is a bunch of layered and messy code under-the-hood that inevitably ends up with a much of bugs that become like a game of whack-a-mole as you try to fix things. Again this is where most of your tokens are going to waste. Map out your idea end-to-end and think about each step, process, UI element etc.

Ask yourself:

  • What does the user need to do?
  • What screens are required?
  • What information needs to be stored?
  • What happens after the user submits something?
  • What happens when something fails?
  • What does the empty state look like?
  • What does success look like?
  • What should be cut from the first version?

LLMs are a huge help for brainstorming, asking questions and helping map things out.

Good planning prompts look like:

I want to build [app idea]. Help me define the MVP, user flow, data model, backend requirements, and what should be out of scope for v1.

Review this app idea like a senior product manager and senior engineer. Identify hidden complexity, technical risks, and scope creep.

Before I build this, ask me the questions a developer would need answered.

Tools I use at the planning stage:

  • Pen and paper/whiteboard: Seriously, I often start with just drawing on paper user flows, UI etc… It may sound stupid to some but I’m not distracted with clicking around a UI, email, alerts and other stuff as I would on my computer.
  • Miro and Figma: Miro is good for workflow and UI and Figma is better for more refined UI and workflows. The free versions of both have been fine for me.
  • LLMs for research: Asking general questions, helping brainstorm ideas, architecture etc.

Map the user flow: Before you ask Cursor, Claude Code, ChatGPT, or whatever tool you use to build anything, map the user flow.

This should be simple. Something like:

  1. User lands on dashboard
  2. User clicks “Add feedback”
  3. User fills out feedback form
  4. User submits feedback
  5. App saves feedback
  6. User sees success message
  7. New feedback appears in the list
  8. User opens feedback detail
  9. User changes status
  10. App updates the record

This may sound basic but, this is where a lot of bugs start. If you don’t know the flow, AI will invent one or worse, three different flows in three different files and now you are debugging nonsense.

For each major flow, ask:

  • What screen does the user start on?
  • What action do they take?
  • What data is required?
  • What happens after the action?
  • What can go wrong?
  • What should the user see if it goes wrong?
  • What should happen if there is no data?

Identify your empty states, loading states, and error states. Most vibe coded apps look ok in the happy path demo and then explode when the API is slow, data is missing, or the user does something unexpected.

Design the data model: It’s tempting to jump straight into the UI because it feels more tangible. Buttons, cards, dashboards, gradients, animations, all the fun stuff. But the data model is the skeleton of your app. If your data model is bad, everything built on top of it gets weird.

You don’t need to be a chief architect but you should write down the main “things” your app needs to store. Things like users, tasks, messages, posts, orders, settings.

Field names, data types, required vs optional all matter. This is where frontend/backend mismatches happen all the time.

A classic vibe coded app without this:

Frontend sends:

{
  "name": "Example"
}

Backend expects:

{
  "title": "Example"
}

Database stores:

item_name

Now your app is broken and when you ask to “Fix the problem and make not mistakes” AI gets confused and ends up introducing 12 more bugs and over complicating the code.

Analytics: This is almost always overlooked. Once you launch your app you’ll want to know what and how users actually use the app. It’s easiest to implement some off-the-shelf analytics tools like Google Analytics, Plausible, PostHog, or something similar.

Don’t track everything because you can! Track the things that tell you whether the app is working and expand from there. Analytics should connect back to your product questions.

Determine your technical architecture: Determine what technical tools and services you need to support your app/service.

Do you need a backend/server? What kind of frontend do you want to use? Do you need a database? Do users need to log in? Are you storing user data? Do you need file uploads? Do you need payments? Do you need email? Do you need an AI API? Do you need background jobs?

If you’re not technical, ask LLMs but don’t just ask, “What stack should I use?” You’ll get generic startup slop.

Ask something more specific like:

I am building an app where users can [do some thing/main actions]. I am a beginner/intermediate vibe coder. Recommend a simple technical architecture and explain the tradeoffs.

For many simple apps, you do not need a complicated architecture.

A simple stack is something like:

  • Frontend framework (e.g. React, Vue, Next.js)
  • Backend/API layer
  • Database
  • Authentication provider, if needed
  • Hosting provider
  • Analytics
  • Error tracking

Start simple but with the right services/tools. Don’t start with microservices, queues, Kubernetes, three databases, and an event bus because an AI gave you a “scalable architecture.” Most MVPs die long before they need any of that.

Security and privacy basics: You do not need to become a security engineer but you do need to understand the basics.

At minimum:

  • Do not commit API keys to GitHub - Sounds obvious but…
  • Use environment variables for secrets
  • Validate user input on the backend
  • Do not trust the frontend
  • Do not expose private database credentials
  • Do not store sensitive data unless you actually need it
  • Do not send private user data to random third-party APIs without thinking
  • Add authentication if users have private data
  • Add authorization if users should only see their own data

And probably one of the most common mistakes is assuming authentication and authorization are the same thing. They are not.

  • Authentication answers “who are you?”
  • Authorization answers “what are you allowed to access?”

A very common mistake is building login and then assuming the app is secure. But just because a user is logged in does not mean they should be able to access every record in your database. If your API route returns data without checking ownership, you will have cerated a potential shit storm of serious problems.

Building the backend: Most projects focus on the frontend first but the frontend is usually the easy part. The backend is often overlooked and is the most critical aspect of a sustainable and scalable build, IMO. This is another area that gives many non-technical vibe coders a huge headache and where I see the most bugs in other projects. Again, it comes down to planning. If you don’t know what an API is you should at least learn the basics. There are plenty of YouTube API explainer videos out there.

You don’t need to become a backend engineer, but you should understand the basic flow:

  1. Frontend makes a request
  2. Backend receives the request
  3. Backend validates the request
  4. Backend talks to the database or service
  5. Backend returns a response
  6. Frontend updates the UI

Build the backend in small chunks. Do not ask the AI to build the entire backend, database, API, validation, auth, and AI integration in one mega-prompt. That is how you get a pile of code you do not understand. In fact, building in small chunks should always be the way.

Start with one endpoint or a small group of related endpoints. Get it working. Test it. Then add the next one.

For each endpoint, know:

  • What does it do?
  • What input does it expect?
  • What does it return?
  • What errors can it throw?
  • How can I test it without the frontend?

Testing without a frontend is honestly the most productive way to learn about APIs. You should be able to test backend endpoints directly using curl, Postman, Insomnia, Thunder Client, or whatever tool. If your backend only works when clicked through the UI, debugging becomes much harder.

Also, add basic logging. Not 900 random console logs everywhere, but useful logs around important actions and failures. When something breaks, you want to know where it broke.

Building the frontend:
Again, this is where most vibe coders jump to because it’s the shiny thing. But by doing all of the other stuff before this you know what data is available to the UI, how to get it, what is missing as you build the front end and how to add missing features with focused prompts (e.g. “Update [some endpoint] to include [some data]…”)

Start boring. Start building a front end that is boring but supports your functionality, user flow, displays the data/info required etc. If you planned your app well you already have this outlined ready to go so it should be relatively easy. This avoids debugging gradients, animations AND debugging backend/API and all the hard stuff to debug.

Here is my basic frontend build order:

  1. Create the basic page layout
  2. Add the main form or primary actions
  3. Connect it to the backend
  4. Show loading, success, and error states
  5. Display saved or returned data
  6. Add edit/update behavior
  7. Add search, filters, or secondary actions
  8. Clean up the UI
  9. Add polish

Error handling: Most vibe coded apps work when everything goes right. Real apps need to handle when things go wrong. You do not need to handle every possible edge case in v1, but you should handle the obvious ones like…

  • Show loading states
  • Show user-friendly error messages
  • Validate forms before submission
  • Validate again on the backend
  • Return useful API errors
  • Log server-side failures
  • Avoid silently failing - This is probably the worst one. User clicks a button, nothing happens, they have no idea whether they did something wrong or your app broke.

Testing: Testing does not have to mean writing a giant automated test suite before you have a working app. But you do need to test intentionally.

At a minimum, go through your entire app and not just the happy path. In general, users are dumb or they do things that you don’t expect. Enter the wrong or no data into a text field, test on mobile and desktop, test on a slow network or no network.

Ask AI to build you a manual testing script and actually use it. Something like:

Create a manual QA test plan for this app. Include happy paths, edge cases, validation tests, mobile tests, and backend API tests.

AI prompting while building: The most efficient way I’ve found is to prompt in small, testable steps. Each prompt implement incrementally and should have a testable output.

Bad prompt:

Add [some feature].

Good prompt:

Implement [specific feature] using the existing project structure. Only modify the files required for this change. Explain what changed, what assumptions you made, and what I should test.

Better prompt:

Implement a new feature in this application that allows users to create, view, update, and delete a generic item. Before making changes, review the existing project structure, coding patterns, component conventions, API patterns, validation approach, and styling system. Follow the existing architecture instead of introducing a new pattern unless absolutely necessary.

Feature requirements:

  1. Add the ability to create a new item with the following fields:
  • title: required, string, minimum 3 characters
    • description: optional, string
    • status: required, one of: “New”, “In Progress”, “Completed”
    • createdAt: automatically generated
    • updatedAt: automatically updated
  1. Add a list view that displays all items. Each item should show:
  • title
  • status
  • created date
  • a short description preview, if available
  1. Add a detail/edit view or inline editing behavior that allows the user to:
  • update the title
  • update the description
  • update the status
  • delete the item
  1. Add proper loading, empty, success, and error states. Do not silently fail. If an action fails, show a clear user-facing message and log the technical error where appropriate.
  2. Add backend/API support if needed. The frontend and backend should use a consistent data shape. Do not use different field names for the same concept across the UI, API, and database.
  3. Validate data on both the frontend and backend. Frontend validation is for user experience. Backend validation is for actual safety and correctness.
  4. Keep the implementation simple. Do not add authentication, permissions, payments, notifications, AI features, file uploads, or unrelated functionality unless the existing app already requires it for this feature.
  5. Do not rewrite unrelated files. Only modify the files required to implement this feature. If you believe a larger refactor is necessary, explain why before making the change.
  6. After implementation, provide:
  • a summary of what changed
    • a list of files modified
    • any assumptions made
    • steps to manually test the feature
    • any known limitations or follow-up improvements

Manual test cases to support: User can create a valid item

  • User cannot create an item with an empty title
  • User cannot create an item with a title shorter than 3 characters
  • User can see the new item in the list
  • User can update an existing item
  • User can delete an item
  • Empty state appears when there are no items
  • Loading state appears while data is being fetched
  • Error state appears if the API or save action fails
  • Page still works after refresh
  • Feature works on both desktop and mobile layouts

All of this may sound a bit overkill considering in theory, AI can one-shot an app. I’m sure I missed some specifics but, if you want to build a sustainable app that you at least know a little about how it works, this is at least a starting point.

I would love to hear what works for others as well.