Add Features to an Existing Project
Add Features to an Existing Project
Building from scratch is exciting, but let's be honest — most of your time as a developer is spent working with code that already exists. You join a project, inherit a codebase, or return to something you built six months ago and barely remember. This is where Claude Code truly shines.
In this lesson, you will learn how to use Claude Code to add features to an existing project. We will walk through three practical examples: pagination, JWT authentication, and full-text search. Along the way, you will learn the review and commit workflow that keeps your codebase healthy.
Preparing the Project
Before you start a Claude Code session on an existing project, a little preparation goes a long way.
Make Sure Git Is Initialized
Claude Code works best when your project uses git. It uses git status, git diff, and the commit history to understand what has changed. If your project is not already a git repository:
cd your-project
git init
git add .
git commit -m "Initial commit"
Create a CLAUDE.md File
A CLAUDE.md file at the root of your project tells Claude Code about your project's architecture, conventions, and important details. If you do not have one yet, you can ask Claude Code to create one:
claude
# Then in the session:
> Read through this project and create a CLAUDE.md file that describes
> the architecture, tech stack, directory structure, and any conventions
> you notice in the code.
This is one of the best investments you can make. Future Claude Code sessions will automatically read this file and immediately understand your project.
Make Sure You Are on a Clean Branch
Always start feature work on a new branch:
git checkout -b feature/add-pagination
This way, if something goes wrong, you can always go back to your main branch without losing anything.
Example 1: Add Pagination to the /products Endpoint
Imagine you have an e-commerce API with a /products endpoint that returns every product in the database at once. As your product catalog grows, this becomes slow and wasteful. Let's add pagination.
Start a Claude Code session in your project:
claude
The Prompt
Add pagination to the GET /products endpoint.
Requirements:
- Accept page and limit query parameters
- Default to page 1, limit 20
- Return a response with this shape:
{
"data": [...products],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"totalPages": 8
}
}
- Update the database query to use LIMIT and OFFSET
- Keep the existing filters (category, priceRange) working alongside pagination
How Claude Code Approaches This
Before writing a single line, Claude Code reads your existing code. It will examine:
- The route handler — to understand the current response format and any existing query parameters
- The database layer — to see how queries are structured (raw SQL? an ORM like Prisma? Knex?)
- Other endpoints — to check if pagination is already implemented elsewhere (so it can follow the same pattern)
- Type definitions — to understand the shape of the Product model
This is a critical difference from asking a chatbot for help. Claude Code does not give you generic pagination code. It gives you pagination that fits your codebase, using your patterns and your database layer.
After reading, Claude Code will typically:
- Add query parameter parsing to the route handler
- Modify the database query to include
COUNT(*)for the total andLIMIT/OFFSETfor the page - Create a pagination utility if one does not exist (or reuse one if it does)
- Update the response format
- Update TypeScript types if needed
Verify the Changes
# Test default pagination
curl "http://localhost:3000/products"
# Should return first 20 products with pagination metadata
# Test custom page and limit
curl "http://localhost:3000/products?page=2&limit=10"
# Should return products 11-20
# Test that existing filters still work
curl "http://localhost:3000/products?category=electronics&page=1&limit=5"
# Should return first 5 electronics products
Example 2: Add Authentication Middleware Using JWT
Next, let's add authentication. This is a more complex change because it touches multiple files and introduces new dependencies.
Add JWT authentication to the API.
Requirements:
- Create POST /auth/register (name, email, password)
- Create POST /auth/login (email, password) that returns a JWT token
- Hash passwords with bcrypt before storing
- Create an auth middleware that validates JWT tokens from the Authorization header
- Protect all /products endpoints (except GET) with the auth middleware
- GET /products should remain public
- Store the JWT secret in an environment variable JWT_SECRET
- Add a .env.example file showing required environment variables
Watch Claude Code Work Across Files
This is a multi-file change. Claude Code will typically:
- Install
jsonwebtoken,bcrypt, and their TypeScript types - Create
src/routes/auth.tswith register and login endpoints - Create
src/middleware/auth.tswith the JWT validation middleware - Update the database schema to add a
passwordfield to users (or create a newuserstable if using the products-only scenario) - Update
src/routes/products.tsto apply the middleware selectively - Create or update
.env.example - Update
src/index.tsto register the new auth routes
Claude Code reads your existing middleware patterns, route structure, and database setup before making these changes. If your project already uses a specific pattern for middleware (like a middlewares/ directory), it will follow that convention.
Test the Authentication Flow
# Register a new user
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com", "password": "securepass123"}'
# Login to get a token
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "alice@example.com", "password": "securepass123"}'
# Response: { "token": "eyJhbG..." }
# Try to create a product without a token — should fail with 401
curl -X POST http://localhost:3000/products \
-H "Content-Type: application/json" \
-d '{"name": "Widget", "price": 9.99}'
# Create a product with the token — should succeed
curl -X POST http://localhost:3000/products \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbG..." \
-d '{"name": "Widget", "price": 9.99}'
# GET /products should still work without a token
curl http://localhost:3000/products
Example 3: Add a Search Feature with Full-Text Search
The third example demonstrates how Claude Code handles features that require both backend and database changes:
Add a search feature to the products endpoint.
Requirements:
- Add a GET /products/search?q=searchterm endpoint
- Use SQLite FTS5 for full-text search across product name and description
- Return results ranked by relevance
- Include a snippet of the matching text in the results
- Support pagination on search results too
Claude Code will need to:
- Create an FTS5 virtual table in SQLite
- Add a migration or initialization step to populate the FTS index
- Keep the FTS index in sync when products are created, updated, or deleted (using triggers or application-level logic)
- Create the search endpoint with proper query escaping
- Reuse the pagination pattern from Example 1
This is where Claude Code's ability to read and understand your existing code pays off. It will see the pagination implementation from earlier and reuse the same response format for search results.
# Search for products
curl "http://localhost:3000/products/search?q=wireless+bluetooth"
# Should return relevant products with pagination
curl "http://localhost:3000/products/search?q=wireless&page=2&limit=5"
# Should return paginated search results
The Review Workflow
After Claude Code makes changes, you should always review them before committing. This is not about distrusting Claude Code — it is about understanding what changed in your codebase.
Using Git Diff
The simplest review method is right inside Claude Code:
Show me a summary of all the changes you made
Claude Code will give you a high-level overview. For the detailed diff, you can ask:
Run git diff to show me exactly what changed
Or exit Claude Code and run it yourself:
git diff
For a file-by-file summary:
git diff --stat
This shows which files changed and how many lines were added or removed:
src/routes/products.ts | 45 +++++++++++++++++++++++++++--
src/middleware/auth.ts | 38 +++++++++++++++++++++++
src/routes/auth.ts | 67 ++++++++++++++++++++++++++++++++++++++
src/index.ts | 4 ++-
.env.example | 3 +++
package.json | 4 ++-
6 files changed, 157 insertions(+), 4 deletions(-)
What to Look For During Review
When reviewing Claude Code's changes, pay attention to:
- Existing patterns: Did Claude Code follow your project's conventions? If your project uses a repository pattern for database access, did it create a new repository or bypass the pattern?
- Error handling: Are errors handled consistently with the rest of the codebase?
- Security: For authentication code, check that passwords are hashed, tokens have expiration times, and secrets come from environment variables.
- Types: Are TypeScript types accurate and complete? Did Claude Code add any
anytypes that should be more specific? - Edge cases: Does the pagination handle page=0 or page=-1 gracefully? Does the search handle empty queries?
Asking Claude Code to Fix Issues
If you spot something during review, tell Claude Code:
In the auth middleware, the JWT token should expire after 24 hours,
not 7 days. Also, add rate limiting to the login endpoint —
max 5 attempts per IP per minute.
Claude Code will make the targeted adjustments without disrupting the rest of the changes.
The Commit Workflow
Once you are satisfied with the changes, ask Claude Code to commit:
Commit these changes with a descriptive commit message following
conventional commit format
Claude Code will stage the relevant files and create a commit message like:
feat(auth): add JWT authentication with register and login endpoints
- Add POST /auth/register with bcrypt password hashing
- Add POST /auth/login that returns JWT tokens
- Create auth middleware for protected routes
- Protect POST/PUT/DELETE /products endpoints
- Keep GET /products publicly accessible
- Add .env.example with JWT_SECRET
If you prefer to commit in smaller chunks:
Commit the auth middleware and route separately from the products
route changes. Use two commits.
Claude Code understands how to split changes into logical commits.
Pushing and Creating a PR
After committing, you can ask Claude Code to push and even create a pull request:
Push this branch and create a pull request with a description
of what was added
If your project uses GitHub, Claude Code can create the PR using the GitHub CLI (gh). The PR description will summarize the changes, making it easy for your team to review.
Handling Merge Conflicts
Sometimes your feature branch falls behind the main branch. Claude Code can help:
Merge the latest changes from main into this branch and resolve
any conflicts
Claude Code will:
- Run
git fetch origin - Run
git merge origin/main - If there are conflicts, read the conflicting files and resolve them intelligently — it understands both the incoming changes and your feature changes
If the conflicts are complex, Claude Code will explain what it did and why, so you can verify the resolution makes sense.
Tips for Working with Existing Codebases
Let Claude Code Explore First
For unfamiliar codebases, start with an open-ended prompt:
Read through this project and explain the architecture, key files,
and how the data flows from the API routes to the database.
This helps Claude Code build context and helps you understand what you are working with.
Reference Existing Patterns
When asking for new features, point Claude Code to existing examples:
Add a PATCH /users/:id endpoint following the same pattern used
in src/routes/products.ts for the PATCH /products/:id endpoint.
This ensures consistency across your codebase.
Ask for Incremental Changes
Rather than asking for a massive change all at once, break it into steps. After each step, review and commit. This gives you clean checkpoints to revert to if needed.
Keep Your CLAUDE.md Updated
As your project evolves, ask Claude Code to update the CLAUDE.md:
Update the CLAUDE.md to reflect the new auth system and
search feature we just added.
This keeps future Claude Code sessions informed about the latest architecture.
Key Takeaway
Working with existing codebases is where Claude Code provides the most value. It reads your code, understands your patterns, and makes changes that fit naturally into the project. The review and commit workflow keeps you in control while letting Claude Code handle the heavy lifting.
The three-step rhythm is: prompt, review, commit. Follow this pattern and you will move faster while keeping your codebase clean and well-documented.
In the next lesson, you will learn how to use Claude Code for code review, documentation generation, and CI/CD integration.
Quiz
Discussion
Sign in to join the discussion.

