Every developer who uses Claude Code hits the same wall within the first week: you spend 20 minutes giving Claude context about your project — the architecture, the conventions, the things to never do — and the next day you open a new session and it’s all gone.
Claude doesn’t remember. Every session starts blank.
Except it doesn’t have to. Claude Code has a layered memory system most developers never use, and when you do use it, the experience changes completely. Here’s how to build persistent memory that follows Claude into every project and session.
Why Claude “Forgets” (And What’s Actually Happening)
Claude Code doesn’t have persistent memory between sessions by default. Each conversation starts fresh — no context from what you built yesterday, no awareness of your coding conventions, no memory of the bug you spent three hours on last week.
This isn’t a bug. It’s an architectural choice around context windows and stateless operation. But Claude Code provides an explicit mechanism to work around it: CLAUDE.md files.
The CLAUDE.md Memory System
CLAUDE.md is a special file that Claude Code reads automatically at the start of every session. It’s your persistent memory layer — a place to write things you’d otherwise say out loud every single session.
Claude Code reads CLAUDE.md files from multiple locations, in order:
~/.claude/CLAUDE.md ← personal memory (applies to all projects)
/path/to/project/CLAUDE.md ← project memory (applies to this repo)
/path/to/subdir/CLAUDE.md ← local memory (applies to this directory)
The content from all active CLAUDE.md files is merged. Deeper files can override or extend parent files.
What to Put in CLAUDE.md
The most valuable things to persist in CLAUDE.md are the things you’d have to explain manually every session:
Project-level CLAUDE.md:
# Project Memory
## Architecture
This is a Next.js 15 app with App Router. All pages use server components by default.
API routes live in app/api/. Database access goes through lib/db/ — never import
prisma directly from components.
## Conventions
- TypeScript strict mode — no `any` types
- Error handling: always use Result<T, E> pattern from lib/types
- Tests: Vitest for unit tests, Playwright for E2E. Run `npm test` before committing.
- Environment: local dev uses Docker Compose (`docker compose up`)
## Do Not
- Do NOT use fetch() directly — use our lib/api/client.ts wrapper
- Do NOT commit .env files even test ones
- Do NOT use console.log in production code — use logger from lib/logger
## Current Focus
We're migrating the auth system from JWT to Supabase Auth. Migration is 60% done.
The old JWT middleware is in middleware/jwt-auth.ts — it's being deprecated.
Personal CLAUDE.md (~/.claude/CLAUDE.md):
# My Preferences
## Style
- I prefer functional components over class components
- Favor explicit over implicit — name things clearly even if it's verbose
- Comments: explain WHY, not WHAT
## Workflow
- Always run tests before suggesting I commit
- Ask clarifying questions before refactoring — I like to understand the tradeoffs
- When you find a bug unrelated to what I'm working on, flag it but don't fix it
The personal CLAUDE.md is especially powerful — it’s a way to teach Claude your personal coding style once and have it apply everywhere.
The /memory Command
Claude Code also has a /memory command that manages memory files interactively:
/memory → shows current memory files and their content
/memory add → adds a new memory entry (Claude picks the right file)
/memory edit → opens a memory file for editing
When you tell Claude something you want it to remember, you can follow up with /memory add and Claude will write it to the appropriate CLAUDE.md file automatically. This is the fastest way to build up memory over time — just tell Claude things as you work, and explicitly add the important ones to memory.
For example:
You: Our Stripe webhook secret is read from STRIPE_WEBHOOK_SECRET env var,
never hardcoded. Remember this.
Claude: Got it — I'll always use process.env.STRIPE_WEBHOOK_SECRET.
You: /memory add
Claude: I've added this to your project's CLAUDE.md:
## Payment Processing
- Stripe webhook secret: always from `process.env.STRIPE_WEBHOOK_SECRET`, never hardcoded
- Test webhooks with `stripe listen --forward-to localhost:3000/api/webhooks`
Memory File Types: A Better Taxonomy
For larger projects, a single CLAUDE.md file gets unwieldy. A more structured approach is to create a memory system — multiple files organized by type:
.claude/
memory/
user.md ← who you are and what you prefer
project.md ← current project goals and status
feedback.md ← corrections Claude has made that apply to future work
reference.md ← pointers to external resources (docs, dashboards, tickets)
Each file has a frontmatter header:
---
name: Project Context
description: Current project focus and architecture decisions
type: project
---
We're building a B2B SaaS for construction project management. Main users are
general contractors who aren't technical...
Then your CLAUDE.md acts as an index:
# Memory Index
- [Project Context](.claude/memory/project.md) — current focus and arch decisions
- [My Preferences](.claude/memory/user.md) — coding style and workflow preferences
- [Feedback Log](.claude/memory/feedback.md) — corrections for future sessions
This scales well — each memory type stays focused and readable, Claude can update specific files without touching others, and you can build up months of institutional knowledge that persists across every session.
GraphRAG: Semantic Memory for Large Codebases
CLAUDE.md memory works well for explicit knowledge — things you know matter and write down deliberately. But there’s a second category of memory: the implicit knowledge spread across your entire codebase.
When you ask “how does our auth system work?” — Claude has to read the files fresh every time, re-learning the patterns that are obvious from the code.
GraphRAG (Graph-based Retrieval-Augmented Generation) builds a knowledge graph over your codebase that Claude can query directly. Instead of loading 50 files to answer a question, Claude queries the graph and gets the relevant nodes:
You: What services does our auth module touch?
Claude: [queries knowledge graph]
→ AuthService → UserRepository (read user by email)
→ AuthService → SessionStore (Redis, write session tokens)
→ AuthService → EmailService (send verification emails)
→ AuthService → AuditLog (write authentication events)
This kind of structural memory is impossible to maintain manually — the graph updates automatically as your code changes.
GraphRAG for Claude Code typically involves:
- Indexing your codebase into a graph structure (entities, relationships, patterns)
- A retrieval layer that lets Claude query “give me everything related to X”
- Injection of relevant nodes into each new session’s context
The result is that Claude arrives at every session with real structural knowledge of your codebase — not just what you remembered to write down.
Practical Memory Patterns
Pattern 1: Session Bootstrapping
Start every session with a context refresh:
# Session Start Prompt (save as a skill)
Read .claude/memory/project.md and .claude/memory/feedback.md.
Summarize the current project state in 3 lines, then ask what we're working on today.
Pattern 2: End-of-Session Memory Capture
End sessions by extracting what’s worth persisting:
# Session End Skill
Review our conversation. What decisions did we make that should be remembered
for future sessions? What patterns emerged that should be added to the coding
guidelines? Draft additions to .claude/memory/project.md and .claude/memory/feedback.md.
Pattern 3: Cross-Project Conventions
Use your personal CLAUDE.md (~/.claude/CLAUDE.md) for conventions that apply everywhere — your preferred libraries, your testing philosophy, how you like Claude to communicate. You set it once and it’s active in every project you open.
Pattern 4: Bug Memory
When you fix a tricky bug, add it to memory with context:
## Bug History
### Apr 2026: Race condition in session cleanup
`session.destroy()` is async but wasn't being awaited in the logout handler.
Symptoms: random 401s on subsequent requests from the same user.
Fix: `await session.destroy()` and handle the promise rejection.
Future Claude sessions won’t repeat the same mistake — and if similar symptoms appear, Claude has context to recognize the pattern.
What’s Available in the CS360 Bundle
The Claude Skills 360 full bundle includes pre-built GraphRAG tools and memory management skills:
- GraphRAG indexer — scans your codebase and builds a queryable knowledge graph
- Memory file templates — ready-to-use CLAUDE.md and memory directory structure
- Session start/end skills — automated context loading and end-of-session capture
- Cross-project conventions skill — generates a personalized ~/.claude/CLAUDE.md from a short interview
These are the tools the free starter kit can’t replicate — because persistent memory across complex codebases is a fundamentally different problem than basic skill usage.
If you’re spending time re-explaining your project to Claude every session, the full bundle is the fix.
Getting Started Today
Even before you install any skills, you can start building memory right now:
-
Create
~/.claude/CLAUDE.md— add your personal preferences (coding style, communication style, things to avoid) -
Create
CLAUDE.mdin your main project — add architecture overview, key conventions, and the current focus -
Use
/memory addafter telling Claude something important -
End each big session by asking Claude: “What should I add to CLAUDE.md from our session today?”
The first CLAUDE.md you write takes 15 minutes and pays off immediately. By the end of the week, you’ll have a memory system that makes every session feel like Claude was there yesterday.
Want pre-built memory tools that go further? The Claude Skills 360 bundle starts free — 360 skills for immediate use, GraphRAG tools and advanced memory patterns in the full version.
Related reading: