All Articles Claude AI

Claude Projects for Software Development Workflows

You've probably used Claude for quick coding questions. Paste in a function, ask why it's broken, get the answer, move on. That works fine for one-off problems.

You’ve probably used Claude for quick coding questions. Paste in a function, ask why it’s broken, get the answer, move on. That works fine for one-off problems. But if you’re building real software — the kind with architecture decisions, coding standards, a team that needs consistency, and a codebase that evolves over weeks and months — those one-off conversations start falling apart fast.

The problem isn’t Claude’s intelligence. The problem is amnesia. Every new conversation starts from zero. You explain your tech stack again. You re-describe your API conventions again. You paste in your project structure again. And by the time you’ve burned through half your context window just setting the stage, you’ve lost the patience (and the tokens) for the actual work you came to do.

Claude Projects fix this. And honestly, once you set one up properly for a development workflow, going back to bare conversations feels like coding without version control. You technically can, but why would you?

Here’s the thing most devs don’t realize: the quality of Claude’s code output is directly proportional to how much project context it has. Not prompt engineering tricks. Not temperature settings. Context. The right architecture docs, the right coding conventions, the right API specs — loaded once, available always. That’s the hidden layer that turns Claude from a generic code assistant into something that actually feels like it understands your codebase.

Let me show you how to set this up properly.

What Claude Projects Actually Are

If you haven’t used them yet, here’s the quick version: Claude Projects are persistent workspaces inside Claude that let you attach reference documents, set custom instructions, and maintain shared context across every conversation within that project. Think of it as giving Claude a permanent desk in your office instead of making it start as a new contractor every morning.

Every project has three key components:

  1. Project Instructions — Custom system-level instructions that shape how Claude behaves in this project
  2. Project Knowledge — Documents, files, and references that Claude can access in every conversation
  3. Conversations — Individual chat threads that all inherit the project’s instructions and knowledge

The power is in the persistence. You set up your coding standards once, attach your architecture docs once, define your API conventions once — and then every conversation in that project has access to all of it without you lifting a finger.

For software development, this changes everything.

Setting Up a Dev Project: The Foundation

Here’s where most people go wrong: they create a project, throw in a vague instruction like “help me code,” and wonder why the output doesn’t match their codebase patterns. The magic is in what you put into the project knowledge and instructions.

Step 1: Architecture Documentation

Your first upload should be your architecture docs. Not a 200-page wiki dump — Claude has limits on project knowledge, and you want to use that space wisely. What you want is a concise architectural overview that covers:

  • System components and how they communicate
  • Tech stack with specific versions
  • Data flow from request to response
  • Key design patterns used in the codebase (repository pattern, CQRS, event sourcing, whatever you’re running)
  • Directory structure — this one matters more than you think

If you don’t have a concise architecture doc, write one. It doesn’t need to be pretty. A well-structured markdown file that covers the above in 500-1000 words will do more for Claude’s output quality than any prompt engineering trick you’ll find on Twitter.

Step 2: Coding Standards and Conventions

This is the hidden layer I mentioned earlier. When you upload your coding conventions, Claude doesn’t just acknowledge them — it internalizes them. Every code snippet it generates will follow your patterns. Your naming conventions. Your error handling approach. Your preferred import ordering.

Here’s an example of what effective project instructions look like for a development workflow:

# Project Instructions: Backend API Development

## Tech Stack

- Runtime: Node.js 22 LTS with TypeScript 5.7 (strict mode)
- Framework: Fastify 5.x with @fastify/type-provider-typebox
- Database: PostgreSQL 16 via Drizzle ORM
- Testing: Vitest with @faker-js/faker for fixtures
- Validation: TypeBox schemas (shared between route validation and DB)

## Code Conventions

- Use named exports only, never default exports
- All async functions must have explicit return types
- Error handling: use Result<T, E> pattern, never throw in business logic
- Database queries go in /src/repositories/, never in route handlers
- All repository methods accept a transaction parameter (optional)
- Prefer composition over inheritance
- No classes except for custom error types

## File Naming

- kebab-case for all files: user-repository.ts, create-order.handler.ts
- Suffix pattern: _.handler.ts, _.repository.ts, _.service.ts, _.schema.ts
- Test files: \*.test.ts colocated with source files

## API Conventions

- RESTful routes under /api/v1/
- Response envelope: { data: T, meta?: { pagination } }
- Error envelope: { error: { code: string, message: string, details?: unknown } }
- Always return appropriate HTTP status codes (201 for creation, 204 for deletion)
- Use TypeBox schemas for both request validation and response serialization

## Git Conventions

- Conventional commits: feat|fix|refactor|test|docs(scope): description
- Branch naming: feature/TICKET-123-short-description
- PRs require passing CI and at least one approval

See what happened there? You didn’t just tell Claude what language you use. You told it how your team writes code. The Result pattern instead of throwing. Named exports only. The specific file naming convention. The response envelope shape. Now every piece of code Claude generates in this project will match these patterns without you having to ask.

Step 3: API Specs and Data Models

If your project has an API, upload the OpenAPI spec or at least the key endpoint definitions. If you’re working with a database, include your schema or the key entity relationships. Claude generates dramatically better code when it knows the shape of your data.

You don’t need the entire spec. Focus on:

  • The entities you work with most frequently
  • The relationships between them
  • Any non-obvious constraints or business rules
  • The authentication and authorization model

Step 4: Your CLAUDE.md File

Here’s something the power users figured out early: if you use Claude Code (the CLI tool), you probably already have a CLAUDE.md file in your repo root that configures how Claude Code behaves in your project. Upload that same file as project knowledge in Claude Projects on the web.

Why? Because a good CLAUDE.md already contains the distilled essence of your project — the commands to run, the testing conventions, the architectural decisions, the things Claude needs to know. You’ve already done the work. Reuse it.

Code Review Workflows with Project Context

Now that your project is set up, let’s talk about one of the highest-value workflows: code review.

Here’s the typical flow: a PR comes in, you need to review it, and you want Claude’s help catching issues you might miss. Without a project, you’d need to paste in the diff, explain your coding standards, describe the architecture, and hope Claude catches the right things.

With a project? You paste in the diff and say “review this PR.” That’s it. Claude already knows your coding standards. It already knows your architecture. It already knows your error handling patterns and API conventions. So instead of generic advice like “consider adding error handling,” you get specific feedback like “this handler throws instead of using the Result pattern — wrap it in a Result.fromPromise() call consistent with the other handlers in /src/handlers/.”

That’s the difference between a code review from someone who just joined the team and one from someone who’s been working in the codebase for months.

Making Reviews Systematic

For even better results, add a code review checklist to your project instructions:

## Code Review Checklist

When reviewing code, check the following in order:

1. **Correctness**: Does the logic actually do what it claims?
2. **Type Safety**: Are TypeScript types properly narrowed? Any `as` casts that could be avoided?
3. **Error Handling**: Does it follow our Result<T, E> pattern? Are error codes specific?
4. **SQL/Query Safety**: Parameterized queries only. No string interpolation in queries.
5. **Testing**: Are new code paths covered? Are edge cases tested?
6. **Performance**: N+1 queries? Unnecessary iterations? Missing indexes?
7. **Security**: Input validation? Auth checks? No exposed secrets?
8. **Convention Compliance**: Naming, file structure, import patterns match project standards?

Prioritize findings by severity: CRITICAL > HIGH > MEDIUM > LOW.
Format findings with file path, line reference, issue description, and suggested fix.

Now every code review in this project follows the same checklist, in the same priority order, with the same format. Consistency that no human reviewer maintains at 4pm on a Friday.

Bug Tracking and Resolution with Persistent Knowledge

Here’s a workflow that will save you hours: use your Claude Project as a persistent bug investigation environment.

When a bug report comes in, start a new conversation in your project. Describe the bug, paste in the relevant code, and let Claude analyze it. Because Claude has your architecture docs, it can trace the likely path of execution. Because it has your data models, it can identify where data might be getting corrupted. Because it knows your error handling patterns, it can spot where exceptions might be getting swallowed.

But here’s the real power move: when you resolve the bug, add a brief summary to your project knowledge. Something like:

## Known Bug Patterns (Updated 2026-03-05)

### Silent Failures in Event Processing

- **Root Cause**: EventBus.emit() swallows errors from async handlers
- **Fix Applied**: Added error boundary wrapper in event-bus.ts that logs failures
  and routes to dead letter queue
- **Detection**: Watch for events where handler count > 0 but processed count = 0
- **Related Files**: src/infra/event-bus.ts, src/handlers/order-events.handler.ts

### Race Condition in User Session Creation

- **Root Cause**: Concurrent requests during OAuth callback create duplicate sessions
- **Fix Applied**: Added advisory lock on user_id in session-repository.ts
- **Detection**: Multiple active sessions per user with creation timestamps < 100ms apart
- **Related Files**: src/repositories/session-repository.ts, src/auth/oauth-callback.handler.ts

Now Claude knows about your past bugs. When a new bug comes in that looks similar, it can connect the dots. “This looks similar to the silent failure pattern in your event processing — check if the handler is async and the error is being swallowed.” That kind of institutional memory is worth its weight in gold, especially on teams with turnover.

Sprint Planning and Task Decomposition

This is an underrated use case. Load your project backlog (or even just the current sprint’s tickets) as project knowledge, and use Claude for task decomposition.

The conversation goes something like this: “We need to add multi-tenancy to the user service. Break this down into implementable tasks, considering our current architecture.”

Because Claude has your architecture docs, it knows the user service structure. Because it has your coding conventions, it knows how to scope tasks that match your workflow. Because it has your API specs, it knows what endpoints need tenant-scoping.

The output isn’t generic “Step 1: Design the schema” advice. It’s specific: “Add tenant_id column to the users table via Drizzle migration. Update the user-repository.ts to accept tenantId in all query methods. Add tenant extraction middleware using the X-Tenant-ID header pattern consistent with your other middleware in /src/middleware/. Update the TypeBox schemas in user.schema.ts to include tenantId in response types.”

That level of specificity comes from context, not from clever prompting.

Architecture Decision Records as Project Context

If your team maintains ADRs (Architecture Decision Records), upload them to your project. This is one of the highest-leverage things you can do.

Why? Because ADRs capture not just what you decided, but why you decided it. When Claude has that context, it stops suggesting solutions you’ve already considered and rejected. It understands the constraints your team operates under. It respects the boundaries you’ve set.

Without ADRs: “You should use Redis for caching.”
With ADRs: “Given your ADR-007 decision to avoid adding new infrastructure dependencies this quarter, you could implement caching at the application layer using an LRU cache in the service layer, consistent with the approach in product-service.ts.”

That’s not a generic AI response. That’s a response from something that understands your team’s actual decision landscape.

Example: ADR as Project Knowledge

Here’s what an effective ADR looks like when added to a Claude Project:

# ADR-012: API Versioning Strategy

## Status: Accepted (2026-01-15)

## Context

Our API serves both the web frontend and mobile apps. Mobile app updates
lag behind web deploys by 2-4 weeks due to app store review cycles.
Breaking changes to the API have caused mobile app crashes twice in Q4 2025.

## Decision

We will use URL-based versioning (/api/v1/, /api/v2/) rather than
header-based versioning. Old versions will be maintained for a minimum
of 6 months after a new version launches. All new endpoints default
to the latest version.

## Consequences

- Route files organized by version: /src/routes/v1/, /src/routes/v2/
- Shared business logic in /src/services/ (version-agnostic)
- Version-specific transformers in /src/transformers/v1/, /src/transformers/v2/
- Increased maintenance burden for overlapping versions
- Need automated tests that verify backward compatibility

## Alternatives Considered

- Header versioning (Accept-Version): rejected because mobile team
  found it harder to debug and API gateways don't handle it cleanly
- Query parameter versioning (?v=2): rejected as non-RESTful
- No versioning with additive-only changes: rejected because some
  changes are inherently breaking (field renames, type changes)

When this ADR lives in your project knowledge, Claude will automatically route new endpoints to the correct version directory, use the transformer pattern for version-specific response shapes, and keep business logic in the services layer. You never need to explain this again.

The Workflow That Ties It All Together

Let me paint the picture of what a full development workflow looks like with a properly configured Claude Project:

Monday morning: You open your project, start a new conversation, paste in the sprint tickets. Claude breaks them down into implementation tasks, referencing your actual codebase structure and patterns.

Monday afternoon: You start implementing the first feature. You ask Claude to scaffold the handler, repository, schema, and test files. It generates all four following your naming conventions, using your error handling patterns, with your test fixtures approach.

Tuesday: A bug report comes in. You start a new conversation, describe the symptoms, paste the relevant logs. Claude traces the likely cause through your architecture, references a similar bug pattern from your known issues doc, and suggests a fix that follows your conventions.

Wednesday: PR review time. You paste diffs into conversations. Claude reviews against your team’s checklist, catches a missing auth check, spots an N+1 query, and flags a naming convention violation. All specific to your standards, not generic advice.

Thursday: Architecture discussion. The team wants to add WebSocket support. You describe the requirements, and Claude proposes an implementation that fits within your existing architecture, respects your ADRs about infrastructure choices, and follows your file organization patterns.

Friday: You update the project knowledge with the week’s decisions — the new ADR for WebSockets, the bug pattern you discovered, the updated API endpoints. Next week starts with even richer context.

That’s the flywheel. The project gets smarter as you use it, and your conversations get more productive because the context compounds.

Tips for Keeping Your Project Effective

A few things I’ve learned the hard way:

Curate aggressively. Project knowledge has limits. Don’t dump your entire codebase in there. Upload the documents that shape how code is written, not the code itself. Architecture docs, conventions, ADRs, key schemas — yes. Every source file — no. You can always paste specific code into individual conversations.

Update regularly. Stale project knowledge is worse than no project knowledge. If your conventions change, update the project instructions. If you resolve a significant bug, add it to the known patterns. If you make an architecture decision, add the ADR. Treat your project like a living document, not a set-and-forget configuration.

Use clear formatting. Claude processes structured markdown better than prose dumps. Use headers, bullet points, and code blocks. Be specific. “Use TypeScript” is less useful than “TypeScript 5.7 strict mode with noUncheckedIndexedAccess enabled.”

Separate concerns. If you’re working on a monorepo with distinct services, consider separate projects for each service rather than one giant project. The focused context will produce better results than a project trying to hold everything.

Include anti-patterns. Don’t just tell Claude what to do — tell it what not to do. “Never use any as a type annotation except in test fixtures.” “Do not suggest ORMs other than Drizzle.” “Never put business logic in route handlers.” The negative constraints are often more valuable than the positive ones because they prevent the most common mistakes.

The Hidden Layer

Here’s what separates developers who get mediocre results from Claude from developers who get exceptional results: the best development projects include your CLAUDE.md, your architecture docs, and your coding conventions. That’s it. That’s the secret.

When Claude has those three things, it doesn’t just generate code — it generates code that matches your codebase patterns automatically. It follows your naming conventions without being asked. It uses your error handling approach without being reminded. It structures files the way your team structures files.

The code it writes looks like code your team wrote. And that’s the whole point. You’re not looking for generic, correct code. You’re looking for code that fits — code that a new team member would look at and not be able to tell whether a human or AI wrote it. That only happens when Claude has enough context to understand not just what you’re building, but how your team builds.

Set up the project once. Keep it updated. Let the context compound. The ROI is absurd.

Free Discovery Call

Start With a Conversation, Not a Commitment

Every engagement begins with a free 30-minute discovery call. We'll map what's slowing your business down and tell you exactly what we'd fix first – no pitch deck, no obligation.