Vibe Coding

Using an LLM to write a flash card app — no framework, no boilerplate, just raw code the model has no trouble reading.

The Idea

Frameworks exist because writing everything from scratch is tedious and error-prone. React, Vue, and their predecessors solved real problems: component reuse, state management, build pipelines. The cost is overhead — a layer of abstraction between you and the browser.

The bet with vibe coding is that this tradeoff has shifted. An LLM can generate framework-free code just as easily as it can generate framework code — and the result runs lighter with no build step. The question is whether the raw output is maintainable.

What Was Built

The target was a French flash card app: load a JSON file of word pairs, display one card at a time, flip on tap, swipe to advance. No dependencies. One HTML file, one CSS file, one JS file.

Runtime Vanilla JS — no framework, no bundler
Data cards.json fetched at load time
Interaction Tap to flip, swipe left to advance, keyboard support
Fallback Hardcoded card set if fetch fails

The Tradeoff

Without a framework, the LLM writes code that is compact and direct. A helper like parseCardObject ends up looking like this:

flashCards.js · parseCardObject
Object.keys(obj).forEach(k => {
  if (Array.isArray(obj[k]) && obj[k].length) {
    arr.push({q: String(k), a: String(obj[k][0])});
  } else {
    arr.push({q: String(k), a: String(obj[k])});
  }
});

This is dense. A human reading it cold needs a moment to parse the inline object construction and the array branch. In a framework project, a library or convention would abstract it away.

But that density is not a problem for the LLM. It wrote the code, it can read the code, and it can extend the code. The bottleneck of "hard to write from scratch" is gone when the model is doing the writing.

What This Demonstrates

See It In Action

View the flash card app →