Build a Bookmark Manager with Claude Code

Build a web app using only natural language with Claude Code.

Introduction

30 Second Summary

You probably have dozens of bookmarks scattered across browsers, sticky notes, and message threads. What if you could build your own bookmark organizer without writing a single line of code yourself?

In this project, you will use Claude Code to build a personal bookmark manager web app entirely through natural language conversations. You'll learn the core workflow that professional developers use with agentic coding tools: explore, plan, then code.

What You'll Build

A personal bookmark manager web application that lets you save, categorize, and search bookmarks, built entirely by directing an AI coding agent through natural language.

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

  • Claude Code installed and configured on your machine, ready to use on any project.
  • A working bookmark manager web app with add, delete, search, and filter features, built through natural language conversations.
  • A CLAUDE.md file and Git repository demonstrating professional agentic coding workflows.
  • Secret Mission: Add dark mode with a toggle switch and persistent theme preference.

Are there any prerequisites?

You'll need basic familiarity with the terminal (navigating directories, running commands). Some programming awareness is helpful but not required.

You'll also need a Claude Pro, Max, Team, or Enterprise subscription (or a Claude Console account with prepaid credits). The free Claude.ai plan does not include Claude Code access.

Install Claude Code

Claude Code is a terminal-based AI coding agent that builds software through natural language conversations. It reads your project files, runs commands, and edits code on your behalf.

In this step, you'll install Claude Code, authenticate with your Claude account, and create a project directory with Git tracking so Claude Code can manage your version history.

In this step, get ready to:
  • Install Claude Code on your machine.
  • Log in with your Claude account.
  • Create a project directory with Git tracking.
Install Claude Code via the native installer

Anthropic's native installer is the recommended way to install Claude Code. It auto-updates in the background, so you'll always have the latest version without manual maintenance.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal and press Enter to open it.
  • Install Claude Code by running this command:
curl -fsSL https://claude.ai/install.sh | bash

What does this command do?

This command downloads and runs Anthropic's official install script. It places the claude binary on your system so you can use it from any terminal session.

  • Verify the installation succeeded by running:
claude --version

You should see a version number printed in your terminal.

✔️ I see a version number

Claude Code is installed and ready to go. Move on to the next substep.

ⓧ Command not found

Your terminal can't find the claude binary. Try these fixes:

  • Close your terminal completely and reopen it. The install script updates your shell profile, which only takes effect in a new session.
  • If it still doesn't work, run the install command again and watch for any error messages during installation.
  • Make sure you have macOS 13.0 or later. Check by clicking the Apple menu, then About This Mac.

help me troubleshoot why claude --version isn't working after running the install script

Log in to your Claude account

Claude Code requires an active Claude subscription to work. You'll authenticate once, and your credentials are stored locally for future sessions.

  • Start Claude Code by running:
claude

A browser window opens automatically, prompting you to log in with your Claude account.

  • Complete the login in your browser using your Claude Pro, Max, Team, or Enterprise account (or a Claude Console account with prepaid credits).
  • Return to your terminal after authentication completes.

You should see the Claude Code welcome screen in your terminal. This confirms your credentials are stored locally.

Which accounts work with Claude Code?

Claude Code requires a Claude Pro ($20/month), Max, Team, or Enterprise subscription. Alternatively, you can use a Claude Console account with prepaid API credits.

The free Claude.ai plan does not include Claude Code access.

  • Type exit to close this Claude Code session.

Browser didn't open or login failed?

  • If the browser didn't open automatically, look in your terminal for a URL. Copy and paste it into your browser manually.
  • Make sure you're logging in with a paid Claude account. Free-tier accounts cannot access Claude Code.

help me troubleshoot Claude Code authentication

Set up your project directory and initialize Git

Claude Code integrates directly with Git. It can stage changes, write commit messages, and create branches. Having a Git repo from the start means every change Claude makes is tracked.

  • Create your project directory and move into it by running these commands:
mkdir ~/bookmark-manager
cd ~/bookmark-manager

Why the home directory?

The ~ symbol refers to your home folder. This creates the bookmark-manager folder in a consistent, easy-to-find location regardless of where your terminal session started.

  • Initialize a Git repository by running:
git init

You should see a message that says Initialized empty Git repository in /Users/.../bookmark-manager/.git/ (with your own username in the path).

Seeing a prompt to install developer tools?

On macOS, if Git isn't installed yet, running git init triggers a system dialog asking you to install Xcode Command Line Tools. Click Install and wait for it to finish. Then run git init again.

help me get Git working on my Mac

Your environment is ready. Next up, you'll configure Claude Code with a CLAUDE.md file that gives it persistent context about your project.

Configure Claude Code with CLAUDE.md

Your project directory is ready and Claude Code is installed. Now it's time to give Claude some context about what you're building.

CLAUDE.md is a configuration file that Claude reads at the start of every conversation. It acts as a persistent instruction manual, telling Claude your coding preferences, project structure, and workflow rules. The better your CLAUDE.md, the more relevant Claude's output becomes.

In this step, get ready to:
  • Start a Claude Code session and run /init to generate a starter CLAUDE.md file.
  • Customize CLAUDE.md with project-specific coding rules.
  • Commit the CLAUDE.md file using Claude Code's Git integration.
Start Claude Code and run /init

The /init command analyzes your project and generates a starter CLAUDE.md file. Even though the directory is empty right now, it gives Claude a foundation to build on.

  • Start a Claude Code session in your project directory by running this command:
claude

What should I see?

You should see the Claude Code interface appear in your terminal. This is an interactive session where you type natural language prompts and Claude responds with actions, code, and explanations.

  • Inside the Claude Code session, generate a starter CLAUDE.md file by typing this command at Claude's prompt:
/init

Claude will ask you a few questions about your project to populate the file.

How should I answer the questions?

Claude Code's questions will vary, but here's the gist of what to communicate:

  • This is a front-end web app using HTML, CSS, and vanilla JavaScript.
  • It's a personal bookmark manager.
  • No build tools or frameworks are needed.

After answering the questions, Claude creates CLAUDE.md in your project folder.

Seeing an authentication error?

If Claude asks you to log in again, follow the browser prompt to authenticate with your Claude Pro, Max, Team, or Enterprise account. Your credentials are stored locally after the first successful login.

Help me fix my Claude Code login

Review and customize your CLAUDE.md

The generated CLAUDE.md is a starting point. You'll now add specific rules so Claude knows exactly how to build this project.

  • Ask Claude to show you the current file by typing:
show me the CLAUDE.md file

Take a quick look at what Claude generated. It should have some basic project info. Now you'll add your specific coding rules.

  • Tell Claude to update the file with your project preferences by typing this prompt:
update CLAUDE.md to include these rules:
- Use vanilla JavaScript only, no frameworks
- Use semantic HTML5 elements
- Keep all code in a single-page app structure (index.html, style.css, app.js)
- Use localStorage for data persistence
- Write clear comments explaining the code
- Always run the app in a browser to verify changes work

What do these rules do?

Each rule you add to CLAUDE.md shapes how Claude writes code for this project:

  • "Vanilla JavaScript only" prevents Claude from pulling in React, Vue, or other frameworks.
  • "Single-page app structure" keeps your project to three predictable files instead of a sprawling directory tree.
  • "localStorage for data persistence" means bookmarks survive a page refresh without needing a backend server.
  • "Clear comments" ensures the generated code is readable and educational.

Why use CLAUDE.md instead of repeating instructions?

Without CLAUDE.md, you'd need to remind Claude of your preferences every time you start a new session. CLAUDE.md is read automatically at the beginning of every conversation, so your rules are always in effect.

  • Verify Claude updated the file by asking it to show the contents again:
show me the CLAUDE.md file

You should see your six rules reflected in the file. The exact formatting may differ since Claude generates the structure.

Missing some of your rules?

If Claude only added some of your rules, ask it to add the missing ones. You can also ask Claude to rewrite the entire file from scratch with all six rules included.

Help me get all my rules into CLAUDE.md

Commit the CLAUDE.md file

Claude Code integrates directly with Git. Instead of running git add and git commit yourself, you can ask Claude to handle it.

  • Ask Claude to commit your new file by typing:
commit the CLAUDE.md file with a descriptive message

What does this do?

Claude Code stages the file and creates a Git commit with an appropriate message. You've just made your first commit without running any git commands directly. This is one of the core benefits of working with an agentic coding tool.

  • Verify the commit exists by asking Claude:
show me the git log

You should see one commit with a descriptive message about adding or initializing CLAUDE.md.

Don't see the commit?

Claude Code asks for permission before modifying files or running commands. If you declined a permission prompt, Claude may not have completed the commit. Ask it to try again and approve when prompted.

Help me retry my CLAUDE.md commit

Your project now has a persistent configuration that shapes every future Claude Code conversation. Next up, you'll put it to work by having Claude build the entire bookmark manager application.

Build the Bookmark Manager

Your project now has a CLAUDE.md that tells Claude Code exactly how you want your code written.

Now it's time to build the actual app. You'll use the "explore first, plan, then code" workflow that Anthropic recommends for agentic coding. This means asking Claude to think through the architecture before writing any code.

In this step, get ready to:
  • Create an implementation plan for the bookmark manager.
  • Have Claude Code build all application files.
  • Test the app in your browser and fix any issues.
Explore and plan the implementation

Professional developers don't start typing code immediately. They explore the problem space, create a plan, then execute. This "plan then code" approach gives Claude the context it needs to make smart architectural decisions across multiple files.

  • In your Claude Code session, ask Claude to create a plan by typing this prompt:
I want to build a bookmark manager app with these features:
- Add bookmarks with a title, URL, and category
- Display bookmarks in a grid layout
- Delete bookmarks
- Filter bookmarks by category
- Search bookmarks by title or URL
- Store everything in localStorage so it persists

Create a detailed implementation plan before writing any code. What files will you create and what will each contain?

What does this prompt do?

You're giving Claude a clear feature list and explicitly asking it to plan before coding. Claude will outline the file structure (index.html, style.css, app.js) and describe what each file will contain.

This is the "explore" phase. Claude gathers context about your requirements before taking action.

Claude will produce a plan outlining the file structure and approach. Read through it to make sure it covers all the features you asked for.

  • Once you've reviewed the plan, add your UI preferences by typing this follow-up:
That looks good. Let's also make sure the UI looks modern and clean with rounded corners, subtle shadows, and a blue accent color.

Why add style preferences now?

Giving style direction during the planning phase means Claude bakes it into the implementation from the start. If you wait until after the code is written, you end up doing a separate styling pass.

Let Claude build the application

With the plan reviewed and approved, it's time to switch from planning to execution. One prompt is all it takes to kick off the build.

  • Tell Claude to execute the plan by typing this prompt:
Implement the full bookmark manager based on your plan. Create all files and make sure everything works together.

Claude Code will start creating files and show you each change for approval.

What happens during the build?

Claude Code enters its agentic loop: it creates index.html with the app structure, style.css with modern styling, and app.js with all the functionality.

For each file change, Claude asks for your permission before writing it. You can approve each change individually or allow Claude to work through everything at once.

  • Approve the file changes as Claude proposes them.

Speed up approvals

If you trust the plan and want Claude to work without pausing after each file, you can accept all proposed changes at once. Claude may create the files one by one or all at once depending on its approach.

Verify the app works

Claude has created the files, but you need to see the app running in a browser to confirm everything works together.

  • Ask Claude to help you open the app by typing this prompt:
open index.html in my default browser so I can test the app

If Claude can't open the browser directly, it will give you the command. You can also open it yourself from a separate terminal window.

  • Open a new terminal window and run this command from your project directory:
open ~/bookmark-manager/index.html
  • Test the app in your browser by working through these actions:
  • Add a bookmark with a title, URL, and category.
  • Verify the bookmark appears in the grid.
  • Use the category filter to show only bookmarks in that category.
  • Type in the search field and confirm results filter as you type.
  • Delete the bookmark and confirm it disappears.

Something not working right?

If any feature doesn't behave as expected, tell Claude exactly what's wrong. For example, if search only works when you press Enter instead of filtering in real-time, switch back to your Claude Code session and type:

The search isn't filtering results as I type. It only works when I press enter. Can you fix it to filter in real-time as I type?

Claude will read the existing code, identify the issue, and fix it. This is the iterative workflow in action.

help me debug my bookmark manager app

Your bookmark manager is alive and working. Next up, you'll iterate on it by adding form validation and a polished empty state.

Iterate and Polish

Your bookmark manager works. You can add, search, filter, and delete bookmarks, all stored in localStorage. Now it's time to polish it into something that feels professional.

In this step, you'll use Claude Code to add form validation and a friendly empty state. This demonstrates the real power of agentic coding: iterating on a working app through natural language without touching the code yourself.

In this step, get ready to:
  • Add form validation with inline error messages.
  • Add a polished empty state for when no bookmarks exist.
  • Commit all progress to Git with a descriptive message.
Add form validation

A form without validation lets users submit garbage data. Real apps catch invalid input before it enters the system and show clear error messages so users know what to fix.

  • In your Claude Code session, type this prompt to request form validation:
Add form validation to the bookmark form:
- URL must be a valid URL format
- Title is required and must be at least 2 characters
- Show inline error messages below each field in red
- Don't allow submission until all fields are valid

What will Claude Code do?

Claude Code will read your existing app.js and index.html, understand the form structure, and propose changes across multiple files. It will add validation logic to the JavaScript, error message containers to the HTML, and red error styles to the CSS.

Approve the changes as Claude proposes them. This is iterative development in action. Claude doesn't start from scratch. It builds on what already exists.

  • Once Claude finishes, refresh your browser to test the changes.
  • Try submitting the form with an empty title field. You should see a red error message below the field.
  • Try entering a single character in the title field. You should see an error about the minimum 2-character requirement.
  • Try entering an invalid URL like notaurl. You should see a URL format error.
  • Fill in all fields correctly and confirm the form submits successfully.

Validation not showing up?

If the form still submits without validation, Claude may not have saved all changes. Ask Claude: "show me the current form submit handler in app.js" to confirm the validation logic is in place.

If error messages appear but the form still submits, tell Claude what's wrong. Something like: "The error messages show but the form still submits with invalid data. Fix it so submission is blocked until all fields are valid."

Ask Claude for help debugging.

Add a polished empty state

When a user first opens the app with no bookmarks saved, a blank screen feels broken. A good empty state guides the user toward their first action.

  • In your Claude Code session, type this prompt:
When there are no bookmarks, show a friendly empty state with an icon and a message encouraging the user to add their first bookmark. Make it look inviting.

What will Claude Code do?

Claude Code will modify the render function in app.js to check whether the bookmark list is empty. If it is, the app displays a centered message with an icon instead of the empty grid.

It will also add styling in style.css to make the empty state look inviting and centered on the page.

  • Approve Claude's proposed changes.
  • To test the empty state, you need to clear any existing bookmarks. Ask Claude:
How do I clear localStorage in the browser so I can see the empty state?
  • Follow Claude's instructions to clear your bookmarks. Then refresh the browser.
  • You should see a friendly message with an icon encouraging you to add your first bookmark, instead of a blank page.
  • Add a bookmark to confirm the empty state disappears and the grid renders normally.

Still seeing a blank grid?

If the empty state doesn't appear after clearing localStorage, tell Claude what you see. A prompt like "I cleared localStorage and refreshed but I still see a blank grid instead of the empty state message. Can you check the render function?" gives Claude enough context to debug the issue.

Ask Claude for help troubleshooting.

Commit all your progress

You've added two meaningful features without writing any code yourself. Time to save this progress to Git so every change is tracked.

  • Ask Claude Code to commit everything by typing this prompt:
commit all changes with a descriptive message summarizing what we built

What does this do?

Claude Code stages all modified and new files, then creates a Git commit with a message it writes based on the changes. You didn't run git add or git commit yourself. This is Claude Code's Git integration in action.

  • Now check your Git history by typing this prompt:
show me the git log
  • You should see clean, descriptive commit messages. One for the CLAUDE.md file from earlier, and one for the application code you just committed.

Why does this matter?

Clean Git history is a hallmark of professional development. Claude Code writes commit messages that describe what changed and why, so anyone (including future you) can understand the project's evolution at a glance.

Commit failed?

If Claude reports that there's nothing to commit, it may have already committed during a previous prompt. Check with "show me the git log" to see if your changes are already tracked.

If you see a Git identity error, Claude Code needs your Git config set. Tell it: "set my git user name to My Name and email to my@email.com, then try the commit again".

Ask Claude for help with Git errors.

Your bookmark manager now validates input and handles the empty state gracefully. Next up, you'll explore Claude Code's essential commands and workflows so you can use it confidently on any future project.

Learn Essential Commands and Workflows

Your bookmark manager is polished and committed to Git. You've experienced the full power of directing Claude Code through a real project, from planning to building to iterating.

Now it's time to learn the commands that make you faster day-to-day. This step covers how to get help, manage your conversation context, run quick one-off queries, and pick up where you left off.

In this step, get ready to:
  • Explore Claude Code's built-in commands.
  • Use Claude Code for a code review.
  • Resume a previous conversation.
Explore Claude Code commands

Claude Code has a set of slash commands you can run inside any session. These let you manage context, switch models, and get help without leaving the conversation.

  • In your active Claude Code session, run the help command by typing this:
/help

What does this show?

The /help command lists all available slash commands, keyboard shortcuts, and configuration options for your session. It's your quick reference guide whenever you forget a command.

Take note of these key commands you'll use regularly:

  • /model switches the AI model mid-session. Use Sonnet for everyday tasks and Opus for complex architectural decisions.
  • /clear clears your conversation history when context gets too long.
  • /compact summarizes the conversation and frees up context space. Use this when your session feels slow but you don't want to lose the thread.

When should I use /clear vs /compact?

Use /clear when you're switching to a completely different task and don't need any prior context. Use /compact when you want to keep working on the same task but your conversation has gotten long. It compresses the history into a summary so Claude still knows what you've been doing.

Claude Code also has a non-interactive mode for quick one-off questions. This is useful when you want a fast answer without starting a full session.

  • Exit your current Claude Code session by typing exit or pressing Ctrl+D.
  • Run a one-off query from your terminal using the -p flag:
claude -p "explain the structure of app.js in this project"

What does the -p flag do?

The -p flag runs a single query and exits immediately. Claude reads your project files, answers the question, and returns you to the terminal. No interactive session, no follow-up conversation.

This is perfect for quick lookups like "what does this function do?" or "where is this variable defined?" without the overhead of a full session.

You should see Claude print an explanation of your app.js file structure directly in the terminal, then return to your normal prompt.

Not seeing any output?

Make sure you're in the ~/bookmark-manager directory. Claude needs access to your project files to answer questions about them.

If you see an authentication error, your session may have expired. Run claude to start an interactive session and re-authenticate.

Why isn't claude -p giving me output about my project?

Use Claude Code for code review

Professional developers use Claude Code not just for writing code, but for reviewing it. Let's start a fresh session and ask Claude to review your entire project for quality.

  • Start a new Claude Code session by running:
claude
  • Ask Claude to review your project by typing this into the session:
review the code in this project. Are there any bugs, accessibility issues, or improvements you'd recommend?

What happens during a code review?

Claude reads through all your project files and analyzes them for potential bugs, accessibility gaps, code style issues, and performance improvements. It provides specific, actionable recommendations.

This is how teams use Claude Code in practice. Instead of waiting for a colleague's review, you get instant feedback on code quality, catching issues before they become problems.

Claude will print a detailed review covering your HTML, CSS, and JavaScript files. You might see suggestions about ARIA attributes, error handling, or code organization.

Continue a previous conversation

Real development happens across multiple sessions. You might close your laptop, come back the next day, and want to pick up exactly where you left off. Claude Code makes this easy.

  • Exit your current session by typing exit or pressing Ctrl+D.
  • Resume your most recent conversation by running:
claude -c

What does the -c flag do?

The -c flag continues your most recent conversation in the current directory. Claude loads the previous session's context so you can keep working without re-explaining what you were doing.

You can also use claude -r to choose from a list of all your previous sessions if you want to resume an older one.

You should see your previous conversation context restored. Claude remembers what you were working on.

Session not resuming?

Make sure you're running claude -c from the same directory where your previous session was active (~/bookmark-manager). The -c flag looks for the most recent conversation in the current directory specifically.

If you're in the wrong directory, cd ~/bookmark-manager first, then try again.

Why can't I resume my Claude Code session?

Commands at a glance

  • claude starts a new interactive session.
  • claude -p "query" runs a one-off question and exits.
  • claude -c continues your most recent conversation.
  • claude -r lets you pick from a list of past sessions.

Secret mission

Add Dark Mode

You've built a fully functional bookmark manager using nothing but natural language. Now challenge yourself with a more complex feature: have Claude Code add a dark mode toggle with persistent theme preferences and smooth transitions between themes.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely on your local machine, so there are no ongoing cloud costs. Your Claude Pro subscription is billed monthly regardless of this project.

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 (HTML, CSS, JavaScript, CLAUDE.md, and Git history).
  • Claude Code CLI tool (installed via native installer).
  • Claude Code configuration files (~/.claude and ~/.claude.json).

Keep everything running

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

  • Your project files stay in ~/bookmark-manager.
  • Claude Code stays installed and auto-updates in the background.
  • Your Claude Code settings and session history remain in ~/.claude.

Pause - I'll come back to this later

There are no running processes to stop. Your files remain on disk and Claude Code stays installed, ready for when you return.

  • No action required. Everything is already "paused" because the app runs in your browser only when you open index.html.
  • When you come back, navigate to ~/bookmark-manager and run claude to pick up where you left off.

Delete - I don't want to use this again

Remove all project resources and optionally uninstall Claude Code from your machine.

  • Delete the project folder by running this command:
rm -rf ~/bookmark-manager
  • Remove the Claude Code binary and version files by running:
rm -f ~/.local/bin/claude
rm -rf ~/.local/share/claude
  • Remove Claude Code settings and session history by running:
rm -rf ~/.claude
rm ~/.claude.json
  • Confirm the project folder is gone by running:
ls ~/bookmark-manager

You should see a "No such file or directory" message confirming the folder was removed.

Nice Work!

Nice Work!

You just built a complete web application without writing a single line of code yourself. More importantly, you learned the mental model for working with Claude Code effectively on any project.

You've learned how to:

  • Installed and configured Claude Code on your machine, created a CLAUDE.md file for persistent project context, and used essential commands like /init, /model, /compact, claude -p, and claude -c.
  • Used the explore, plan, code workflow to build a multi-file bookmark manager web app entirely through natural language conversations.
  • Iterated on features using natural language prompts (form validation, empty states) and used Git integration to track every change with clean, descriptive commits.
  • Added dark mode with a toggle switch, persistent theme preference, and OS-level detection using the plan-then-code methodology.

You now have the foundation to use Claude Code on any project. Whether you're exploring a new codebase, debugging production issues, writing tests, or building features from scratch, the workflow is the same. Give Claude context, let it explore, have it plan, then execute.

Ready to quiz yourself?