Build Software. Build Users

December 27, 2025

Vibe coding has enabled us to build software incredibly quickly, but it’s also raised the question of software quality to new heights. What does it mean for software to be high quality? Does it mean writing unit/integration/e2e tests for all possible code execution branches? Measuring code coverage? Having a comprehensive suite of test cases? And how do we even measure test comprehensiveness? Should we focus on happy paths or negative checks? Performance and stress testing? Accessibility? Running every possible test on each pull request? Security testing? Usability? The list goes on.

That’s a lot of testing types. But even if we write all of them, does that guarantee quality software? Practice shows the answer is no. There’s a meme that illustrates this perfectly:

A QA engineer walks into a bar and orders a beer. She orders 2 beers, 0 beers, -1 beers. The first customer comes in an orders a beer. They finish their drink, and then ask where the bathroom is.

The bar explodes.

The beer ordering module was spotless—it could handle every possible way to order a beer. And yet the bar exploded.

Why did the bar explode?

The problem was that the engineers who built the bar hadn’t put themselves in their users’ shoes. They didn’t realize that people who order and drink beers in a bar typically need to use the bathroom after a couple of pints. They could have known this if they’d studied their target users more deeply. We can’t know every aspect of our users’ lives. But now we have LLMs—trained on essentially the entire internet. LLMs likely have a much better understanding of what our users need and want. So why not vibe code the users themselves?

Vibe coding users

The idea is simple: choose your target users and understand them inside and out. You could create a folder structure like this:

/users
  /group1
    user.md
    /happy-paths
        requirement.flow.md

In this example, group1 represents a group of users who interact with our software. user.md contains the user profile—a description of who they are and what they do throughout their day, with our software being just one step in their life. happy-paths is a folder containing files that describe user flows through our software. These happy paths can be built the same way as agent skills—using natural language, pseudocode, or actual code, depending on how precise the flow needs to be.

Workflow

The process is iterative:

Vibe code users → Vibe code software
      ^                    |
      |                    |               
      |____________________|

Step by step, you get closer to truly understanding your users while making your software simpler for them.

Simplicity is the ultimate sophistication

Quality software, in my view, looks simple to its users. But achieving that simplicity requires deep understanding—the user’s workflows, capabilities, background knowledge, essentially everything about them and how our software fits into their lives. We can run users as sub-agents that perform happy paths through our software and provide feedback. If we understand our target audience well enough to simulate their behavior using an agent (general-purpose agents like Claude Code, Open Code, Cline, or Copilot) with good accuracy, we unlock almost infinite potential to simplify our software and increase its quality. We can automate this process—having an agent vibe code the application while consulting with simulated users. In this paradigm, the human developer becomes just another user telling the agent what to build.

How is it different from personas and user stories?

This approach is quite similar to traditional personas and user stories. The key difference is that we vibe code the personas just like we vibe code the software— we start with the personas and user stories first. Building the software comes second. The personas and their stories become LLM agents that actually use your software—clicking buttons, reading information, and fulfilling their needs just like real users would.

How is it different from testing?

This approach resembles current software testing practices, but with a crucial difference: the starting point. Typically, we vibe-code software first, then test it, trying to cover already-developed features with functional and non-functional tests. Test-driven development exists, but it faces fundamental questions: What tests should we write? How do we know if tests/requirements are sensible and actually validate/represent what the software should do? And what should the software do in the first place? In practice, TDD works well at the unit level, where the “user” of a function (usually another function) is well understood. But at the e2e level, everything becomes harder because we’re now dealing with actual human users—and we rarely understand them well enough.

Conclusion

The key is to understand users first. Build an agent that represents your software’s user before you build the software itself. Then iterate: create an agentic user, build software, let users (both real and agentic) interact with it, refine the agentic user, improve the software, and repeat. This is how we achieve truly quality software—software that’s simple in the eyes of those who actually use it.

Tags:
ideas

More posts

Nov 11, 2025
Nov 11, 2025
Nov 11, 2025