DEV Community

Sangmin Lee
Sangmin Lee

Posted on • Originally published at claudeguide.io

Context Engineering for Claude: How to Train It on Your Codebase

Originally published at claudeguide.io/context-engineering-claude

Context Engineering for Claude: How to Train It on Your Codebase

Context engineering is the practice of deliberately structuring what Claude sees in its context window — not just what you ask, but what background information Claude has when it answers in 2026. For Claude Code, this means curating CLAUDE.md, using @file references strategically, and loading the right architectural context before asking for implementation. Done well, it eliminates the "Claude doesn't understand my codebase" problem entirely.


Why Context Engineering Matters More Than Prompt Engineering

Most developers focus on how they phrase requests. Context engineering focuses on what Claude already knows before you ask.

Without context engineering:

You: "Add pagination to the user list endpoint"
Claude: "I'll use an offset-based approach. Here's the implementation..."
[Uses wrong DB library, ignores your existing pagination pattern, generates type errors]
Enter fullscreen mode Exit fullscreen mode

With context engineering:

CLAUDE.md includes:
- "Use cursor-based pagination (not offset) — see lib/db/pagination.ts for the pattern"
- "All list endpoints follow the pattern in app/api/items/route.ts"

You: "Add pagination to the user list endpoint"
Claude: "I'll use cursor-based pagination consistent with your existing pattern..."
[Generates code that matches your conventions perfectly]
Enter fullscreen mode Exit fullscreen mode

The difference isn't the request — it's what Claude already knows.


Layer 1: CLAUDE.md — The Persistent Context Layer

CLAUDE.md is loaded automatically every time Claude Code starts in your project. It's your primary context engineering tool.

What belongs in CLAUDE.md

High-value content:

  1. Architecture decisions — not just what was chosen but why
  2. Conventions and anti-patterns — the exact things Claude gets wrong without guidance
  3. Key file map — where to find important patterns
  4. Domain vocabulary — project-specific terms and their meanings

Low-value content (skip these):

  • Technology descriptions Claude already knows (e.g., "we use TypeScript")
  • General best practices (e.g., "write clean code")
  • Things that are obvious from the code itself

High-signal CLAUDE.md example

# Project Context

## Architecture
This is a multi-tenant SaaS. Every DB query MUST filter by `organizationId`.
Forgetting this causes cross-tenant data leaks. Before writing any DB query,
check: does it include `.where(eq(schema.table.organizationId, ctx.organizationId))`?

## Key Patterns (read these before implementing anything similar)
- Auth: middleware.ts — how session validation works
- DB queries: lib/db/queries/users.ts — the pattern all queries follow
- Server actions: app/actions/projects.ts — the validation + mutation pattern
- Error handling: lib/errors.ts — our custom error types and how to throw them

## Domain Vocabulary
- "workspace" = an organization account (not a personal workspace)
- "member" = a user within a workspace (User is the auth identity)
- "resource" = any workspace-owned entity (projects, templates, etc.)

## Anti-patterns (Never Do This)
- Never use `userId` directly in DB queries — always go through `organizationId` first
- Never return raw DB errors to the client — use our `AppError` class
- Never add `"use client"` to a component that doesn't need browser APIs
- Never skip the `bun run typecheck` step before saying a task is complete
Enter fullscreen mode Exit fullscreen mode

Layer 2: @file References — Targeted Context Loading

During a session, use @filename to load specific files into context before complex tasks.

Pattern: Reference-before-implement

@lib/db/queries/users.ts @lib/db/schema.ts

Now implement a query function that returns all active projects for an organization,
sorted by lastModifiedAt descending, with pagination using the same cursor pattern.
Enter fullscreen mode Exit fullscreen mode

This ensures Claude sees the exact patterns you want replicated before it writes any code.

Pattern: Error-plus-context

This error is happening:
[paste error]

@app/api/webhooks/route.ts @lib/stripe/webhook-handlers.ts

What's causing this and how do I fix it?
Enter fullscreen mode Exit fullscreen mode

Loading the relevant files alongside the error gives Claude the context to diagnose precisely rather than guess.

Which files to reference

Situation Files to reference
Adding a new API endpoint Existing endpoint of same type
Adding a new DB query schema.ts + existing query of same type
Debugging an error File with error + direct dependencies
Adding a new component Similar existing component
Writing tests Test file for similar functionality

Layer 3: Project Summary Files

For large codebases, maintaining ARCHITECTURE.md and DECISIONS.md as separate files that you reference on complex tasks.

ARCHITECTURE.md structure

# Architecture Overview

## System Diagram
[ASCII or text description of how services connect]

## Request Flow
1. Client → Vercel Edge → Next.js middleware (auth check)
2. Middleware → App Router page/route
3. Route → Server Action → Drizzle query → Neon DB
4. Response → Server Component render → Client

## Key Invariants
- All mutations go through Server Actions (no direct DB calls from components)
- Session validation happens in middleware — routes assume valid session
- Billing gates are checked in Server Actions, not middleware

## Bounded Contexts
- Auth: handled entirely by Clerk (we don't touch auth logic)
- Billing: Stripe webhooks → our DB (never call Stripe from frontend)
- Email: Resend SDK called from server actions only
Enter fullscreen mode Exit fullscreen mode

DECISIONS.md — the "why" record

# Architecture Decisions

## 2026-02-01: Cursor-based pagination instead of offset
**Why**: Offset pagination is O(n) — scanning all rows before the offset.
At 100k+ records, page 500 becomes unacceptably slow.
Cursor pagination is O(1) regardless of dataset size.
**Trade-off**: You can't jump to an arbitrary page number.
**Implementation**: lib/db/pagination.ts

## 2026-03-15: Drizzle over Prisma
**Why**: Drizzle SQL stays closer to actual queries — easier to optimize.
Prisma's abstraction hides performance issues until production.
**Trade-off**: More verbose queries, no automatic cascade handling.
Enter fullscreen mode Exit fullscreen mode

Reference these in complex tasks:

@ARCHITECTURE.md @DECISIONS.md

I need to add real-time presence indicators (show who's online in a workspace).
How should I implement this given our architecture? What are the trade-offs?
Enter fullscreen mode Exit fullscreen mode

Layer 4: Dynamic Context Injection

For automated or programmatic Claude usage, inject context programmatically.

Python: Injecting relevant file contents


python
import anthropic
from pathlib import Path

client = anthropic.Anthropic()


def load_context_files(*paths: str) -

[→ Get Power Prompts 300 — $29](https://shoutfirst.gumroad.com/l/agfda?utm_source=claudeguide&utm_medium=article&utm_campaign=context-engineering-claude)

*30-day money-back guarantee. Instant download.*
Enter fullscreen mode Exit fullscreen mode

Top comments (0)