DEV Community

Cover image for Vibe Coding One Pixel at a Time
raphiki for Technology at Worldline

Posted on

Vibe Coding One Pixel at a Time

Editing "stick figure" Yoga poses

In Part 1, we dipped our toes into "Vibe Coding" by building a Python script. It was linear, logical, and frankly, a bit safe. Text in, text out.

But let’s be real: backend scripts are the "easy mode" of LLM-assisted coding. The logic is contained. The state is ephemeral.

The real boss fight is the Frontend.

Can you "vibe" a UI? Can you talk a chaotic mess of DOM elements, event listeners, and CSS pixels into a functional application without losing your mind (or the AI losing the context)?

I decided to find out. My goal: Build Yoga Pose Builder, a browser-based tool to edit "stick figure" yoga poses, drag limbs around, and export vector SVGs.

I had no design, no stack picked out, and—crucially—I had never used a Canvas library in my life.

Here is how we vibed it into existence.


1. Context is King (The .md Anchors)

The biggest enemy of Vibe Coding is the LLM’s "Goldfish Memory." You’re 40 turns into a chat, you ask for a button change, and suddenly the AI forgets you’re building a yoga app and tries to sell you a subscription to a SaaS platform.

In Part 1, we just chatted. For a full UI application, that doesn't fly.

The Strategy: Documentation as Prompt Anchoring.

Before I let the AI write a single line of JavaScript, I made it write Markdown.
We created a Docs/ folder with two files:

  1. spec.md: The high-level architecture.
  2. features.md: A checklist of what we wanted to do.

I didn't write these because I love administrative work. I wrote them so that when the AI inevitably got confused, I didn't have to re-explain the project. I just said: "Read Docs/spec.md and try again."

Vibe Tip: Think of your documentation not as a manual for humans, but as "Long-Term Memory" for your AI pair programmer.

2. The Architecture: Letting the AI be CTO

I knew I needed a canvas where I could drag "joints" (knees, elbows) and have "bones" (lines) follow them.

Me: "I want to do this in the browser. Should I use React? Raw Canvas API?"
AI: "React might be overkill. Raw Canvas is painful. Use Fabric.js."

Me: "Never heard of it. Let's do it."

Fabric.js Logo

This is the beauty of Vibe Coding. I didn't spend 3 hours reading "Top 10 JS Canvas Libraries 2025" Medium articles. I trusted the vibe.

We settled on a Build-less Architecture:

  • Backend: Node.js + Express (just to serve files and save JSON).
  • Frontend: Vanilla JS + Fabric.js (loaded via CDN).
  • Build Tool: None. No Webpack, no Vite, no npm run eject nightmares.

Why? Because Vibe Coding thrives on speed. I wanted to change a line of code, hit F5, and see the result.

Application folder structure:

.
├── Docs
│   ├── features.md
│   └── spec.md
├── package.json
├── public
│   ├── index.html
│   └── poses
└── server.js
Enter fullscreen mode Exit fullscreen mode

3. The "Rig": Math is for Machines

Here is where I expected to get stuck. Creating a "rig" where moving a hand automatically updates the angle of the arm involves trigonometry and vector math.

Usually, this is where I’d open 15 StackOverflow tabs and copy-paste code I don't understand.

Instead, I just described the behavior:

"Create a Mannequin class. It has Nodes (circles) and Links (lines). When a Node moves, the Links connected to it should update their coordinates."

The AI wrote the entire class. It hooked into Fabric.js’s object:moving event and handled the coordinate updates. It worked on the first try.

Pose Builder Mannequin

I still barely know how fabric.Line works under the hood. And I don't care. It works.

4. Iteration: The "Yes, And..." Technique

UI Vibe Coding isn't about getting it right instantly; it's about sculpting.

The Ugly Phase:
The first version looked like a programmer made it (because a programmer did make it). The stick figure looked like a dead bug. The background was gray.

The "Vibe" Phase:
Me: "This looks depressing. Make it 'Zen'. Use soft colors, rounded buttons, and a clean layout."

The AI generated the CSS variables (--highlight-color: #88b04b), added a "Save As" modal, and cleaned up the toolbar.

Yoga Pose Builder GUI

The "Feature Creep" Phase:
Me: "I want to save my poses."
AI: "We have no database."
Me: "Just write JSON files to a folder on the server."

In 5 minutes, we had a fully working persistence layer. No database migrations, just fs.writeFile.

Here is a example of such a Pose JSON file:

{
  "meta": { "nameFR": "Demi-Pont", "nameSK": "Setu Bandhasana" },
  "joints": {
    "head": { "x": -120, "y": 100 }, "neck": { "x": -100, "y": 100 }, "chest": { "x": -60, "y": 50 }, "hips": { "x": 20, "y": 0 },
    "lShoulder": { "x": -80, "y": 100 }, "lElbow": { "x": -20, "y": 100 }, "lHand": { "x": 40, "y": 100 },
    "rShoulder": { "x": -80, "y": 100 }, "rElbow": { "x": -20, "y": 100 }, "rHand": { "x": 40, "y": 100 },
    "lHip": { "x": 20, "y": 0 }, "lKnee": { "x": 80, "y": 20 }, "lFoot": { "x": 80, "y": 100 },
    "rHip": { "x": 20, "y": 0 }, "rKnee": { "x": 80, "y": 20 }, "rFoot": { "x": 80, "y": 100 }
  }
}
Enter fullscreen mode Exit fullscreen mode

5. The Pivot: Language as a Feature

At the end of the session, I realized a problem: the app was vibing in French (my native tongue), but I wanted screenshots in English for this article.

Instead of manually editing labels, I asked the AI to "make the whole app i18n." In one single refactor, we added a translation dictionary, a language switcher, and logic to dynamically swap every label, tooltip, and even the pose names in the library.


GUI (and data) in French

This turned a linguistic hurdle into a core feature, proving that with Vibe Coding, "changing your mind" is just a prompt away.

6. The "Traceability" Hack

We spent about 90 minutes building this. We added features, fixed bugs, and refactored code. By the end, the chat context was massive and messy.

If I came back to this project in a week, I’d be lost.

So, I ran one final "Meta-Prompt":

"Read all the code we wrote and the docs in Docs/, and generate a Docs/session_summary.md. Explain what we built, why we made these choices, and the current state of the app."

The AI analyzed its own work and wrote a summary file. This is my "Save Game" point. When I want to work on this again, I’ll feed that summary to the AI to restore its context instantly.

Conclusion

We went from a blank folder to a functional, vector-based SVG editor with a backend in one session.

Vibe Coding a UI is possible, but you have to change your approach:

  1. Anchor the Context: Write specs so the AI has a "North Star."
  2. Delegate the Heavy Lifting: Let the AI choose the libraries and do the math.
  3. Iterate Visually: Don't try to prompt the perfect UI. Prompt the skeleton, then prompt the paint.

Next time, we'll try to Vibe Code a real full stack app. Or a game. Who knows? The prompt is the limit.


SVG exported by Yoga Pose Builder (opened in Inkscape)

Top comments (0)