~/VibeHandbook
$39

Chapter 11 · 03

A Worked Example: A "Favorites" Feature

Let's build a small feature end to end: users can mark items in a list as favorites, and see a count of how many they've favorited.

Slicing it

Here's how I'd break it into vertical steps:

  1. Add a star button next to each item (does nothing yet, just shows up).
  2. Clicking the star toggles its on/off look (state only, not saved).
  3. Show a "★ 3 favorites" counter that reflects the toggles.
  4. Save favorites so they persist after a page reload.

Notice each step is independently runnable and visible. You could stop after any one of them and still have a working app.

Step 1: the button

A good names the file, the change, and what not to touch:

In the ItemCard component (src/components/ItemCard.jsx), add a star
button in the top-right corner of each card. It should render an
outline star icon. Don't wire up any click behavior yet — just make
it appear. Keep the rest of the card layout unchanged.

Run the app. Do you see stars? Good. :

git add -A && git commit -m "Add star button to item cards"

Step 2: toggle the state

Make the star button toggle between filled and outline when clicked.
Track this with local component state — don't save it anywhere yet.
A filled star means favorited.

Think of state as the app's short-term memory — what's true right now, like whether a particular star is currently filled. Now you're handling state and UI together, which is normal. (UI, or user interface, is just the part of the app a person sees and clicks.) The AI will probably add something like:

const [isFavorite, setIsFavorite] = useState(false);

<button onClick={() => setIsFavorite(!isFavorite)}>
  {isFavorite ? <StarFilled /> : <StarOutline />}
</button>

Click a few stars. They toggle? Commit.

Step 3: the counter

Add a "★ N favorites" counter at the top of the item list. It should
count how many items currently have their star filled. Lift the
favorite state up to the list component if you need to so the counter
can see it.

This step may require the AI to restructure where state lives — that's expected, and it's exactly why you do it as its own small step. Run it, toggle a few stars, watch the number change. Commit.

Step 4: make it persist

Persist favorites so they survive a page reload. Use localStorage for
now — save the list of favorited item IDs whenever it changes, and
load it on startup.

(localStorage is just a small notebook the browser keeps on the visitor's own computer, so the app can jot things down and find them again after a reload.) Reload the page. Still favorited? You just shipped a feature, one runnable slice at a time.

Here is how the finished feature's pieces talk to each other. A click flows down into state, the screen redraws from state, and state is mirrored to storage so it survives a reload:

     ┌─────────────────────────────────────────────┐
     │                                              │
   click star                                  redraws from
     │ (event)                                 state
     ▼                                              ▲
 ┌────────┐   updates    ┌─────────┐    feeds   ┌────────┐
 │   UI   │─────────────▶│  STATE  │───────────▶│   UI   │
 │(button)│              │(in app  │            │(filled │
 └────────┘              │ memory) │            │ star + │
                         └────┬────┘            │counter)│
                              │ save on change  └────────┘
                              ▼
                         ┌──────────┐
                         │ STORAGE  │  ◀── load on startup,
                         │(localSt.)│      so it survives reload
                         └──────────┘

Want it offline?

Get the PDF + EPUB + downloadable prompt library + version updates.

$ Get the PDF — $39