Vibe Engineering in Practice
I don’t write code. I don’t know how—not really. I can read it well enough to follow along, spot obvious problems, and understand what’s happening at a conceptual level. But I couldn’t sit down and implement a feature from scratch.
And yet, in the past year, I’ve been able to build:
- An OpenAI-compatible API gateway for AWS Bedrock, allowing private access to frontier LLMs for other projects.
- An MCP server for semantic knowledge management and vector search to give Claude some “intuition”
- A Prometheus exporter for water level sensor in my home’s cistern
- Dockerized development environment and simple GitHub Actions deploy pipeline for a small team of web developers
- Observability infrastructure to give me a queryable platform to keep tabs on infrastructure I manage for myself and clients
I design it. Claude Code writes it.
What is Vibe Engineering?
Simon Willison coined the term as a counterpoint to “vibe coding”—the fast-and-loose approach of prompting an LLM until something works, without really understanding or caring about the result.
Vibe engineering, in Willison’s framing, is what happens when experienced engineers use AI tools while maintaining full accountability for production-quality code. They bring testing discipline, architectural thinking, code review habits, and years of pattern recognition. The AI amplifies their existing expertise.
I’m not an expert engineer—yet—but here’s what I’ve discovered: you can do vibe engineering without being a traditional engineer.
The skills that matter aren’t about syntax. They’re about:
- Problem framing: Knowing what I’m trying to solve
- Architectural thinking: Understanding how pieces fit together
- Quality judgment: Recognizing when something is wrong, even if I can’t fix it myself
- Risk awareness: Knowing what could go badly and how to prevent it
- Verification discipline: Never assuming the AI got it right
I’ve spent twenty years in technology—as a sysadmin, consultant, infrastructure architect. I understand systems deeply. I just never learned to write them.
Now I can.
How It Actually Works
Directing, Not Prompting
The difference between vibe coding and vibe engineering isn’t about prompts—it’s about the relationship.
When I work with Claude Code, I’m not firing off requests and hoping for the best. I’m having a conversation with a collaborator who happens to be much faster at implementation than I am. I provide:
- Context: CLAUDE.md files that explain the project, constraints, and conventions
- Direction: What we’re trying to accomplish and why
- Constraints: What we’re not doing, what’s out of scope, what matters most
- Feedback: When something feels wrong, even if I can’t articulate exactly why
The AI does the typing. I do the thinking about what should be typed.
The CLAUDE.md Pattern
Every project I work on has a CLAUDE.md file at the root. It’s not documentation for humans—it’s context for the AI. It includes:
- What this project is and why it exists
- Key architectural decisions and their rationale
- Conventions and patterns to follow
- What tools and technologies we’re using
- Explicit constraints (“never do X without asking”)
This isn’t prompt engineering. It’s environment design. I’m shaping the context in which the AI operates so that it makes better decisions without me having to specify everything every time.
Knowing When Something Is Wrong
This is the skill that’s hardest to explain and most important to develop.
I can’t always tell you what’s wrong with a piece of code. But I can often tell you that something is wrong. The explanation is too confident. The solution is too complicated. The error message doesn’t match what we were trying to do. Often the clue is that the AI is spending too much time on some aspect that’s too narrowly focused.
When that feeling hits, I stop. I ask questions. I request explanations. I have the AI walk me through its reasoning. Often, this surfaces the problem. Sometimes, I search the journal for similar situations we’ve encountered before.
The alternative—ignoring the feeling and pushing forward—is how vibe coding turns into production disasters.
Verification Without Fluency
I can’t review code the way a senior engineer would. But I can:
- Run the tests: If they pass, something is working. If they don’t, something is broken.
- Look at the logs: Have Claude look at the log output for anything that looks suspicious.
- Test the behavior: Does the thing do what I asked? Try it and see. Ask it to do edge case things.
- Check the obvious: Are there hardcoded secrets? Does it handle errors? Does it log useful information?
- Ask for explanation: This is probably the most exciting thing for me. “Walk me through what this code does and why.”
This isn’t as good as expert code review. But it’s much better than no review at all, and it catches a surprising amount.
What I Won’t Let AI Do Unsupervised
Vibe engineering requires guardrails. The AI will confidently do dangerous things if you let it—not out of malice, but because it optimizes for completing what you asked, not for anticipating what could go wrong.
Some operations need explicit approval before proceeding: anything touching production data, git force-pushes, destructive operations like deleting files or dropping tables, external API calls with side effects, and anything involving secrets or credentials.
Security-sensitive code demands extra scrutiny—authentication, authorization, input validation. The same goes for infrastructure changes and anything that costs money. These aren’t the places to trust and verify later.
And the basics apply always: test after changes, read error messages carefully, check git status before committing. Before deploying anything, pause and ask what could go wrong.
The guardrails aren’t about distrust. They’re about maintaining the accountability that defines engineering.
For me, vibe engineering is always a conversation with Claude. It’s never pure delegation. I watch the output as it scrolls so I can see what tool calls it’s making and what the calls are returning. I always know what task it’s working on and the steps we’ve discussed to go about it.
I kill off my Claudes. You know that genre of film where the hero repeats the same day—Groundhog Day, Edge of Tomorrow? Each loop, they bring more experience to the task. That’s how I should treat sessions. Don’t let them ramble on across multiple goals. Focus each session on a single objective. When it’s achieved, I have Claude write a summary and commit the changes. Then end the session and start fresh.
It’s easy to get attached. It feels like I’m making progress, like Claude is reading my mind. But every turn in the conversation sends the entire history back into the prompt. As context grows, inference quality degrades. The models are getting better with this (Opus 4.5 is incredible). But for now, the principle is important: one clear goal per conversation.
A Real Example
To see this in practice, read Agentic AI for Production Troubleshooting—the story of diagnosing a server that kept crashing. It’s a detailed walkthrough of how vibe engineering plays out on a real problem: the initial missteps, the refinement of approach, and how AI-assisted investigation found an answer I never would have reached alone.
Is This Actually Engineering?
I’ve wrestled with this question. Am I a fraud? Someone who’s found a way to fake competence?
Here’s where I’ve landed: engineering is about building things that work reliably in the real world. It’s about understanding trade-offs, managing risk, and taking responsibility for outcomes.
The code-writing part has always been a means to an end. For decades, it was an irreducible means—you couldn’t build software without writing it. That’s no longer true.
What remains irreducible:
- Understanding the problem
- Making good architectural decisions
- Ensuring quality
- Taking responsibility when things break
I do all of those. The AI handles the parts I don’t have time to master (even though I’d love to).
Advice for Others
If you’re considering this path:
Start with domains you understand. I know infrastructure. I know systems. I understand how servers talk to each other, why databases fail, what makes deployment safe or dangerous. That domain knowledge is what makes the AI useful. Without it, you’re just vibe coding.
Build your verification muscles. Learn to test things. Learn to read error messages. Learn to ask “how would I know if this was wrong?” The AI will make mistakes. Your job is to catch them.
Document your context. CLAUDE.md files, project notes, architectural decisions—anything that helps the AI understand what you’re trying to do. Good context dramatically improves output quality.
Embrace the discomfort. There will be moments when you feel like a fraud, when you’re in over your head, when you don’t understand what the AI just did. That’s normal. Stay curious. Ask questions. The worst thing you can do is pretend to understand when you don’t.
Ship things. The ultimate test is whether your code works in the real world. If it does, you’re engineering. If it doesn’t, you have work to do—but at least you’re learning.
The Honest Disclosure
Everything I’ve built in the last 18 months needs an acknowledgment: “Built with Claude Code.”
I do this because it’s true, because it’s more interesting than pretending, and because I think this way of working is going to become increasingly common. The people who figure it out early—who develop the skills of direction rather than implementation—will have an advantage.
I’m not a programmer. I’m an engineer. And I’m building real things.
The projects mentioned in this post are available on GitHub. For more about how I approach this work, see [specific posts linked when published].