The Cartographer · 12 min mission
GEMINI.md: Gemini CLI's Context & Memory Layer
Master the GEMINI.md hierarchy, @-imports, and the /memory command — then compare it honestly to CLAUDE.md and AGENTS.md.
On this page
GEMINI.md is Gemini CLI's persistent instruction layer: plain-Markdown files the CLI discovers across a hierarchy, concatenates in order, and prepends to every prompt. After this guide you can place context files at the right tier, split them with @-imports, and use /memory to inspect, reload, and verify exactly what loaded. Scoped to Gemini CLI v0.46.0 (released 2026-06-10).
The three-tier hierarchy
The spec: the CLI "loads various context files from several locations, concatenates the contents of all found files, and sends them to the model with every prompt." Files load and concatenate in tier order — broad to specific.
| Tier | Location | When it loads | Scope |
|---|---|---|---|
| 1. Global | ~/.gemini/GEMINI.md | Always | Default instructions for all projects |
| 2. Workspace | ./GEMINI.md + parent dirs | At launch (walks up through parents) | The current project(s) |
| 3. JIT (just-in-time) | ./src/payments/GEMINI.md etc. | When a tool touches that dir or an ancestor (up to a trusted root) | Per-component rules; no context cost until reached |
How files appear in the assembled prompt
The CLI does not silently glue files together — it wraps each one in explicit boundary markers so the model can tell where each instruction came from. Verified in the v0.46.0 source (concatenateInstructions() in memoryDiscovery.ts), every file is bracketed as below.
--- Context from: /Users/you/.gemini/GEMINI.md ---
Always prefer const over let. Use 2-space indentation.
--- End of Context from: /Users/you/.gemini/GEMINI.md ---
--- Context from: ./GEMINI.md ---
This repo uses pnpm. Run `pnpm test` before claiming done.
--- End of Context from: ./GEMINI.md ---Split a file with @-path imports
The Memory Import Processor breaks one fat GEMINI.md into modules. Write @ followed by a path; both relative and absolute paths resolve.
| Syntax | Resolves to |
|---|---|
@./instructions.md | A file in the same directory |
@../shared.md | A file in the parent directory |
@./components/ui.md | A file in a subdirectory |
@/absolute/path/to/file.md | An absolute path anywhere on disk |
| Mechanic | Behavior | Exact marker / default |
|---|---|---|
| Successful import | Wrapped inline with provenance comments | <!-- Imported from: <path> --> … <!-- End of import from: <path> --> |
| Nested imports | Allowed — an imported file may import others | Bounded by max depth |
| Max import depth | Stops processing past the limit | 5 — emits Maximum import depth (5) reached. Stopping import processing. |
| Circular import | Detected and neutralized, not errored | <!-- File already processed: <path> --> |
| Path traversal | Escapes from allowed dirs are blocked | <!-- Import failed: <path> - Path traversal attempt --> |
| Missing file | Fails gracefully inline, no crash | <!-- Import failed: <path> - <message> --> |
| Code regions | marked parser skips @ inside fences / inline code | Put the syntax in a code fence to document it without firing |
| Import format | context.importFormat controls tree vs flat output | tree | flat, defaults to tree |
Assemble a GEMINI.md hierarchy and watch it resolve
Build your GEMINI.md
Toggle what your repo needs — the file on the right rewrites itself as you click. It is the Gemini CLI's context file: plain Markdown grouped under ## headings, a commands table, zero fluff — the same shape the CLI concatenates into every prompt.
Project overview
The first thing Gemini reads — say what the repo is in one line.
Tech stack
Naming the stack stops Gemini from guessing your toolchain.
Build & test commands
Commands save Gemini from guessing your scripts. Clear a field to drop it.
Conventions
House rules written once here beat repeating them in every prompt.
Do not touch
Fence off the places where an eager edit does damage.
Inspect and reload with /memory
/memory ("Commands for interacting with memory") shows what loaded and forces a re-scan after edits. Verified against memoryCommand.ts at tag v0.46.0, it exposes exactly these subcommands — and not /memory add, which several cheat-sheets wrongly list.
| Subcommand | What it does |
|---|---|
/memory show | Displays the full, concatenated hierarchical memory — the exact instructional context sent to the model |
/memory reload | Re-scans and reloads every GEMINI.md from all configured locations. Alias: `/memory refresh` |
/memory list | Lists the paths of the GEMINI.md files in use (the hierarchy, not the contents) |
/memory inbox | Opens the Auto Memory review dialog — a *separate* experimental feature, not GEMINI.md editing |
GEMINI.md vs CLAUDE.md vs AGENTS.md
All three are a Markdown briefing the agent reads up front — context, not enforcement: instructions the model tries to follow, not rules it is forced to obey. The mechanics differ in ways that matter when running more than one agent across a repo. Do not assume one number (e.g. import depth) applies to all three.
| Dimension | GEMINI.md | CLAUDE.md | AGENTS.md |
|---|---|---|---|
| Default filename | GEMINI.md | CLAUDE.md (+ CLAUDE.local.md) | AGENTS.md |
| Global/user file | ~/.gemini/GEMINI.md | ~/.claude/CLAUDE.md | n/a — per-repo format |
| Hierarchy | global → workspace + parents → JIT subdir scan, stops at .git | ancestors loaded in full at launch; subdir files load on demand | nested files in subprojects; nearest file wins |
@-imports | Yes — relative + absolute, nested, cycle-safe, max depth 5 | Yes — relative + absolute, recursive, max depth 4 | No import syntax — modularity via nested files only |
| Inspect command | /memory show, /memory list | /memory (lists loaded files, opens them) | tool-dependent |
| Reload command | /memory reload (alias refresh) | no dedicated reload; /compact re-injects the root file | tool-dependent |
| "Remember this" | natural-language ask → agent edits the right tier (no `/memory add`) | natural-language ask → separate auto-memory store, or "add to CLAUDE.md" | n/a |
| Reads the others? | Can read `AGENTS.md` — set context.fileName to include it | reads only `CLAUDE.md` — import or symlink to use AGENTS.md | the neutral format many tools adopt |
AGENTS.md interop
Gemini CLI + AGENTS.md
Set context.fileName to AGENTS.md (or list it alongside GEMINI.md) and the CLI loads it as-is — no symlink, no import. One settings line joins a team already standardized on the cross-tool AGENTS.md.
Claude Code + AGENTS.md
Claude Code reads only CLAUDE.md. To honor an AGENTS.md, @AGENTS.md-import it from your CLAUDE.md, or symlink CLAUDE.md → AGENTS.md. And AGENTS.md itself has no @-import mechanism — its modularity comes from nested files where the closest one wins.
Knowledge check
You edit `./GEMINI.md` to add "use pnpm, never npm" while a Gemini CLI session is already running, but the agent keeps reaching for npm. What is the correct fix?
Reach the end and this star joins your charted sky.