Get featured

Vibe coding for beginners: build your first app safely

Guide · checked against the docs on

You can describe an app in plain English and have an AI tool write it. That part is real. What tutorials skip is everything around it: where your work is saved, what happens to the password you pasted into the chat, and how you'd know if the app is quietly wrong. This guide walks through a first project with those habits built in from the start.

Not affiliated with or endorsed by any of the tools or companies mentioned. Tools change quickly, so check their own docs.

What "vibe coding" means

The term comes from Andrej Karpathy, who posted on X on February 2, 2025: "There's a new kind of coding I call 'vibe coding', where you fully give in to the vibes, embrace exponentials, and forget that the code even exists." In the same post he described accepting every change without reading the diffs, and said it was "not too bad for throwaway weekend projects".

That last part matters. In its original sense, vibe coding meant not reading the code, and he pitched it for throwaway projects. Today people use the term more loosely, for any app built mostly by prompting an AI. Either way, a first app is a good time for it, as long as you add a few safety nets. That's what the rest of this guide is about.

Pick a tool

There are two broad kinds of tool for this:

Either kind works for the project below. If you pick an app builder, check whether you can export or download the code, and where it's stored.

A safe first project: a habit tracker

Build something that's useful to you and can't hurt anyone if it breaks. A habit tracker fits: a page where you tick off today, and it shows your streak.

What makes it safe:

Start with a prompt like this:

Build a single-page habit tracker in plain HTML, CSS and JavaScript (no framework).
- One habit for now. A button marks today as done.
- Show the current streak: days in a row, ending today.
- Save to localStorage. No server, no login, no external services.
- Put the streak logic in its own function in streak.js so I can test it.
- Explain each file in two sentences.

Then work in small steps: one change per prompt, and check it works in the browser before asking for the next. "Add a second habit" is a good prompt. "Make it better" isn't, because you won't know what changed.

Review what the AI wrote

You don't need to understand every line. You do need to look. On each change, ask yourself:

AI tools can be confidently wrong, and a common beginner trap is accepting fixes until the error goes away without knowing why it went away.

Save your work with git

Git keeps a history of your project. The Git book describes each commit as a snapshot of all your files at that moment. So when an AI change breaks everything, you can go back.

The habit is simple: commit every time something works.

git init
git add .
git commit -m "Streak shows on the page"

Most AI editors can run these for you, and many app builders have a version history or export option. Then keep a second copy somewhere other than your computer, such as a private repository or another drive.

Keep secrets out

Sooner or later, a project needs an API key. Before that happens:

Test it

Clicking around isn't enough, because you'll only test what you expect. Ask the AI for small tests of the logic. Here's the streak function from our version of this project, and the tests for it:

// streak.js: counts how many days in a row ending today are marked done.
// days is a list of dates as 'YYYY-MM-DD' strings, in any order.
export function streak(days, today) {
  const done = new Set(days);
  let count = 0;
  const d = new Date(today + 'T00:00:00Z');
  while (done.has(d.toISOString().slice(0, 10))) {
    count += 1;
    d.setUTCDate(d.getUTCDate() - 1);
  }
  return count;
}
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { streak } from './streak.js';

test('no days means no streak', () => {
  assert.equal(streak([], '2026-10-15'), 0);
});

test('three days in a row ending today', () => {
  assert.equal(streak(['2026-10-13', '2026-10-14', '2026-10-15'], '2026-10-15'), 3);
});

test('a gap breaks the streak', () => {
  assert.equal(streak(['2026-10-12', '2026-10-14', '2026-10-15'], '2026-10-15'), 2);
});

test('today not done means 0, even if yesterday was', () => {
  assert.equal(streak(['2026-10-14'], '2026-10-15'), 0);
});

test('works across a month boundary', () => {
  assert.equal(streak(['2026-09-30', '2026-10-01'], '2026-10-01'), 2);
});

test('order and duplicates do not matter', () => {
  assert.equal(streak(['2026-10-15', '2026-10-14', '2026-10-15'], '2026-10-15'), 2);
});

They use Node's built-in test runner. With Node.js installed, run node --test in the folder. Ours printed pass 6, fail 0 on Node 22. The tests cover the cases people forget: a gap, today not done yet, the end of a month, and the same day saved twice.

When a test fails, paste the output to the AI and ask it to fix the code, not the test. Read the change to make sure it didn't just delete the test.

When to stop and learn

Vibe coding can get a small project working, but it has limits. It's time to slow down and learn the basics of what you're building when:

Learning doesn't mean stopping. Ask the AI to teach you instead of doing it for you: "walk me through how this streak function works, line by line".

Next step

Not affiliated with or endorsed by any of the tools or companies mentioned. Tools change quickly, so check their own docs.