Ending the "But I Just Told You That" Loop
Every new session, you type the same context again. "This project uses TypeScript." "Run tests with Vitest." "Write commit messages in Japanese." When I first started with Claude Code, I began nearly every session this way. Each instruction takes a minute, but repeating it every time fragments your focus.
It's different now. As an indie developer, I run several sites on Claude Code, and every session starts by automatically loading CLAUDE.md and MEMORY.md. The time spent re-explaining context has dropped to almost nothing, so I get straight to the real work. This article covers the memory system that makes that possible — and how to take your first step with it.
CLAUDE.md — Your Project's Instruction Manual
CLAUDE.md is a configuration file placed at the root of your project directory. Claude Code reads this file automatically when a session starts and follows the instructions it contains.
What to Include in CLAUDE.md
Think of CLAUDE.md as defining "how Claude Code should behave in this project." Here's an effective example:
# Project Overview
Next.js 16 + TypeScript + Tailwind CSS web application.
Deployed on Cloudflare Workers.
# Development Rules
- Use Vitest for testing
- Write commit messages following Conventional Commits
- Use Tailwind utility classes instead of CSS-in-JS
# Directory Structure
- src/app/ — App Router pages
- src/components/ — Shared components
- src/lib/ — Utility functionsIn my experience, the trick to keeping this file alive is not to overload it at the start. Even just the tech stack and directory structure noticeably sharpens Claude's first move. Then, every time you catch yourself re-explaining something, add one line. That slow accumulation is what ends up matching reality best.
File Placement and Priority
Claude Code reads multiple CLAUDE.md files in a hierarchical manner:
~/.claude/CLAUDE.md ← Global settings (shared across all projects)
./CLAUDE.md ← Project root (most common)
./src/CLAUDE.md ← Subdirectory-specific settings
Files deeper in the hierarchy take higher priority. For monorepos where frontend and backend follow different conventions, placing separate CLAUDE.md files in each directory lets Claude automatically switch context based on where you're working.
MEMORY.md — Knowledge Accumulated from Conversations
While CLAUDE.md defines static project rules, MEMORY.md serves as a dynamic knowledge base that grows through your interactions with Claude Code.
Types of Memory
Claude Code organizes memory into four main categories:
| Type | Purpose | Example |
|---|---|---|
user | User profile and preferences | "Senior engineer, 10 years of Go experience" |
feedback | Guidance for Claude's behavior | "Skip the summary at the end" or "Don't mock the database in tests" |
project | Project status and context | "Merge freeze after 3/25 for mobile release" |
reference | Pointers to external resources | "Bugs are tracked in Linear's INGEST project" |
How Memory Gets Saved
When Claude Code detects important information during a conversation, it automatically creates a memory file. For example, if you say "don't mock the database in tests," a file like this gets created:
---
name: feedback_no_mock_db
description: Use real database connections in tests, not mocks
type: feedback
---
Integration tests must use a real database, not mocks.
**Why:** A previous incident where mock/production divergence masked a broken migration.
**How to apply:** When writing integration tests, always connect to a real database instance.This information is indexed in MEMORY.md and automatically referenced in future sessions. Keep one fact per file and preserve the reasoning in the **Why:** line — when you reread it later, you won't misremember why the instruction existed in the first place.
Getting Started with Memory Management
Step 1: Create Your CLAUDE.md
Run this in your project root:
# Create CLAUDE.md
cat << 'MEMO' > CLAUDE.md
# Project Settings
## Tech Stack
- Next.js 16 (App Router) + TypeScript
- Package manager: pnpm
- Testing: Vitest + Testing Library
## Coding Conventions
- Functional components only (no class components)
- Prefer named exports over default exports
- Follow Conventional Commits for commit messages
MEMO
echo "✅ CLAUDE.md created"
# Output: ✅ CLAUDE.md createdStep 2: Watch Memory Accumulate
During your conversations with Claude Code, share your preferences naturally:
You: When writing tests, use Japanese for describe block labels.
Claude: Got it. I'll write test describe blocks in Japanese going forward.
(→ Automatically saved to memory)
Check your saved memories in the .auto-memory/ directory:
# List memory files
ls .auto-memory/
# Example output:
# MEMORY.md
# feedback_test_describe_japanese.md
# user_profile.mdStep 3: Review the Memory Index
MEMORY.md contains links to all saved memory files:
cat .auto-memory/MEMORY.md
# Example output:
# # Memory Index
# ## Feedback
# - [feedback_test_describe_japanese.md] — Write test describe blocks in JapaneseLessons From Actual Use: Keeping Memory From Going Stale
Knowing how the system works and keeping it in a shape you can live with long-term are two different skills. Here, honestly, are the operating habits I picked up the hard way while running memory across several projects — the practical instincts you won't find in the official docs.
First, write exactly one fact per file. Pack several topics into one file and you'll agonize, when one goes out of date, over whether to delete or keep the whole thing. Keep the grains small and you can surgically remove only the wrong memory.
Second, let MEMORY.md be nothing but an index. It's tempting to write the facts themselves here, but a bloated index makes loading heavy. Hold each entry to a one-line link plus a few words, and push the substance out to individual files. The leaner the index, the faster you can pull the right memory into reach.
Third, put the most important facts first. Auto-loading doesn't always deliver the entire file intact; when it grows long, the top gets priority. Put the conventions you want enforced constantly near the top, and rarely-referenced notes lower down. That reordering alone makes the effect more consistent.
Fourth, verify old memories before you act on them. A memory saying "this file uses A" may linger long after a refactor removed A. A memory is only ever "what was true when it was written." Before relying on any memory that names a file, function, or flag, confirm it still exists. Make that a habit and you'll get far fewer suggestions anchored to stale assumptions.
Finally, loosely link related memories inline, such as [[filename]], so you can trace connected notes later. It's fine to link to a memory that doesn't exist yet — it works as a sticky note for "something worth writing down eventually."
Wrapping Up — Memory Management Is the Key to Claude Code Productivity
Claude Code's memory system is the foundation for continuously improving your AI collaboration. By documenting project rules in CLAUDE.md and letting MEMORY.md accumulate knowledge from conversations, Claude's responses become more accurate with every session. More than the mechanism itself, it's the habit of tending memory so it doesn't rot that makes the biggest difference.
Start today by creating a single CLAUDE.md in your current project. Even just documenting your tech stack and directory structure makes a noticeable difference. Use it for a week, and the moment you notice yourself re-explaining something, add that one line. That repetition is what grows it into the memory that fits your own hands best.
Thank you for reading — I hope it helps with your own setup.