Minimal AI coding agent (~1300 LoC) inspired by Claude Code. Works with any LLM.
Project description
NanoCoder
中文 | English | Claude Code Architecture Deep Dive (7 articles)
512,000 lines of TypeScript → 1,300 lines of Python.
I spent a weekend reverse-engineering the leaked Claude Code source — all half a million lines. Then I stripped it down to the load-bearing walls and rebuilt them in Python. The result: every key architectural pattern from Claude Code, in a codebase you can read in one sitting.
NanoCoder is not another AI coding tool. It's a blueprint — the nanoGPT of coding agents. Read it, fork it, build your own.
$ nanocoder -m kimi-k2.5
You > read main.py and fix the broken import
> read_file(file_path='main.py')
> edit_file(file_path='main.py', ...)
--- a/main.py
+++ b/main.py
@@ -1 +1 @@
-from utils import halper
+from utils import helper
Fixed: halper → helper.
What You Get
Claude Code's 512K lines distilled to 7 patterns that actually matter:
| Pattern | Claude Code | NanoCoder |
|---|---|---|
| Search-and-replace editing (unique match + diff) | FileEditTool | tools/edit.py — 70 lines |
| Parallel tool execution | StreamingToolExecutor (530 lines) | agent.py — ThreadPool |
| 3-layer context compression | HISTORY_SNIP → Microcompact → CONTEXT_COLLAPSE | context.py — 145 lines |
| Sub-agent with isolated context | AgentTool (1,397 lines) | tools/agent.py — 50 lines |
| Dangerous command blocking | BashTool (1,143 lines) | tools/bash.py — 95 lines |
| Session persistence | QueryEngine (1,295 lines) | session.py — 65 lines |
| Dynamic system prompt | prompts.ts (914 lines) | prompt.py — 35 lines |
Every pattern is a real, runnable implementation — not a diagram or a blog post.
Install
pip install nanocoderagent
Pick your model — any OpenAI-compatible API works:
# Kimi K2.5
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://api.moonshot.ai/v1
nanocoder -m kimi-k2.5
# Claude Opus 4.6 (via OpenRouter)
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://openrouter.ai/api/v1
nanocoder -m anthropic/claude-opus-4-6
# OpenAI GPT-5
export OPENAI_API_KEY=sk-...
nanocoder -m gpt-5
# DeepSeek V3
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://api.deepseek.com
nanocoder -m deepseek-chat
# Qwen 3.5
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
nanocoder -m qwen-max
# Ollama (local)
export OPENAI_API_KEY=ollama OPENAI_BASE_URL=http://localhost:11434/v1
nanocoder -m qwen3:32b
# One-shot mode
nanocoder -p "add error handling to parse_config()"
Architecture
The whole thing fits in your head:
nanocoder/
├── cli.py REPL + commands 160 lines
├── agent.py Agent loop + parallel tools 120 lines
├── llm.py Streaming client + retry 150 lines
├── context.py 3-layer compression 145 lines
├── session.py Save/resume 65 lines
├── prompt.py System prompt 35 lines
├── config.py Env config 30 lines
└── tools/
├── bash.py Shell + safety + cd tracking 95 lines
├── edit.py Search-replace + diff 70 lines
├── read.py File reading 40 lines
├── write.py File writing 30 lines
├── glob_tool.py File search 35 lines
├── grep.py Content search 65 lines
└── agent.py Sub-agent spawning 50 lines
Use as a Library
from nanocoder import Agent, LLM
llm = LLM(model="kimi-k2.5", api_key="your-key", base_url="https://api.moonshot.ai/v1")
agent = Agent(llm=llm)
response = agent.chat("find all TODO comments in this project and list them")
Add Your Own Tools (~20 lines)
from nanocoder.tools.base import Tool
class HttpTool(Tool):
name = "http"
description = "Fetch a URL."
parameters = {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}
def execute(self, url: str) -> str:
import urllib.request
return urllib.request.urlopen(url).read().decode()[:5000]
Commands
/model <name> Switch model mid-conversation
/compact Compress context (like Claude Code's /compact)
/tokens Token usage
/save Save session to disk
/sessions List saved sessions
/reset Clear history
quit Exit
How It Compares
| Claude Code | Claw-Code | Aider | NanoCoder | |
|---|---|---|---|---|
| Code | 512K lines (closed) | 100K+ lines | 50K+ lines | 1,300 lines |
| Models | Anthropic only | Multi | Multi | Any OpenAI-compatible |
| Readable? | No | Hard | Medium | One afternoon |
| Purpose | Use it | Use it | Use it | Understand it, build yours |
The Deep Dive
I wrote 7 articles breaking down Claude Code's architecture — the agent loop, tool system, context compression, streaming executor, multi-agent, and 44 hidden feature flags. If you want to understand why NanoCoder is designed this way, start there.
License
MIT. Fork it, learn from it, ship something better. A mention of this project is appreciated.
Built by Yufeng He · Agentic AI Researcher @ Moonshot AI (Kimi)
Claude Code Source Analysis — 170K+ reads, 6000 bookmarks on Zhihu
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nanocoderagent-0.1.0.tar.gz.
File metadata
- Download URL: nanocoderagent-0.1.0.tar.gz
- Upload date:
- Size: 56.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f60deff7b1adae7e94ccdf13eec46bf926f4f9ce08dea6ba9053bdb4bbed81f
|
|
| MD5 |
0e9e9e853a84b3f9b2b9fe9c63b80e93
|
|
| BLAKE2b-256 |
f1ff16b02768acc919bcd707a99249da4575934eb17382de9c62d125300c18a8
|
Provenance
The following attestation bundles were made for nanocoderagent-0.1.0.tar.gz:
Publisher:
publish.yml on he-yufeng/NanoCoder
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nanocoderagent-0.1.0.tar.gz -
Subject digest:
6f60deff7b1adae7e94ccdf13eec46bf926f4f9ce08dea6ba9053bdb4bbed81f - Sigstore transparency entry: 1212251139
- Sigstore integration time:
-
Permalink:
he-yufeng/NanoCoder@156ac5ba43f7f2e768472fd92b5e9738af577317 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/he-yufeng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@156ac5ba43f7f2e768472fd92b5e9738af577317 -
Trigger Event:
release
-
Statement type:
File details
Details for the file nanocoderagent-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nanocoderagent-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f766711ee5d83157a77620613d4046e9c85b68f4ba310af0183e0462a67f3d5c
|
|
| MD5 |
a933c7edce64a0e687d0317a2cdbf614
|
|
| BLAKE2b-256 |
5c32422e78a0d846008b89f34e16b42cf3bce6f68bfb290e3491ba7ee6c43ac7
|
Provenance
The following attestation bundles were made for nanocoderagent-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on he-yufeng/NanoCoder
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nanocoderagent-0.1.0-py3-none-any.whl -
Subject digest:
f766711ee5d83157a77620613d4046e9c85b68f4ba310af0183e0462a67f3d5c - Sigstore transparency entry: 1212251204
- Sigstore integration time:
-
Permalink:
he-yufeng/NanoCoder@156ac5ba43f7f2e768472fd92b5e9738af577317 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/he-yufeng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@156ac5ba43f7f2e768472fd92b5e9738af577317 -
Trigger Event:
release
-
Statement type: