Context Management and Project Setup
Explore the fundamentals of context management in Claude Code, including how to introduce projects using the /init command, create and maintain CLAUDE.md files as persistent memory, and use targeted file references with @ to provide relevant information. Understand how to balance context to optimize Claude's performance for large projects and improve coding accuracy. This lesson prepares you to apply strategic context control to enhance AI-driven development workflows.
We'll cover the following...
Now that we’re comfortable with basic conversation-driven development, it’s time to learn one of the most critical skills for productive AI-assisted development: context management. We’ve already learned how to ask Claude about a codebase and get useful responses. Here’s the challenge: what happens when a project has hundreds or thousands of files? How does Claude know which files are most relevant to our question? How do we ensure that Claude understands our project’s unique patterns, conventions, and architecture without overwhelming it with irrelevant information? That’s where context management comes in.
What is context management?
Context management is the practice of strategically controlling what information Claude has access to when helping with code. Think of it as curating Claude’s knowledge about a specific project and ensuring it knows exactly what it needs to know, when it needs to know it, without being overwhelmed by irrelevant details.
At its core, context management involves three key activities.
Establishing project understanding: Through systematic analysis and documentation, teach Claude about the project’s architecture, conventions, and important patterns.
Providing targeted information: Include specific files, configurations, and code snippets that are relevant to the current task or question.
Maintaining persistent knowledge: Create a knowledge base that Claude can reference across conversations, so we don’t have to re-explain fundamentals.
The goal is to transform Claude from a generic coding assistant into a knowledgeable team member who understands the specific project, the team’s conventions, and architectural decisions. Consider two scenarios:
Suppose we’re working on a large React application with authentication, complex state management, custom API integrations, and team-specific coding conventions. We ask Claude: “How should I implement user profile editing?” Without proper context, Claude might provide a generic React form example that doesn’t match our authentication patterns, ignores our state management approach, and violates our team’s coding standards. We would spend more time adapting suggestions than writing the code ourselves.
Too much context is just as problematic as too little. If we dump the entire codebase into every conversation, Claude gets overwhelmed, and its performance decreases.
The skill is learning to provide precisely the right context for each situation. Hence, the next step in our journey is to actually use the built-in features Claude Code comes equipped with to deal with context management.
What is the /init command?
Every meaningful relationship starts with proper introductions. The /init command is how we introduce Claude Code to a project in a systematic, intelligent way. When we run /init, Claude Code executes an analysis prompt that instructs Claude to examine the codebase. While the exact prompts are proprietary and evolve over time, we can get a sense of the intent by looking at similar prompts used in the AI coding community:
Please analyze this codebase and create a CLAUDE.md file containing:1. Build/lint/test commands - especially for running a single test2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long.If there's already a CLAUDE.md, improve it.If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.
This shows that /init is designed to create concise, actionable context for AI agents. The prompt focuses on two critical pieces of information: how to run and test the code, and what coding conventions to follow. It can also incorporate existing AI tool configurations from other editors like Cursor.
Let’s see this in action. Try running the /init command in the terminal below:
We can see that when Claude completes its analysis, it will show a comprehensive project summary and ask permission to create a CLAUDE.md file. Pay close attention to this summary, because it reveals how Claude understands the project. If something seems wrong or incomplete, this is the moment to correct it before it becomes part of the persistent context.
When Claude asks for permission to create the CLAUDE.md file, you have two choices:
Press “Enter”: Approve each individual file write operation. This gives fine-grained control over every change, but it requires more interaction.
Press “Shift+Tab”: Allow Claude to write files freely throughout the session. This is faster, but it gives Claude broader permissions.
For most projects, “Shift+Tab” is the right choice. You can always review and modify the generated CLAUDE.md file afterward.
Running /init again re-analyzes the repository and suggests updates to the existing CLAUDE.md. You can approve changes file by file using “Enter,” or apply them broadly with “Shift+Tab.” The update is “merge-ish,” that is, it tries to preserve and improve what’s there and avoid duplicating sections, but the process is best-effort.
Best practice: commit the current CLAUDE.md first and review the diff; keep long-lived conventions in Local CLAUDE.md if you don’t want them touched. If you want a true reset, rename/delete CLAUDE.md and run /init to regenerate from scratch.
How does the CLAUDE.md file work?
The CLAUDE.md file is more than documentation; it’s Claude’s persistent memory of the project. Every time we start a new conversation with Claude Code in this repository, the contents of this file are automatically included in the context. This is so that Claude remembers project specifics without repeated explanations. Here’s an example of a well-structured CLAUDE.md for a Next.js e-commerce application:
# E-Commerce PlatformThis is a Next.js-based e-commerce platform with TypeScript, featuring user authentication, product management, and payment processing.## Architecture- **Frontend**: Next.js with TypeScript, Tailwind CSS for styling- **Authentication**: NextAuth.js with database sessions- **Database**: PostgreSQL with Prisma ORM- **Payment Processing**: Stripe integration- **State Management**: Zustand for client state, React Query for server state## Key Directories- `/src/app`: Next.js app router pages and API routes- `/src/components`: Reusable UI components organized by feature- `/src/lib`: Utility functions and configuration- `/prisma`: Database schema and migrations- `/src/stores`: Zustand state management stores## Development Commands- `npm run dev`: Start development server- `npm run build`: Build for production- `npm run test`: Run test suite- `npx prisma db push`: Update database schema
We can see immediately how useful this will be to our conversations. But what if there are coding conventions or important context we need to include that aren’t already present? Will Claude Code be confined to the contents of the CLAUDE.md it created? Not necessarily.
Claude Code recognizes a hierarchy of context files, each with a different scope.
Project-level
CLAUDE.md(in the project root): Created by/init, it contains the project’s architecture, conventions, and important files. As it’s committed to source control, any teammate using Claude Code in the project shares the same context.Local
CLAUDE.md(also in the project root): Adds personal instructions without affecting teammates. For example, you might prefer more verbose explanations or have specific focus areas.
# Personal Context for This Project## My Focus AreasI'm currently working on the payment integration system. Always consider Stripe webhook handling and PCI compliance when making suggestions.## My Preferences- Prefer detailed explanations over concise ones- Always suggest comprehensive error handling- Include relevant TypeScript types in all suggestions- Remind me about writing tests for new functionality## Current Sprint ContextWe're implementing the new subscription billing system. Key files I'm working with:- @src/lib/stripe.ts- @src/app/api/webhooks/stripe/route.ts- @prisma/schema.prisma (subscription-related models)
Global
CLAUDE.md(in the home directory): Captures personal coding philosophy and preferences that apply across projects.
# Global Development Preferences## Code Style- Always use TypeScript when possible- Prefer functional programming patterns- Write self-documenting code with clear variable names- Include error handling in all examples## Communication Style- Provide the reasoning behind suggestions- Include alternative approaches when relevant- Point out potential edge cases or security considerations- Always suggest testing strategies## Security Mindset- Always consider security implications- Validate all inputs- Use parameterized queries for database operations- Follow principle of least privilege
When Claude processes a request, it combines all three files in this order:
Global
CLAUDE.md(universal preferences).Project-level
CLAUDE.md(shared project context).Local
CLAUDE.md(personal customizations).
If there are conflicts, the more specific file takes precedence. Local overrides global, which overrides project-level.
Can Claude add instructions to the memory files themselves?
While the /init command creates an excellent baseline context; every project evolves. You’ll discover new patterns, establish additional conventions, and want Claude to understand aspects that weren’t apparent during the initial analysis.
The # command puts you into “memory mode,” a streamlined way to add instructions to CLAUDE.md without manual edits. The simplest form is typing # followed by an instruction:
# When suggesting React components, always include proper TypeScript prop interfaces
Claude will intelligently merge this instruction into the appropriate section of your CLAUDE.md file, maintaining good organization, and avoiding duplication. Why don’t you go ahead and try doing this in the terminal below?
We can see that when you use the # command, Claude will merge this instruction into the appropriate section of a CLAUDE.md file, keeping the organization tidy and avoiding duplication. When you use the # command, Claude asks where to save the memory and shows the available CLAUDE.md files, so updating them doesn’t disrupt your workflow.
How do we refer to specific files in Claude Code?
One of Claude Code’s most powerful features is including specific files in a conversation using the @ symbol. This lets us include exactly the files that are relevant to the current question.
The simplest form is @ followed by a file path or pattern:
How does the blog post rendering work? @src/pages/blog/[...slug].astro
This automatically includes the contents of src/pages/blog/[...slug].astro, so Claude can answer based on the actual Astro implementation.
Claude Code also supports intelligent file matching. You don’t need exact paths, and a command like @blog can show a list of matches:
Found multiple matches for "blog":1. src/pages/blog/[...slug].astro2. src/layouts/BlogPost.astro3. src/content/blog/4. src/components/BlogCard.astroWhich files would you like to include? (Enter numbers separated by commas)
We can also include multiple files in a single question:
I need to modify how blog posts display their metadata. How should I update this?@src/layouts/BlogPost.astro @src/components/BlogCard.astro @src/content/config.ts
This gives Claude a complete picture of the blog post layout, component structure, and content configuration, enabling comprehensive suggestions.
Use @ when:
You’re asking about specific functionality that exists in particular files.
You want Claude to modify or extend existing code.
You’re debugging an issue and know which files are involved.
You need Claude to maintain consistency with existing patterns.
Don’t use @ when:
You’re asking general questions about the project (Claude can find relevant files on its own).
You’re not sure which files are relevant (let Claude explore first).
You’re including so many files that you overwhelm the context.
Can we add context files in CLAUDE.md too?
While the @ symbol includes files in individual conversations, referencing files directly in CLAUDE.md creates persistent context that’s available in every conversation, which is powerful for complex projects.
When files are referenced in CLAUDE.md, their contents are incorporated into Claude’s baseline understanding of your project. This means:
No repetition: You don’t have to keep referencing the same important files.
Consistent context: Every conversation starts with the same foundation.
Automatic updates: If referenced files change, the context updates automatically.
Team consistency: All team members share the same persistent context.
Add file references to CLAUDE.md using the same @ syntax. For example, a Next.js e-commerce project might include:
## Important Context FilesThe database schema is defined in @prisma/schema.prisma. Reference this for all data modeling questions.Our API conventions are established in @src/lib/apiHelpers.ts. Follow these patterns for all new endpoints.The main configuration file @src/config/app.ts contains environment-specific settings and feature flags.
However, remember that not every file should be in persistent context. Choose files that are frequently referenced, architecturally important, or convention-defining.
How do we diagnose poor responses after setting up CLAUDE.md?
Persistent context is powerful, but too much can overwhelm Claude and slow down responses. When answers don’t seem quite right, the issue is often context-related.
If Claude gives generic advice that doesn’t fit the project, the context is insufficient. Add more persistent file references and project conventions to
CLAUDE.md.If Claude suggests patterns that conflict with existing code, conventions might be missing or outdated. Use
#commands to update coding standards and patterns.If Claude asks for file contents it should already know, persistent file references are missing. Add frequently referenced files to
CLAUDE.mdwith the@syntax.If responses are slow or inconsistent, the context is overloaded. Prune persistent context to the most essential files.
With solid context management in place, we’re ready for what comes next. In upcoming lessons, we’ll explore advanced communication patterns to orchestrate complex, multi-step development tasks. We’ll learn to give Claude sophisticated planning capabilities, control conversation flow for complex debugging sessions, and eventually coordinate multiple AI agents working on different aspects of a codebase.