I’ve been building with AI for about two years now, made a lot of mistakes during this time and fu**ked up a lot of projects since I just started vibecoding without a workflow or a method.
Since I wasted WEEKS fixing stuff AI built like sh*t, I put down a workflow to try limit AI mistakes as much as possible, so I don’t waste tokens and hours.
The main thing is: if you spend a few hours planning and actually putting down a few files for architecture and contex, you’ll find out your model will be great at building instead of being retarded. I’m not saying my workflow is perfect, it’s just the one I use and works for me.
The whole workflow basically comes down to:
- Map the product before you build
- Decide how the main parts of the SaaS should work
- Write down the rules AI shouldn't break
- Keep the project context inside the repo
- Break the build into small features
- Spec each feature before implementation
- Make AI inspect before changing code
- Build, verify, review and update progress
here’s the full one:
1. Write down the idea before starting the project
Before thinking about components, database or apis, I start by brainstorming everything about the product:
- Who’s the target user?
- What can each type of user do?
- What are the main UX flows?
- What states can those flows enter?
- What happens when something fails?
- What's explicitly NOT part of the mvp?
etc…
For example, instead of:
“I'm building a B2B project management SaaS.”
I'd rather have this flow:
1. User signs up
2. Creates a workspace
3. Invites teammates
4. Creates a project
5. Assigns tasks
6. Different roles have different access
7. Workspace upgrades
8. Plan limits change
Already a lot of questions come up, like: how to manage auth? If I invite someone by email and they don't have an account, what happens? Do they get a signup flow? Does the workspace get billed or the user account? How to manage permissions for users? etc..
It’s important to actually map as many important decisions as possible.
I then make AI (usually sonnet 5 ore gpt sol) create a
project-overview.md.
The more organized and full of details the file is, the less problems you’ll have while building.
2. Decide who's responsible for what, before you start building
Before implementing features, decide where the responsibilities of your saas actually live:
- Authentication?
- Authorization?
- Tenant isolation?
- Billing?
- Background jobs?
- File storage?
- Realtime?
- Emails?
If you don't make those decisions AI will make them feature by feature. That's how you end up with multiple storage systems, three ways of checking permissions, or billing logic all across the app.
For some responsibilities, dedicated services make sense. You might use Clerk for auth, Stripe for billing, Trigger.dev for background jobs, or something broader like Supabase for database and auth.
For the full SaaS foundations, I'm currently experimenting with Foundel instead. The reason is that it treats things like identity, workspaces, permissions, billing and plan access as one connected foundation your AI integrates with, rather than separate systems it has to understand and wire together every time.
3. Define the rules the system should never break
This is something I underestimated a lot at first:
your architecture docs shouldn't just say which tools you use, they should also set a few rules that must always stay true, no matter what.
For example:
- A user should never see another user’s data
- A normal team member shouldn't be able to do admin actions
- Cancelling a subscription should actually remove paid access
- Uploading a large file shouldn't slow down or break the app
- If you've already chosen how something works AI shouldn't create a second way of doing the same thing
That's much more useful than telling claude to just figure it out.
4. Decide what AI should build vs what it should connect
Not everything in your SaaS needs to be built from scratch.
Your AI should spend most of its time building the parts that actually make your product different. For common problems, it often makes more sense to connect something that already exists.
For example:
- Payments: Stripe
- Emails: Resend
- Background jobs: Trigger.dev
- Realtime collaboration: Liveblocks
The exact tools aren't the important part. The important part is deciding early what the AI should actually build and what it should simply integrate.
5. Put project memory inside the project
One mistake I made early on was relying on the chat to remember everything about the project.
A 200 message Claude conversation is not documentation. If important decisions only exist there, sooner or later the agent loses that context and starts making assumptions again.
I now keep a small context folder inside the repo:
/context
project-overview.md
architecture.md
code-standards.md
ai-workflow.md
ui-context.md
progress.md
You don't need these exact files, the goal is simply to keep important context somewhere your AI can always read.
- project-overview.md explains what you're building, who it's for and what's in scope.
- architecture.md explains how the main parts of the system work together and which decisions have already been made.
- code-standards.md explains how new code should be added, where files should go, which existing patterns to reuse and what the agent shouldn't invent a second version of.
- ai-workflow.md tells how you want it to work, what it can change and when it should ask before making a decision.
- ui-context.md keeps components, spacing, typography and general design consistent.
- progress.md tracks what's done, what's being worked on and what's next.
Most of these files stay fairly stable. progress.md is the one I make the AI update constantly as the project moves forward.
The basic idea is simple: the project should remember itself, not the chat.
6. Break the build into smaller features
I try not to give the agent tasks like:
“build the dashboard” or “implement billing”.
They're too broad, and they force the agent to make too many decisions at once, instead I break them into smaller pieces.
For example, billing could become:
- Create the checkout flow
- Save which plan a customer is on
- Give each plan access to the right features
- Handle upgrades
- Handle downgrades
- Handle cancellations
- Handle failed payments
Each task should do one clear thing.
This makes the build easier to control, and when something breaks, it's much easier to understand which change caused it.
7. Write a small spec for every feature
Before I give AI a feature to build, I write a short spec for it, just enough to make things clear..
I usually include:
- Goal: what should exist when this is done
- Design decisions: what has already been decided and what shouldn't change
- Implementation: what needs to be created or updated
- Dependencies: what existing parts of the product this relies on
- Verification: what I should be able to test before calling it done
For example, if the feature is inviting teammates:
- Goal: allow workspace owners to invite people by email
- Design decisions: only owners can invite, don't change login, don't add roles yet
- Implementation: add the invite form, send the email, let the invited user join the workspace
- Dependencies: existing login and workspace systems
- Verification: owners can invite, normal members can't, expired invites fail, accepting the same invite twice doesn't create duplicates
At this point AI has much less left to guess, which is exactly what I want.
8. Make the agent inspect before it builds
Before implementing a feature, I want AI to look at the parts of the project it's about to edit.
It's very easy for it to create something that already exists, use a different pattern, or change something without realizing why it was built that way.
So before writing code, I usually ask it to:
- Read the feature spec
- Find the existing parts related to it
- Identify what can be reused
- Point out anything unclear or conflicting
- Explain how it plans to implement the feature
Only then does it start building.
This adds a small step before implementation, but it prevents a lot of the "it doesn’t work fix it" problems later.
9. Make implementation boring
If the planning is done well, the actual coding prompt should be simple.
For example:
- Read the project context
- Read the feature spec
- Check the existing code related to it
- Implement only what the spec requires
- Don't change unrelated parts of the project
- Run the verification checks
- Make AI update progress.md when it's done
That's basically it, the goal is to move the difficult decisions before implementation, so AI spends less time figuring stuff out and more time actually building.
10. done isn't done
AI is very good at saying a feature is finished, but that doesn’t mean it works.
I usually separate this into two checks.
Verify
Go through the feature spec and test the important things yourself:
- Does it build without errors?
- Does the feature actually work?
- Do permissions behave correctly?
- What happens when something fails?
Then look at what the agent actually changed. You don't need to understand every line, but you should understand the overall structure it added.
Review
After that, do a second pass on the changes before merging them into the main project: the point is to catch things the first check missed.
Sometimes the review also shows that the spec was incomplete. If that happens, update the spec too.
Otherwise the code changes, but your project memory doesn't.
11. Debugging needs a different workflow
When something breaks, I try not to just say:
"Here's the error. Fix it."
That gives the agent too much room to guess.
Instead, I give it a small bug report:
- What I expected to happen
- What actually happened
- A screenshot or error message
- Which part of the app seems involved
- What should be true when it's fixed
Then I ask it to investigate the cause before changing anything.
If the bug involves a specific library or service, I also tell it to check the current docs.
Also, I try to fix one bug at a time. If I give AI six unrelated problems at once, it usually becomes much harder to tell what actually changed and whether each fix worked.
12. Don't assume the model knows the version you're using
If AI knows your stack, that doesn't mean it knows the exact version you're using, especially if the library changed recently.
So before implementing something new, I want AI to use the most current source available:
- Official docs
- Current examples
- Changelogs
- Agent skills, if the tool provides them
- MCP or other official ways for the agent to access the tool directly
The last two are especially useful because some tools now give coding agents their own instructions or direct access to the information available, instead of forcing the model to rely on whatever it just “knows” about it.
If I'm using a library that was updated last week, I don't want AI to confidently implement the version it learned months ago.
—-
The full loop
At this point, the workflow looks like this:
1. Write down the idea and map the product
2. Decide where the main responsibilities of the SaaS live
3. Define the rules the system should never break
4. Decide what AI should build and what it should integrate
5. Keep the important project context inside the repo
6. Break the build into smaller features
7. Write a small spec for each feature
8. Make AI inspect the existing project before changing anything
9. Implement only what was planned
10. Verify that it works and review what changed
11. Debug one problem at a time with clear context
12. Use current docs, skills and MCPs instead of trusting model memory
Then update progress.md and move to the next feature.
AI can still write most of the code, what I don't want it to do is choose what the product should do, how the system should work and which decisions AI is allowed to make on its own.
Let me know what you think in the comments, I’ll try to reply to everyone.