Build a Bookmark Manager with Claude Code

Use Claude Code's agentic workflow to build a bookmark manager app.

Introduction

30 Second Summary

We all have dozens of links we want to save for later. Browser bookmarks get messy fast, buried in folders you never open again.

In this project, you will build a personal bookmark manager web app entirely through natural-language prompts to Claude Code. You won't write a single line of code yourself.

What You'll Build

A fully functional bookmark manager that lets you save, categorize, search, and delete bookmarks, running locally in your browser with no server or framework required.

By the end of this project, you'll have:

  • A working bookmark manager web app built with plain HTML, CSS, and JavaScript.
  • A CLAUDE.md project memory file that teaches Claude Code your preferences and constraints.
  • A repeatable agentic coding workflow (plan, prompt, iterate, commit) you can apply to any future project.
  • Secret Mission: Add a dark mode toggle and import/export feature to back up your bookmarks as a JSON file.

Are there any prerequisites?

You need a Claude Pro, Max, Team, or Enterprise subscription. The free Claude.ai plan does not include Claude Code access.

Install Claude Code

Claude Code is a terminal-based AI assistant that lives in your command line. You talk to it in plain English, and it writes code, creates files, and manages your project for you.

In this step, you will install Claude Code on your Windows machine, log in with your account, and set up Git so Claude Code has access to its full toolkit.

In this step, get ready to:
  • Install Claude Code on Windows using PowerShell.
  • Authenticate with your Claude account.
  • Install Git for Windows for a better development experience.
Install Claude Code on Windows using PowerShell

Claude Code installs directly from Anthropic's servers using a single PowerShell command. You need Windows 10 version 1809 or later and at least 4 GB of RAM.

  • Press the Windows key to open your search bar.
  • Type PowerShell and press Enter to open it.
  • Install Claude Code by running this command:
irm https://claude.ai/install.ps1 | iex

What does this command do?

This command downloads the Claude Code installer script from Anthropic's servers and runs it immediately. It sets up the claude command so you can use it from any terminal window.

The native installation also handles automatic updates in the background, so you will always have the latest version.

  • Once the install finishes, verify it worked by running:
claude --version

✔️ I see a version number

Claude Code is installed and ready to go. You can move on to authentication.

ⓧ I see an error or nothing happened

If PowerShell shows an error about execution policies, try the following:

  • Close PowerShell.
  • Right-click the PowerShell icon and select Run as administrator.
  • Run the install command again:
irm https://claude.ai/install.ps1 | iex
  • After installation completes, close and reopen PowerShell, then run claude --version again.

If you still see an error, help me troubleshoot my Claude Code installation on Windows.

Authenticate Claude Code with your account

Claude Code needs to connect to your Anthropic account before you can use it. The first time you run it, a browser window opens for you to log in.

  • Start Claude Code by running:
claude

What happens when you run this?

Claude Code opens an interactive session and detects that you have not logged in yet. It displays a URL and opens your default browser to the Anthropic authentication page.

  • When your browser opens, sign in with the account that has your Claude Pro, Max, Team, or Enterprise subscription.
  • After signing in, return to your PowerShell window. Claude Code confirms you are authenticated and shows an interactive prompt.
  • Type exit and press Enter to close the session for now.

Authentication not working?

Make sure your account has an active Claude Pro, Max, Team, or Enterprise subscription. The free Claude.ai plan does not include Claude Code access.

If the browser does not open automatically, copy the URL shown in your terminal and paste it into your browser manually. Help me fix my Claude Code authentication issue.

Install Git for Windows

Git for Windows gives Claude Code access to the Bash tool, which provides a better development experience. Without it, Claude Code falls back to PowerShell as its shell tool.

  • Check if Git is already installed by running:
git --version

✔️ I see a version number

Git is already installed. You are all set for the next step.

ⓧ Command not recognized

Git is not installed yet. Install it using the Windows package manager by running:

winget install --id Git.Git -e --source winget

What does this command do?

This uses winget, the built-in Windows package manager, to download and install the official Git for Windows package. The installer runs in the background and adds git to your system PATH.

  • The installer may prompt you to accept license terms. Type Y and press Enter to accept.
  • Once the install finishes, close and reopen PowerShell so it picks up the new PATH.
  • Verify Git installed correctly by running:
git --version

You should see a version number like git version 2.54.0.windows.1 (your exact number may differ).

Still not recognized after installing?

Make sure you closed and reopened PowerShell after the install. The new PATH entry only applies to new terminal sessions.

If it still does not work, help me get Git working in my PowerShell after installing with winget.

Why install Git for Windows?

Claude Code's documentation recommends Git for Windows on native Windows installs. It gives Claude Code access to the Bash tool, which provides a Unix-like shell environment for running commands.

Without Git for Windows, Claude Code still works but uses PowerShell exclusively. For this project, having Git also lets Claude Code commit your code to version control directly through conversation.

Your development environment is ready. Next up, you will create your project folder and set up Claude Code's project memory so it knows exactly what you want to build.

Set Up Your Project

Your tools are installed and ready to go. Now it's time to create the project workspace where Claude Code will build your bookmark manager.

Every Claude Code project starts with a folder and a Git repository. You also need a CLAUDE.md file that tells Claude Code the rules of your project. Think of it as a briefing document that Claude reads at the start of every session.

In this step, get ready to:
  • Create a project folder and initialize a Git repository.
  • Launch Claude Code and explore its interface.
  • Create and customize a CLAUDE.md project memory file.
Create the project folder and initialize Git

Claude Code needs a dedicated folder for your project. It also needs a Git repository so it can track and commit the code it writes for you.

  • Return to your PowerShell window from the previous step.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir bookmark-manager
cd bookmark-manager
  • Initialize a Git repository inside this folder by running:
git init

What does git init do?

This command creates a hidden .git folder inside bookmark-manager that tracks all changes to your files. Claude Code uses Git to manage the code it writes and create commits on your behalf.

  • You should see a message confirming the repository was created, including the path to your new .git folder.

Don't see the initialization message?

Make sure you ran cd bookmark-manager before git init. You need to be inside the project folder. Run pwd to confirm your current location ends with bookmark-manager.

If you see a "git is not recognized" error, Git for Windows may not have been installed correctly in the previous step. Revisit the Git installation instructions.

Help me troubleshoot my Git init setup

Launch Claude Code and explore the interface

Now that your project folder is ready, you can start Claude Code inside it. Claude Code will use this folder as its working directory for all file operations.

  • Launch Claude Code by running:
claude

What should I see?

Claude Code opens an interactive session inside your terminal. You should see a welcome banner showing the model name and a prompt where you can type messages. This is where you will give Claude instructions in plain English.

  • Explore the available commands by typing this into the Claude Code prompt:
/help
  • You should see a list of slash commands including /init, /clear, /cost, and others. These are the commands you will use throughout this project.

Keep this session open

You will stay inside this Claude Code session for the rest of the step. Everything you type from here on goes into the Claude Code prompt, not the regular PowerShell prompt.

Create and customize your CLAUDE.md file

A CLAUDE.md file gives Claude persistent instructions about your project. Claude reads it at the start of every session, so it always knows your tech stack, coding conventions, and constraints.

  • Generate a starter CLAUDE.md file by typing this command in your Claude Code session:
/init

What does /init do?

The /init command analyzes your project and generates a starter CLAUDE.md file with build commands, conventions, and project structure. Since your folder is empty, the generated file will be minimal.

You will refine it with instructions Claude could not discover on its own.

  • Claude Code may ask follow-up questions about your project during the /init process. Answer them or approve Claude's suggestions to proceed.
  • Once the starter CLAUDE.md is created, customize it by typing this prompt into Claude Code:
Update CLAUDE.md with the following details: This is a personal bookmark manager web app using plain HTML, CSS, and JavaScript. The tech stack is plain HTML, CSS, JavaScript only - no frameworks, no build tools, no external dependencies. Use localStorage for data persistence. The app runs locally by opening index.html in a browser. For conventions: use kebab-case for file names, use semantic HTML elements, mobile-first responsive design, and CSS custom properties for theming.

What does this prompt do?

This tells Claude exactly what constraints to follow when building your app. Without these rules, Claude might reach for a framework like React or suggest running a build tool.

The CLAUDE.md keeps Claude on track every session.

  • Claude Code will ask for permission to edit the file. Approve the change.
  • Verify the file looks correct by typing:
Show me the contents of CLAUDE.md
  • Confirm that your CLAUDE.md includes the project name, tech stack constraints, and conventions listed above.

✔️ Awesome, I've got everything!

Great. Double check you see all the sections: a project title, tech stack rules, and conventions. Your CLAUDE.md is now ready to guide Claude Code through the rest of this project.

ⓧ I'd like to double check the full code

Here is what your CLAUDE.md should look like. If yours differs slightly in wording, that is fine as long as the key constraints are present. If it is missing sections, ask Claude to update it:

# Bookmark Manager

A personal bookmark manager web app using plain HTML, CSS, and JavaScript.

## Tech Stack
- Plain HTML, CSS, JavaScript only
- No frameworks, no build tools, no external dependencies
- localStorage for data persistence
- Runs locally by opening index.html in a browser

## Conventions
- kebab-case for file names
- Use semantic HTML elements
- Mobile-first responsive design
- CSS custom properties for theming

CLAUDE.md missing sections or looks different?

Since Claude Code generates responses dynamically, your file may not match the reference exactly. The important thing is that it includes the "no frameworks" constraint, the localStorage requirement, and the kebab-case convention.

If a section is missing, type a follow-up prompt like: "Add a Conventions section to CLAUDE.md with kebab-case for file names, semantic HTML elements, mobile-first responsive design, and CSS custom properties for theming."

Help me fix my CLAUDE.md file

Your project workspace is fully set up. You have a folder, a Git repository, and a memory file guiding Claude Code. Next up, you will use Plan Mode to design the bookmark manager before writing any code.

Plan Your Bookmark Manager

Your CLAUDE.md is set up, giving Claude Code persistent context about what you're building and how. Now it's time to design the actual features before any code gets written.

Jumping straight into code often produces scattered results. Claude Code works best when you plan first, then build. You'll use Plan Mode to have Claude think through the architecture and features without touching any files.

In this step, get ready to:
  • Enter Plan Mode and describe your bookmark manager features.
  • Review Claude's plan and provide feedback until you're satisfied.
Enter Plan Mode and describe your app

Plan Mode tells Claude to think and plan without creating or editing files. It's the "explore first, then plan, then code" workflow that separates effective Claude Code usage from trial-and-error prompting.

  • In your Claude Code session, press Shift+Tab to cycle through permission modes until you reach Plan Mode.
  • You'll see the input box border change color to indicate you're in Plan Mode.

What is Plan Mode?

Claude Code has several permission modes you can cycle through with Shift+Tab. In Plan Mode, Claude describes what it will do and waits for your approval before making any changes. This means it won't create or edit files until you switch back to a normal mode and confirm.

Think of it as a whiteboard session. Claude maps out the architecture, file structure, and feature logic. You review the map, then give the go-ahead to build.

  • Type the following prompt into Claude Code to describe the bookmark manager you want to build:
Design a personal bookmark manager web app. I need these features:
- Save bookmarks with a title, URL, and category
- Search bookmarks by title or URL
- Delete bookmarks with a confirmation prompt
- Filter bookmarks by category
- Use localStorage to persist all data between sessions

The categories should be: General, Work, Learning, Entertainment, and Social.
The app should use three files: index.html, style.css, and script.js.
Keep the design clean, minimal, and responsive.

Why be this specific?

Vague prompts produce vague results. Naming the exact features, the file structure, and the visual style gives Claude a clear target. You'll get a focused plan instead of a generic outline.

The official best practice is: instead of "build me an app", try "build a bookmark manager with title, URL, and category fields that persists data with localStorage."

After you press Enter, Claude responds with a structured plan. It outlines the file structure, the features it will implement, and how the pieces connect.

Don't see a plan?

If Claude starts creating files instead of planning, you're not in Plan Mode. Press Shift+Tab to cycle modes until the border color changes, then try your prompt again.

If Claude asks a clarifying question instead of producing a plan, answer the question. It's gathering the details it needs to give you a useful plan.

Help me get into Plan Mode in Claude Code

Review the plan and exit Plan Mode

Claude's plan is your chance to catch issues before any code exists. Reviewing now saves you from rewriting later.

  • Read through Claude's plan. Look for the file structure (index.html, style.css, script.js), the features list, and the localStorage approach.
  • Check that the plan includes all five categories: General, Work, Learning, Entertainment, and Social.
  • If anything looks off, type feedback directly. For example:
I want a simpler layout - just a single column. Also make sure the search filters results in real time as I type.

What kind of feedback works best?

Be specific about what you want changed. "Make it better" gives Claude nothing to work with. "Move the search bar above the bookmark list and add real-time filtering" gives it a clear action.

You can go back and forth as many times as you like. Plan Mode is for iteration. Once the plan covers everything you need, move on.

  • Once you're satisfied with the plan, press Shift+Tab again to exit Plan Mode and return to the default permission mode.

The input box border returns to its normal color. You're now back in the mode where Claude can create and edit files.

Your plan is your reference

The plan stays in your conversation history. When you give Claude the build prompt in the next step, it already knows the architecture you agreed on. You don't need to repeat everything.

Your blueprint is locked in. Next up, you'll give Claude the green light to build the entire app from this plan.

Build the App with Claude Code

You have a solid plan approved and ready to go. Now it's time to hand the actual building work over to Claude Code.

The key skill here is writing a specific, comprehensive prompt that gives Claude everything it needs in one shot. Vague prompts produce vague results. Detailed prompts produce working apps.

In this step, get ready to:
  • Give Claude Code a detailed prompt to build the entire bookmark manager.
  • Approve file creation actions as Claude generates code.
  • Test the working app in your browser.
Give Claude a comprehensive build prompt

The more specific your prompt, the closer Claude's output matches what you want on the first try. You need to tell Claude about the file structure, the features, the visual style, and how data is stored.

  • In your Claude Code session, type the following prompt and press Enter:
Build a personal bookmark manager web app with the following specifications:

File structure:
- index.html (main page)
- style.css (all styles)
- script.js (all logic)

Features:
- A form to add bookmarks with title, URL, and category (General, Work, Learning, Entertainment, Social)
- Display bookmarks as cards showing title, clickable URL, and category badge
- Search bar that filters bookmarks by title or URL as the user types
- Category dropdown filter with an "All Categories" default option
- Delete button on each bookmark card with a confirmation dialog
- localStorage persistence so bookmarks survive page refresh

Visual style:
- Clean, minimal design with a centered container (max 800px)
- Use CSS custom properties for colors
- Responsive layout that works on mobile
- Cards with subtle shadows and rounded corners
- Blue accent color for interactive elements, red for delete

Show an empty state message when there are no bookmarks.

Why does this prompt work?

This prompt is effective because it covers all four dimensions Claude needs: structure (what files to create), behavior (what features to build), aesthetics (what it should look like), and data (how to persist information).

A vague prompt like "build me a bookmark manager" would leave too many decisions to Claude, and you'd spend more time iterating. Front-loading detail saves time.

Tailor the prompt to your taste

Feel free to adjust the visual style or categories before pressing Enter. Want a dark theme? Prefer different categories? Change the prompt to match your preferences. This is your app.

Approve Claude's file creation actions

After you submit your prompt, Claude Code starts generating code. It creates each file one at a time, but it cannot write anything to disk without your explicit permission.

  • Watch your terminal as Claude proposes creating index.html. It shows you the proposed changes and waits for your approval.
  • Press y to approve the file creation.
  • Repeat for style.css and script.js when Claude proposes them.

What is happening behind the scenes?

Claude Code always asks for permission before modifying files. For each file, it finds the appropriate location, shows you the proposed changes, asks for your approval, and then makes the edit.

You can also enable an "Accept all" mode for the session if you prefer not to approve each file individually. For your first project, approving one by one lets you see exactly what Claude creates.

  • Wait for Claude to finish generating all three files. You will see it wire the HTML to the CSS and JavaScript automatically.

Claude seems stuck or stopped generating?

If Claude stops after creating only one file, it may be waiting for another approval. Check if there is a permission prompt you missed in the terminal output.

If Claude generated an error, read the message carefully. You can type a follow-up like "that didn't work, try again" and Claude will attempt a fix.

Help me troubleshoot this

Test the app in your browser

Claude Code just generated a complete web app from your description. Time to see if it works.

  • Open File Explorer and navigate to your bookmark-manager folder on your Desktop.
  • Double-click index.html to open it in your default browser.
  • Try adding a bookmark: type a title like NextWork, enter https://www.nextwork.org as the URL, pick a category, and click Add Bookmark.
  • Add two or three more bookmarks with different categories.
  • Type a word into the search bar and confirm it filters your bookmarks in real time.
  • Change the category dropdown to a specific category and confirm only matching bookmarks appear.
  • Click Delete on one of your bookmarks. A confirmation dialog should appear. Click OK to confirm.
  • Close the browser tab, then reopen index.html. Your bookmarks should still be there thanks to localStorage persistence.

What should I see?

You should see a clean, centered page with a form at the top for adding bookmarks. Below that is a search bar and category filter. Your added bookmarks appear as cards with the title, a clickable link, a category badge, and a red delete button.

If the page shows "No bookmarks yet. Add your first one above!" before you add anything, that is the empty state working correctly.

Page looks broken or features don't work?

If the page is unstyled (no colors, no layout), check that style.css exists in the same folder as index.html. Open your browser's developer console (press F12) and look for red error messages.

If adding bookmarks does nothing, check that script.js exists in the same folder. A common issue is Claude generating the HTML with a different script filename than it used for the actual file.

Help me fix my bookmark manager

✔️ Awesome, I've got everything!

Great. Make sure all three features work (add, search/filter, and delete) and that your bookmarks persist when you close and reopen the page.

ⓧ I'd like to double check the full code

Here is what each generated file should look like. Compare your files against these references.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bookmark Manager</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <header>
            <h1>📑 Bookmark Manager</h1>
        </header>

        <section class="add-bookmark">
            <h2>Add Bookmark</h2>
            <form id="bookmark-form">
                <input type="text" id="bookmark-title" placeholder="Title" required>
                <input type="url" id="bookmark-url" placeholder="https://example.com" required>
                <select id="bookmark-category">
                    <option value="general">General</option>
                    <option value="work">Work</option>
                    <option value="learning">Learning</option>
                    <option value="entertainment">Entertainment</option>
                    <option value="social">Social</option>
                </select>
                <button type="submit">Add Bookmark</button>
            </form>
        </section>

        <section class="controls">
            <input type="text" id="search-input" placeholder="Search bookmarks...">
            <select id="filter-category">
                <option value="all">All Categories</option>
                <option value="general">General</option>
                <option value="work">Work</option>
                <option value="learning">Learning</option>
                <option value="entertainment">Entertainment</option>
                <option value="social">Social</option>
            </select>
        </section>

        <section class="bookmarks-list">
            <div id="bookmarks-container"></div>
            <p id="empty-message" class="empty-message">No bookmarks yet. Add your first one above!</p>
        </section>
    </div>

    <script src="script.js"></script>
</body>
</html>
:root {
    --bg-primary: #ffffff;
    --bg-secondary: #f5f5f5;
    --text-primary: #333333;
    --text-secondary: #666666;
    --accent: #4a90d9;
    --accent-hover: #357abd;
    --border: #dddddd;
    --danger: #e74c3c;
    --danger-hover: #c0392b;
    --shadow: rgba(0, 0, 0, 0.1);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    line-height: 1.6;
    padding: 20px;
}

.container {
    max-width: 800px;
    margin: 0 auto;
}

header {
    text-align: center;
    margin-bottom: 30px;
}

header h1 {
    font-size: 2rem;
    color: var(--text-primary);
}

.add-bookmark {
    background: var(--bg-primary);
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px var(--shadow);
    margin-bottom: 20px;
}

.add-bookmark h2 {
    margin-bottom: 15px;
    font-size: 1.2rem;
    color: var(--text-secondary);
}

#bookmark-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

#bookmark-form input[type="text"],
#bookmark-form input[type="url"] {
    grid-column: 1 / -1;
}

#bookmark-form input,
#bookmark-form select,
#bookmark-form button {
    padding: 10px 15px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.95rem;
}

#bookmark-form input:focus,
#bookmark-form select:focus {
    outline: none;
    border-color: var(--accent);
}

#bookmark-form button {
    background: var(--accent);
    color: white;
    border: none;
    cursor: pointer;
    font-weight: 600;
    transition: background 0.2s;
}

#bookmark-form button:hover {
    background: var(--accent-hover);
}

.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.controls input,
.controls select {
    padding: 10px 15px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.95rem;
    background: var(--bg-primary);
}

.controls input {
    flex: 1;
}

.controls input:focus,
.controls select:focus {
    outline: none;
    border-color: var(--accent);
}

.bookmark-card {
    background: var(--bg-primary);
    padding: 15px 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px var(--shadow);
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
}

.bookmark-info {
    flex: 1;
    min-width: 0;
}

.bookmark-info h3 {
    font-size: 1rem;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bookmark-info a {
    color: var(--accent);
    text-decoration: none;
    font-size: 0.85rem;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bookmark-info a:hover {
    text-decoration: underline;
}

.bookmark-category {
    display: inline-block;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.75rem;
    margin-top: 4px;
    text-transform: capitalize;
}

.bookmark-actions button {
    background: var(--danger);
    color: white;
    border: none;
    padding: 8px 12px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    transition: background 0.2s;
}

.bookmark-actions button:hover {
    background: var(--danger-hover);
}

.empty-message {
    text-align: center;
    color: var(--text-secondary);
    padding: 40px 20px;
    font-style: italic;
}

@media (max-width: 600px) {
    #bookmark-form {
        grid-template-columns: 1fr;
    }

    .controls {
        flex-direction: column;
    }

    .bookmark-card {
        flex-direction: column;
        align-items: flex-start;
    }

    .bookmark-actions {
        align-self: flex-end;
    }
}
const bookmarkForm = document.getElementById('bookmark-form');
const bookmarkTitle = document.getElementById('bookmark-title');
const bookmarkUrl = document.getElementById('bookmark-url');
const bookmarkCategory = document.getElementById('bookmark-category');
const searchInput = document.getElementById('search-input');
const filterCategory = document.getElementById('filter-category');
const bookmarksContainer = document.getElementById('bookmarks-container');
const emptyMessage = document.getElementById('empty-message');

let bookmarks = JSON.parse(localStorage.getItem('bookmarks')) || [];

function saveBookmarks() {
    localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
}

function renderBookmarks() {
    const searchTerm = searchInput.value.toLowerCase();
    const categoryFilter = filterCategory.value;

    const filtered = bookmarks.filter(bookmark => {
        const matchesSearch = bookmark.title.toLowerCase().includes(searchTerm) ||
                              bookmark.url.toLowerCase().includes(searchTerm);
        const matchesCategory = categoryFilter === 'all' || bookmark.category === categoryFilter;
        return matchesSearch && matchesCategory;
    });

    bookmarksContainer.innerHTML = '';

    if (filtered.length === 0) {
        emptyMessage.style.display = 'block';
        if (bookmarks.length === 0) {
            emptyMessage.textContent = 'No bookmarks yet. Add your first one above!';
        } else {
            emptyMessage.textContent = 'No bookmarks match your search.';
        }
    } else {
        emptyMessage.style.display = 'none';
        filtered.forEach(bookmark => {
            const card = document.createElement('div');
            card.className = 'bookmark-card';
            card.innerHTML = `
                <div class="bookmark-info">
                    <h3>${escapeHtml(bookmark.title)}</h3>
                    <a href="${escapeHtml(bookmark.url)}" target="_blank" rel="noopener noreferrer">${escapeHtml(bookmark.url)}</a>
                    <span class="bookmark-category">${escapeHtml(bookmark.category)}</span>
                </div>
                <div class="bookmark-actions">
                    <button onclick="deleteBookmark('${bookmark.id}')">Delete</button>
                </div>
            `;
            bookmarksContainer.appendChild(card);
        });
    }
}

function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

function addBookmark(event) {
    event.preventDefault();

    const newBookmark = {
        id: Date.now().toString(),
        title: bookmarkTitle.value.trim(),
        url: bookmarkUrl.value.trim(),
        category: bookmarkCategory.value,
        createdAt: new Date().toISOString()
    };

    bookmarks.unshift(newBookmark);
    saveBookmarks();
    renderBookmarks();
    bookmarkForm.reset();
}

function deleteBookmark(id) {
    if (confirm('Are you sure you want to delete this bookmark?')) {
        bookmarks = bookmarks.filter(bookmark => bookmark.id !== id);
        saveBookmarks();
        renderBookmarks();
    }
}

bookmarkForm.addEventListener('submit', addBookmark);
searchInput.addEventListener('input', renderBookmarks);
filterCategory.addEventListener('change', renderBookmarks);

renderBookmarks();

Your bookmark manager is alive. Next up, you will learn how to iterate on what Claude built by giving it targeted corrections and committing your work with Git.

Iterate and Improve

Your bookmark manager is alive and working. You can add, search, filter, and delete bookmarks. That is a huge milestone for a single prompting session.

The real power of Claude Code shows up in what happens next: iteration. You can refine your app by describing exactly what you want changed, commit your work to Git without leaving the conversation, and manage your session's token usage to stay efficient.

In this step, get ready to:
  • Give Claude Code specific corrections using targeted prompts.
  • Commit all your changes to Git through Claude Code's conversational interface.
  • Check your token usage and reset your context window.
Give Claude specific corrections

Vague prompts produce vague results. The more specific your correction, the more precisely Claude Code can act on it.

  • Look at your bookmark manager in the browser and pick something you want to improve.
  • Return to your Claude Code session in PowerShell.
  • Type a precise, targeted prompt describing the change you want.

Here are examples of specific prompts that work well:

The category dropdown should have a default 'All' option for filtering
Make the delete button red and add a confirmation

Why specific prompts matter

A vague prompt like "fix the bug" forces Claude to guess what you mean. A specific prompt like "fix the login bug where users see a blank screen after entering wrong credentials" gives Claude the exact context it needs to act.

Name the element, describe the behaviour you want, and mention any visual details. The more concrete you are, the fewer back-and-forth iterations you need.

  • Approve Claude's file changes when prompted.
  • Refresh your browser to see the updated app.
  • If the change isn't quite right, give another specific correction. This back-and-forth is normal and expected.

One change at a time

Resist the urge to ask for five things in a single prompt. Give one correction, verify it, then move on to the next. This keeps each change clean and easy to undo if something goes wrong.

Commit your changes to Git

You can ask Claude Code to run Git commands for you using plain English. No need to remember exact Git syntax.

  • Ask Claude Code to commit your work by typing this prompt:
commit all changes with a descriptive message

What does this do?

Claude Code stages all modified files with git add, writes a descriptive commit message based on what changed, and runs git commit. You get a clean Git history without memorizing commands.

  • Approve the Git commands when Claude asks for permission.
  • You should see a confirmation message showing the commit hash and message that Claude chose.

Git commit failed?

If Claude reports an error about Git identity, it means Git does not know your name and email yet. Ask Claude: "set my git user name to My Name and email to my@email.com, then commit." Replace the name and email with your own.

If you skipped installing Git for Windows in Step 1, Claude Code uses PowerShell and may not have access to git. Go back and install it, then relaunch Claude Code.

Help me fix a Git commit error in Claude Code.

Check your token usage and clear context

Every prompt, file read, and code generation uses tokens from your context window. Keeping an eye on usage helps you stay efficient during longer sessions.

  • Check how many tokens you have used so far by typing this slash command:
/cost

What does /cost show?

The /cost command displays your token usage for the current session. This helps you understand how much context Claude has consumed so you can plan when to reset.

  • If you are planning to continue with more changes (like the Secret Mission), reset your context by typing:
/clear

Why clear context?

The /clear command wipes your conversation history, giving Claude a fresh context window. Your files on disk stay exactly as they are. Claude will re-read your CLAUDE.md on the next prompt, so it retains your project conventions.

When to clear

Clear your context when you are switching to a completely different task (like moving from feature work to bug fixing). If you are still iterating on the same feature, keep your context intact so Claude remembers what you have been working on.

You have now experienced the full Claude Code workflow: plan, build, iterate, and commit. Your bookmark manager is polished and safely stored in Git. Next up, you can take on the Secret Mission to add dark mode and import/export to your app.

Secret mission

Add Dark Mode and Import/Export

Your bookmark manager works great, but what about late-night browsing sessions? And what happens if you clear your browser data? In this secret mission, you'll prompt Claude Code to add a dark mode toggle and an import/export system so your bookmarks are never lost.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on your local machine, so there are no ongoing cloud costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • The bookmark-manager project folder on your Desktop (including index.html, style.css, script.js, and CLAUDE.md).
  • Claude Code CLI tool installed on your system.
  • Git for Windows installed on your system.
  • Claude Pro subscription (pre-existing, not created by this project).

Keep everything running

No action needed. Choose this if you plan to keep building on your bookmark manager or using Claude Code for other projects.

  • Your bookmark-manager folder stays on your Desktop for future use.
  • Claude Code remains installed and ready for your next project.
  • Git for Windows stays available for version control on any project.
  • Your Claude Pro subscription continues at $20/month (billed monthly) or $17/month (billed annually).

Pause - I'll come back to this later

Free up space without losing your work. You can always resume later.

  • Your project files stay on disk. No processes are running since the app is a static HTML file.
  • Claude Code has no background processes to stop. It only runs when you launch it.
  • No action required for a pause. Everything is already idle.

Delete - I don't want to use this again

Remove all project files and optionally uninstall Claude Code and Git for Windows.

  • Delete your project folder by running this in PowerShell:
Remove-Item -Path "$env:USERPROFILE\Desktop\bookmark-manager" -Recurse -Force
  • To uninstall Claude Code, run these commands in PowerShell:
Remove-Item -Path "$env:USERPROFILE\.local\bin\claude.exe" -Force
Remove-Item -Path "$env:USERPROFILE\.local\share\claude" -Recurse -Force
  • To also remove Claude Code settings and cached data, run:
Remove-Item -Path "$env:USERPROFILE\.claude" -Recurse -Force
Remove-Item -Path "$env:USERPROFILE\.claude.json" -Force
  • To uninstall Git for Windows, open Settings, then select Apps, then Installed apps.
  • Search for Git, click the three-dot menu next to it, and select Uninstall.
  • Your Claude Pro subscription is managed separately. If you no longer need it, you can cancel it from your account settings at claude.ai.

Nice Work!

Nice Work!

Nice work! You just built a complete web app without writing a single line of code yourself.

You've learned how to:

  • Installed and authenticated Claude Code on Windows, and created a CLAUDE.md project memory file to guide its behavior across sessions.
  • Used Plan Mode to design your app's architecture before any code was generated, following the explore-plan-code workflow.
  • Built a full bookmark manager with natural-language prompts and iterated with specific corrections to refine the output.
  • Secret Mission: Added dark mode and import/export functionality as stretch features.

Ready to quiz yourself?