What vibe coding is, and what it isn't, for a senior engineer
Short answer: vibe coding is building software by describing what you want in plain language and letting an AI agent write, run and fix the code, while you steer by results rather than by typing. The term comes from Andrej Karpathy (early 2025), who described "fully giving in to the vibes" and barely looking at the code. For a throwaway prototype that's fine. For anything real, the version that works keeps the speed and puts an engineer in charge of the parts AI is bad at: architecture, invariants, tests, security and deployment.
A real example: a small business site, and where the time really goes
Take a typical small-business request: a bicycle shop wants a website with a weekly camping schedule people can browse and a form to request a bike repair. Classic work would be a few weeks of scaffolding, forms, admin screens, styling and hosting.
With an agentic tool, most of that boilerplate is a conversation. You describe the pages, the data and the rules; the agent creates the project, writes the pages, runs the build, reads the errors and fixes them. Your time goes into the parts that need judgement: what the repair form must capture, how the schedule is edited, how the site is deployed and backed up.
That's the honest pitch: not "no engineering", but engineering time spent where it matters.
That example is not hypothetical. I built LifeBudget, a web and Android budgeting app I use every day, with vibe coding. It logs spending from bank SMS messages and tracks monthly and instalment credit separately. The agent wrote the code fast; deciding what to build was still my job.
What vibe coding is good at
- Boilerplate at scale. CRUD pages, forms, DTOs, mappings, migrations, configuration.
- Getting from zero to running. Project setup, wiring, first deploy, all the parts you know how to do but that take hours.
- Reading errors and iterating. An agent that can run
dotnet buildanddotnet testfixes most compile and test failures on its own. - Exploring unfamiliar code. "Where is the payment callback handled and what does it check?" is a great prompt.
Where it breaks
- Invariants it can't see. "Money is never a double", "a transfer always nets to zero", "seeded articles are drafts". Unless they're written down and tested, the AI will happily break them.
- Plausible but wrong. Code that compiles, reads well and is subtly incorrect: an off-by-one in pagination, a missing
await, a race in a balance update. - Security defaults. Missing authorization on one endpoint, user input in a raw SQL string, secrets in config files.
- Scope creep. Ask for one thing, get five refactors. Big diffs are where review stops working.
Guardrails that make it safe
- Write the brief down. A
CLAUDE.md(or similar) with the stack, the rules that must never break and the commands to build and test. The agent reads it in every session. - Encode invariants as tests. A rule in a test is enforced; a rule in a prompt is a suggestion.
- Small steps, small diffs. One feature or fix per change, reviewed before the next one starts.
- Read every diff. You are the reviewer. If you wouldn't approve it from a colleague, don't approve it from an AI.
- Real deploys, early. Deploy the first page, not the last. Deployment surprises are cheaper in week one.
Runnable code: an architecture guardrail
A test like this turns "money must never be floating-point" from a hope into a build failure, whoever (or whatever) writes the next property:
using System.Reflection;
namespace Shop.Tests;
public sealed class Order
{
public long TotalRials { get; set; }
public decimal DiscountRate { get; set; }
}
public class ArchitectureGuardrails
{
private static readonly string[] MoneyWords = ["Amount", "Price", "Balance", "Total", "Fee"];
/// <summary>
/// AI assistants reach for double when they see a number with a decimal point.
/// This test fails the build the moment money becomes floating-point anywhere in the domain.
/// </summary>
[Fact]
public void Money_is_never_a_floating_point_number()
{
var offenders = typeof(Order).Assembly.GetTypes()
.SelectMany(t => t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
.Where(p => p.PropertyType == typeof(double) || p.PropertyType == typeof(float))
.Where(p => MoneyWords.Any(word => p.Name.Contains(word, StringComparison.Ordinal)))
.Select(p => $"{p.DeclaringType!.Name}.{p.Name}")
.ToList();
Assert.Empty(offenders);
}
}
In a real project, point typeof(Order).Assembly at your domain assembly. The same pattern works for other rules: no controller without [Authorize], no DateTime.Now in domain code, no forbidden phrases in content. This site's own test suite uses one to block claims that must never appear in its articles.
Pros and cons
Pros
- Weeks of boilerplate become days; small projects become affordable.
- The engineer's time moves to decisions, reviews and the hard 10%.
- The agent's errors are visible and fixable when the feedback loop (build, test, run) is tight.
Cons
- Without guardrails, quality is whatever the model guessed.
- Review fatigue is real: large AI diffs get skimmed, and skimmed code ships bugs.
- You still need to understand the result well enough to debug it at 2 a.m.
The senior-engineer version
Let the AI type. Keep owning what it can't: the spec, the invariants, the tests, the security model and the deploy. That's vibe coding you can put in production.
Want an MVP built this way, with a senior engineer reviewing every line? See how I can help.
Frequently asked questions
Is vibe-coded software production quality?
It can be, but not by default. The AI writes plausible code fast; production quality comes from the parts you still own: a clear spec, tests that encode the rules, code review of every change, and a real deployment and rollback path.
Which tools are used for vibe coding?
Agentic coding tools that read and edit a whole repository and run commands, such as Claude Code in the terminal or Cursor in the editor, plus a chat model for planning. The tool matters less than the workflow around it.
Does vibe coding replace developers?
It replaces a lot of typing. It doesn't replace deciding what to build, knowing which failure modes matter, reviewing code critically, or owning production. Those become a larger share of the job.