Plan First, Glue Second: A Three-Step Method That Stops AI from Writing Spaghetti Code
I Finally Found the Right Way to Write Code with AI: From 'Shit Mountain' to 'Glue' — What a ToDo List Taught Me
🎯 After reading this, you'll be able to make AI write clear, maintainable, and non-hallucinatory code. Pure practical advice, with a complete hands-on review.
Have you ever experienced a moment like this—
You confidently tell AI: "Help me write a React to-do list." Ten seconds later, a large chunk of code is spit out, complete with components, styles, and event handling. But when you look closely: title and content are used interchangeably, local storage and remote APIs are all crammed together, and it even "thoughtfully" wrote you a drag-and-drop sorting feature—hand-coded using onMouseDown and getBoundingClientRect. When you run it, it either throws errors or behaves bizarrely. You want to add a filtering feature, but find the code has been twisted into a pretzel, impossible to modify.
This is the classic double whammy of "hallucination code + shit mountain code."
I used to do this too, until I came across the Vibe Coding CN guide. It didn't teach me a new language, but it taught me a methodology for collaborating with AI to write reliable code. Strictly speaking, it's not "how to write code," but "how to direct AI to work like a reliable colleague."
Using this method, starting with a small ToDo List project, I completely reshaped my experience of programming with AI. Today, I'll break down this methodology, integrated with my hands-on experience, and explain it thoroughly.
1. Don't Treat AI as a Code Generator; It's Your First-Day Colleague
Many tutorials say "the era of natural language programming has arrived." That's true, but the easiest trap to fall into is treating it like a magic wand that obeys your every command.
Imagine this: You start a new company and hire a programmer on their first day. You neither show them the company's coding standards nor tell them what tech stack to use, and immediately say, "Write me a complete backend management system." They will inevitably scratch their head and then write code based on memories from their previous company—ultimately delivering something completely different from what you imagined.
AI is this new colleague. The more casually you use it, the more casually it writes.
The guide proposes an important operational concept: Treat tools like Claude Code and Cursor as your pair-programming colleague, not a code generator. Since it's a colleague, you need to:
- Show it the "employee handbook" (tech stack, standards, boundaries)
- Assign clear tasks (Lego-like modules)
- Define unified terminology (field names cannot be made up on its own)
More crucially—you must make this information effective in every conversation. Many tools support /init or memory modules, allowing you to fix the project plan as a system prompt. This way, every subsequent prompt automatically carries the global constraints, and AI will never go off track again.
This is the first cornerstone of the three-step method that follows.
2. The Three-Step Method: Say Goodbye to Hallucinations and Shit Mountains Forever
The entire Vibe Coding collaboration process, as I've refined it, consists of three interlocking steps. I applied them fully to the ToDo List project, and each step is concrete and substantial.
Step 1: Planning is Everything—First, Force AI to Write the "Employee Handbook"
Don't ask AI to write code right away. You must force it into a "plan only, no code" state, first clarifying what needs to be done, how to do it, and what not to do.
This is the first prompt I gave Claude Code (note its structure):
Help me write a React to-do list page that supports adding and deleting tasks.
Plan first, then code.
Phase 1: Only plan, output no code.
1. Confirm tech stack: React 19 + TailwindCSS + useState
2. Define feature boundaries
- Add to-do, delete to-do, toggle completion status
- No local persistence, filtering, or drag-and-drop functionality
3. Split modules (Lego components)
Input box component, to-do item component, list container component
4. Define data flow
useState stores task array, data structure:
{ id, text, completed }
5. Output this complete plan, wait for my confirmation, then implement the code in segments.
You can understand this prompt as an outline for an "employee handbook." Behind it are four anti-hallucination designs:
- Define boundaries: Explicitly stating "no persistence, no filtering, no drag-and-drop" prevents AI from arbitrarily gifting features, stopping code from infinite expansion.
- Enforce module splitting: Input box, item, list container—three components, each with its own responsibility. Later, reading code or adding features will be like flipping through a book, not opening a mystery box.
- Predefine data structure: Fields must be named
id,text,completed, nottitleorcontentimagined by the AI. This eliminates field-level hallucinations at the root. - Generate-Review-Update loop: This plan is not a one-off. Every time requirements change, you must first update the plan, then let AI execute. It is the constitution for your project's entire lifecycle.
When AI outputs the plan, you must review it as carefully as a product manager reviewing a PRD: Are the boundaries clear? Are the modules reasonable? Are the fields accurate? Only after everything is confirmed, let it write code segment by segment. Beginners love to skip this step and look at the code directly, but it is precisely this step that determines whether your project ends up a Lego castle or a condemned building.
Step 2: Glue Programming—Copy, Don't Write; Connect, Don't Build
After the basic functions were running, I wanted to add drag-and-drop sorting. If I still shouted like before, "Help me add drag-and-drop sorting," AI would very likely hand-code a set of coordinate listeners and sorting algorithms from scratch. Not only would the code volume explode, but bugs from various edge cases would drive you crazy.
The guide provides an incredibly vivid term: Glue Programming.
🧴 Glue itself doesn't create parts; it's only responsible for sticking existing parts together. You only write the adhesive code for connection, invocation, and flow, linking the various modules. Others have already built the wheels; you just be the glue.
In practice, it boils down to one sentence: Never develop underlying logic from scratch; prioritize mature, open-source components that have been long-validated by the community.
My instruction to AI became this:
Adhere to the glue programming principle: Never develop underlying logic from scratch; prioritize mature, open-source components long-validated by the community.
Current requirement: Add drag-and-drop sorting to the to-do list component.
1. Research first: Mature drag-and-drop libraries in the React ecosystem, prioritize react-beautiful-dnd (widely used in the industry).
2. Do not hand-write underlying drag-and-drop code; only do the gluing work.
3. Output order:
Install dependency command, connect the existing TodoList component with react-beautiful-dnd, only write the adapter and data flow glue code between modules.
Guess what? AI faithfully "researched" the usage of this library and then generated just a couple dozen lines of code: wrapping the list with DragDropContext, transforming each item with Droppable and Draggable, and writing an array reordering function inside onDragEnd.
All glue, not a single line of redundant coordinate calculation. Drag-and-drop went live smoothly, and the code was extremely concise; even coming back two weeks later, it was understandable at a glance.
The "glue" mindset goes far beyond drag-and-drop. For any feature—form validation, state management, routing, requests—always think first: "Is there a mature library I can glue together?" You direct AI to find those "Lego parts" that have been validated millions of times, then write the minimum amount of code to piece them together. The probability of hallucinations and shit mountains naturally drops exponentially.
Step 3: Meta-Counterargument—Let AI Help You Polish Your Prompts
By this point, you can already write clean projects. But there's an even more advanced play: Let AI self-evolve, continuously optimizing your collaboration method.
The guide introduces the concept of "Meta-Counterargument," which sounds a bit academic. In plain terms:
- α Prompt (Alpha): The specification you write, telling AI how to work.
- Ω Prompt (Omega): AI's evaluation and scoring of the α prompt based on the generated results, proposing improvement suggestions, forming a self-evolving closed loop.
How to use it specifically? Every time AI completes a feature, you can add a line:
"Please review my instructions above, analyze which expressions might cause ambiguity, which boundaries were not clearly stated, and provide an optimized prompt version."
AI will then transform into your personal teaching assistant, helping you discover ambiguous points you hadn't even noticed. For example, it might say: "You didn't specify the initial value of the array last time; this time, it's suggested to add initial state is an empty array." Or, "You asked to 'toggle completion status' but didn't specify the UI behavior; next time, you can describe it as 'add strikethrough and change opacity when clicking the text'."
You feed the improved α prompt, based on its suggestions, back to it, and the output quality spirals upward. It's like having a coach by your side specifically helping you improve communication efficiency; your every "prompt engineering" session is iteratively evolving.
You can even go a step further, summarizing these reviews into a "collaboration memo," pasting it into the project's planning document, making it a knowledge base for your team (you and AI).
3. ToDo List Full Practical Process Review: Running Through the Three-Step Method in One Project
Enough theory, let's see how I applied it end-to-end in a real project.
Phase 1: Create the Plan
I threw the previous "plan only, no code" prompt at Claude Code. It output a clear Markdown plan: React 19 + TailwindCSS, three components, { id, text, completed } data structure, no persistence, no drag-and-drop. I reviewed it item by item, confirming the boundary of "no filtering" was reasonable and the field name didn't use title.
Phase 2: Segmented Construction, Reviewing Every Brick
I said: "Following the plan, write the TodoInput component first." After AI generated it, I checked that it was indeed a controlled component, pushing text into the array on onSubmit, with ID using Date.now(). No problem, then proceed to write TodoItem and TodoList. Each step was a small, fast run, preventing errors from piling up.
Phase 3: Glue Time, Adding Drag-and-Drop
After the basic functions ran, I gave the "glue principle" prompt. AI output pnpm install react-beautiful-dnd, then rewrote TodoList: wrapping with DragDropContext, the original map becoming draggable inside droppable, and writing two lines of splice + setTasks inside onDragEnd. Throughout the process, no clientX or clientY appeared. The drag-and-drop experience was smooth, and the code remained clean.
Phase 4: Review and Optimization—Let AI Find Fault with Itself
After all features were settled, I did one more step. This step seemed inconspicuous, but the actual effect was astonishing.
I told AI: "Look back at all the instructions I just gave you, find faults—where was I unclear? Where was it easy for you to go astray? Give me an improved version."
This is the so-called "Meta-Counterargument." In plain terms: Let AI review your words and help you improve your prompt.
AI quickly gave me feedback: "Your plan defined the id field, but didn't specify the generation rule. If you need editing functionality later, an unstable ID will cause bugs. Suggestion: Use nanoid for ID generation."
Just this one sentence made me instantly realize: Right, I previously used Date.now(), which could potentially duplicate if tasks are added rapidly in succession. Switching to nanoid would be stable. I immediately added it to the planning document. No matter how this project iterates in the future, the ID part won't be a pitfall.
Experience this process:
- I write instructions → AI executes
- AI looks back at my instructions → identifies ambiguities → I improve instructions
- Next time, using the improved instructions → higher quality generation
It's like bringing on a new colleague; after finishing the work, he tells you: "Boss, I actually didn't quite understand the third step you mentioned; I guessed. Next time, you could explain it this way, and I won't go off track." You find it reasonable and change your phrasing next time. After several iterations, your cooperation becomes increasingly tacit, to the point where you barely need to speak, and he knows what you want.
This is the core of "Meta-Counterargument"—it's not you unilaterally training AI, but AI, in turn, helping you become a better prompt author. Your collaboration forms a positive cycle, becoming smoother the more you use it.
After the entire project was completed, the code had not a single redundant state, not a single self-invented sorting algorithm. Even if I opened it a month later, I could immediately grasp the structure without panic.
4. Why Can This Method Cure "AI Code Phobia"?
By this point, you'll realize that the reason we were tormented by AI hallucinations and shit mountains in the past wasn't because AI wasn't powerful enough, but because our collaboration method with it was too crude.
Looking at these three steps together:
- Planning solves the ambiguity of "not knowing what to do," using hard boundaries to block feature creep.
- Glue solves the technical selection of "how to do it reliably," replacing fragile hand-coded parts with mature components.
- Meta-Counterargument continuously refines the communication language between you and AI, forming a positive flywheel.
More fundamentally, this is a switch from the "programmer + code generator" model to the "architect + collaboration partner" model. You are not writing a prompt; you are writing a living employee handbook for AI, then leading it through reviews and iterations.
This method is tech-stack agnostic. React, Vue, Python FastAPI, Flutter… in any scenario, you can first define boundaries, then find mature wheels, and finally polish instructions through review.
In Conclusion
Now, every time I open Claude Code, it doesn't feel like typing commands, but like conversing with a colleague very familiar with my project's architecture. He reminds me of boundaries, recommends the best parts, and helps me piece together what I want with the minimum amount of glue.
If you are also fed up with AI's fabrications and incomprehensible code, I strongly recommend you thoroughly read the original Vibe Coding CN text. All my practices originated from there.
Remember these few sentences, and post them at your workstation:
- Write the constitution first, then start work.
- Only be the glue, don't reinvent the wheel.
- Let AI review, getting stronger with use.
Now, don't you also want to write AI an "employee handbook" that includes a "test task"? 🚀
If this practical note helped you avoid a few pitfalls, feel free to like, bookmark, and forward it to partners who are also "battling wits" with AI. Your every "one-click triple" is my greatest motivation to continue digging for best practices and recording more real-world pitfall reviews. See you in the next article!