Skip to content

AI CODING ASSISTANTS

Claude Code Init Command: What /init Actually Writes

We ran the claude code init command across seven repositories. It recovers 11 of our CLAUDE.md's 28 rules — and none of the 9 that came from an incident.

The claude code init command reads your repository and writes a CLAUDE.md at the project root — build and test commands, then the architecture that takes several files to piece together. We ran it seven times on 2026-09-04 against Claude Code 2.1.260: four repository shapes, two models, one repeat, and one run against this site's own 433-file repository with its hand-written CLAUDE.md removed. It produced a usable file in six of the seven. It also recovered 11 of the 28 rules our own file carries, and none of the nine that exist because something broke once.

Key takeaways

  • /init is a built-in prompt command (type:"prompt", source:"builtin"), not a skill — the same bytes are in 2.1.259, which means an article we published yesterday was wrong.
  • On a 7-file TypeScript project it costs 9 turns, 33 seconds and $0.0484; on a 433-file site, 21 turns, 107 seconds and $0.3727.
  • It does not need git, but it costs 34% more without it — 18 turns instead of 9 for identical files.
  • Two identical runs wrote files 40% apart in size (1,678 then 2,355 bytes), so the output is a draft, not a derivation.
  • On this site it recovered 11 of 28 rules, all of them derivable from code or config. The nine that came from an incident or an operating procedure: zero.

The short answer

Run it once, in a repository that already has a README and a package.json, and treat the result as the discoverable half of a CLAUDE.md — the half the complete Claude Code guide would tell you to expect from a generator. Then write the other half yourself, because that is the half Anthropic's memory documentation is describing when it talks about project instructions, and it is the half no reader of your repository can reconstruct.

Terminal
claude -p "/init" --permission-mode acceptEdits
# → 9 turns, 33s, $0.0484 on a 7-file TypeScript CLI
# → writes ./CLAUDE.md, 1,678 bytes

Print mode cannot answer a permission prompt, so --permission-mode acceptEdits is what lets a command whose entire job is writing a file actually write it — the flag is documented in Anthropic's CLI reference. Inside an interactive session you just type /init and approve the write.

Seven /init runs compared against a hand-written CLAUDE.md, with the rules it recovered and missed
Seven runs on Claude Code 2.1.260, 2026-09-04.

What /init actually is

It is a built-in prompt command. The registration in the 2.1.260 binary reads:

claude.exe, offset 189,690,758
{type:"prompt",name:"init",
 get description(){return a.CLAUDE_CODE_NEW_INIT
   ? "Initialize new CLAUDE.md file(s) and optional skills/hooks with codebase documentation"
   : "Initialize a new CLAUDE.md file with codebase documentation"},
 contentLength:0,progressMessage:"analyzing your codebase",source:"builtin"}

Three things fall out of that. source:"builtin" means it is not a skill — it ships in the binary rather than being discovered from your settings, and /skill-doctor on this machine lists 32 skills without it, and it does not appear in the commands reference as one either. type:"prompt" means there is no code behind it: the command expands to a block of instructions and the model does the rest with ordinary Read, Glob and Grep calls, which is why the cost scales with your repository rather than with the command.

And there is a second /init behind an environment variable. With CLAUDE_CODE_NEW_INIT set, the description changes to "Initialize new CLAUDE.md file(s) and optional skills/hooks", and the prompt behind it is a different, interactive one — it checks for an existing file, then uses AskUserQuestion to ask what you want set up before writing anything. Everything measured below is the default path.

The instructions it runs on

The prompt is static text in the binary, so it is worth reading once — every judgement call the command makes is in here. It asks for exactly two things: commands (build, lint, test, and how to run a single test) and high-level architecture that requires reading multiple files to understand. Then nine usage notes constrain it:

InstructionEffect on the output
Suggest improvements if a CLAUDE.md existsYour rules survive a re-run
No obvious instructions, no generic practicesNo "write unit tests" filler
Avoid listing every component or fileNo directory dump
Fold in Cursor and Copilot rules if present.cursorrules, .github/copilot-instructions.md
Fold in the important parts of README.mdYour README is the strongest input
Do not invent "Common Development Tasks"No fabricated sections
Prefix the file with a fixed two-line headerEvery file we got carried it

That last one is testable, and it held: all six files that were written start with the mandated header, byte for byte. The "fold in the README" note is the one that decides output quality — the repositories where /init produced something worth keeping are the ones that had a README worth reading.

Seven runs, one file each

Every row is one process: claude -p "/init" --permission-mode acceptEdits --output-format json, with the cost and turn count read out of the result envelope rather than estimated.

Repository shapeModelTurnsCostBytes written
Empty git repository, no fileshaiku2$0.0240none
7-file TypeScript CLI, committedhaiku9$0.04841,678
The same repository, run againhaiku13$0.04012,355
The same repositorysonnet10$0.12761,262
The same files, no githaiku18$0.06491,979
The same repository, CLAUDE.md presenthaiku10$0.04941,462
This site: 433 files, 9.5 MBsonnet21$0.37277,548

An empty repository gets nothing. Two turns, eight cents of a cent, and a reply that lists what it would need — source files, a config file, a README — and asks whether you want to add them first. It does not write a placeholder, which is the right call and worth knowing before you script it.

It does not need git. The same files with the .git directory removed still produced a CLAUDE.md, but it took 18 turns instead of 9 and cost 34% more, because a repository hands over its file list in one call and a bare directory has to be walked.

Two identical runs disagree. Same repository, same model, same prompt, nothing changed in between: 1,678 bytes with four ## sections, then 2,355 bytes with seven. That is a 40% spread on a file whose whole purpose is to be stable, and it is the strongest argument in this article for treating the output as a first draft.

The stronger model wrote the shorter file. Sonnet produced 1,262 bytes for 2.6× the price of haiku's 1,678 — no "Input Format" section, no restating of the tech stack that package.json already declares. Shorter is the right direction here: CLAUDE.md length has a measured cost on every single request.

When a CLAUDE.md already exists

We seeded the same TypeScript repository with a four-line CLAUDE.md containing two real project rules and a marker string, then ran /init again:

CLAUDE.md, before
# ledger-cli

Run `npm test` before every commit. Do not add a second runtime dependency
without asking; the binary is shipped to machines with no network.

MARKER-KEEP-THIS-LINE

The file came back rewritten at 1,462 bytes — the mandated header, an architecture section, a commands section — with both rules restated under a Key Constraints heading and the marker line still sitting at the bottom. So the "suggest improvements" instruction is honoured in the strong sense: it does not merge into your file, it writes a new one that contains your file's claims.

The rule audit: 11 of 28

The interesting test is not a toy repository. This site has a hand-written CLAUDE.md, 8,377 bytes, that has been edited every time something bit us. So we copied the repository without .git, node_modules, .next and CLAUDE.md — 433 files, 9.5 MB — and ran /init on the copy.

It produced 7,548 bytes in 21 turns for $0.3727, and it is genuinely good: it found the D1 chokepoint, the rehype-slug anchor trap, the reason react/jsx-no-comment-textnodes is disabled, and the sentence "middleware is UX only, not the security boundary". Then we listed the 28 distinct rules the hand-written file carries and checked each one against the generated file.

Rule classIn the hand-written fileRecovered by /init
Derivable from code or config1911
An operating procedure or a remembered incident90

Every rule it recovered is one a careful reader could have derived from lib/d1.ts, eslint.config.mjs, app/globals.css or a component. Every rule it missed in the second class is one that only exists because of something that happened:

  • Never run a build while the dev server is running — they share .next, and every route starts returning 500, which looks exactly like an application bug.
  • EPERM on .next/trace means a node process is still alive.
  • Every article ships with a cover; draft: false without one is not a valid state. That rule cost nine articles before it was written down.
  • The parent directory must never be a git repository. It was once, for a day, and recorded this repository as a gitlink instead of files.
  • Secrets live in .env, not .env.local, on this machine — a line that was wrong in the file for three weeks.

Nothing in the repository states any of that, because a repository records what the code does, not what it did to you. /init is a very good reader. It is not a witness. That gap is also why Claude Code sometimes ignores instructions that were never written down in the first place.

A correction we owe

Our slash commands census, published on 2026-09-03, answers the question "Is /init still a slash command?" with "Yes, but it is a skill rather than a built-in in 2.1.259, which is why it takes arguments and can be chained." That is wrong.

We checked both binaries — the 2.1.260 build on this machine and the 2.1.259 build still sitting beside it as claude.exe.old — and the registration is byte-identical in both: type:"prompt", source:"builtin". It was not a skill when that sentence was published. The FAQ answer has been corrected and that article's updatedIso bumped in the same change that shipped this one.

This is the third published error on this site found by an instrument rather than by a reader, and the pattern is consistent: the claims that break are the ones asserted from a plausible mental model instead of measured. A command reference has a half-life; a claim about how a command is implemented has a shorter one.

How to run the claude code init command well

The claude code init command is worth about five minutes of setup before you run it, because its inputs are the only lever you have.

  • Write the README first. It is the single strongest input the prompt names. A repository with a good README gets a good CLAUDE.md; a repository with a stub gets architecture guessed from filenames.
  • Run it in a repository, not a folder. Half the turns and a third less money for the same output.
  • Run it on a clean tree and diff the result. Especially on the second and later runs.
  • Then delete half of it. Anything package.json already says — the dependency list, the script names — costs tokens on every request and tells the model nothing it cannot read. The structure that actually works is shorter than what you get back.
  • Add the incidents by hand. One line per thing that has broken. That is the part with the payoff, and it is the part /init structurally cannot write.

What did not work

The empty-repository run was supposed to test the fallback and instead tested nothing. We expected a skeleton file with placeholder sections. There is no skeleton: /init reads the directory, finds nothing, explains what it would need, and asks a question. In print mode that question goes nowhere, the process exits 0 having written no file, and a script that checks only the exit code would record a success. That is the same failure shape as a review command that finds nothing because it was pointed at the wrong range.

Our first cost comparison between models was meaningless and we nearly published it. Haiku's run cost $0.0484 and sonnet's cost $0.1276, and the obvious sentence is "sonnet costs 2.6× more to run /init". But sonnet also used 10 turns to haiku's 9 and wrote a shorter file, so per-unit-of-output the comparison inverts, and neither figure survives a different repository. The cost column in the table above is what those seven runs cost on this hardware on one day. It is not a price list.

We could not measure what /init read. The turn count is a proxy for exploration and a bad one — a turn can be a 30-line Read or a repository-wide Grep. Which files fed the generated CLAUDE.md, and in what proportion, is the measurement that would actually explain the 11-of-28 result, and this method cannot produce it.

Best practices

  • Run the claude code init command once, not as a habit. It rewrites the whole file, so a second run costs you every hand-edit you have not re-defended.
  • Treat the output as a draft with a deadline. Edit it the same day, while you still remember what it left out.
  • Run it after a significant refactor, not on a schedule. The architecture section is the part that goes stale, and a re-run rewrites the whole file.
  • Keep the mandated header. It is what other tooling looks for, and every generated file has it.
  • Pair it with the rest of your configuration. /init writes one file; settings.json precedence decides which of your other files win.
  • Version the result. Commit the generated CLAUDE.md on its own so the first hand-edit is a readable diff.

Common mistakes

  • Running it in an empty repository and expecting a template. You get a question instead, and in a script you get silence.
  • Believing the second run reproduces the first. Ours differed by 40% in size on an unchanged repository.
  • Leaving the tech-stack section in. It restates package.json on every request forever.
  • Assuming it is a skill because it takes arguments. We made this mistake in print. It is a built-in prompt, and knowing that is what tells you it cannot be overridden by a file in .claude/skills/.
  • Running it on a dirty working tree. The rewrite lands on top of uncommitted edits to a file you may care about.

Conclusion

Run /init once per repository, early, with a good README in place, and budget five cents and forty seconds for anything small. Then spend twenty minutes deleting what package.json already says and adding the things that have gone wrong — that is where the 17 rules it missed live, and it is the whole difference between a file that describes your repository and one that protects it. If you are writing that second half from scratch, our CLAUDE.md setup guide is the structure we actually run, and the command reference covers the flags that sit beside this one.

Frequently asked questions

What does the Claude Code init command do?
It reads your repository and writes a CLAUDE.md at the project root containing the commands you build, lint and test with, plus the architecture that needs several files to understand. It is a built-in prompt command, so the model does the work with ordinary Read, Glob and Grep calls. On a 7-file TypeScript project it took 9 turns, 33 seconds and about five cents.
Does /init overwrite an existing CLAUDE.md?
It rewrites the file, but it carries your rules across. We seeded a repository with a four-line CLAUDE.md holding two project rules and a marker string, ran /init, and got a longer file back with both rules restated under their own heading and the marker line intact. Commit before running it anyway — a rewrite is a rewrite.
Do I need a git repository to run /init?
No. We ran it in a directory with the same files and no .git and it wrote a 1,979-byte CLAUDE.md. It costs more without git: 18 turns and $0.0649 against 9 turns and $0.0484 for the identical files in a repository, because it explores the tree by hand instead of asking git for the file list.
Is /init a skill in Claude Code?
No. In the 2.1.260 binary it is registered as type "prompt" with source "builtin", and the same bytes are in 2.1.259. Skills are listed by /skill-doctor and /init is not among them. /security-review is a bundled plugin command and /code-review is code-backed, so three commands that look identical at the prompt have three different implementations.
Is the CLAUDE.md that /init writes good enough to keep?
As a starting point, yes. As a finished file, no. On this site's repository it recovered 11 of the 28 rules our hand-written CLAUDE.md carries, and every one of the 11 is derivable from a config file or a component. All 9 rules that exist because something broke once — the ones that actually save time — were missing.

Muhammad Kashif

Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.