Skip to main content

Minimal AI coding agent (~1300 LoC) inspired by Claude Code. Works with any LLM.

Project description

NanoCoder

PyPI Python License: MIT Tests

中文 | 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nanocoderagent-0.1.0.tar.gz (56.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nanocoderagent-0.1.0-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

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

Hashes for nanocoderagent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6f60deff7b1adae7e94ccdf13eec46bf926f4f9ce08dea6ba9053bdb4bbed81f
MD5 0e9e9e853a84b3f9b2b9fe9c63b80e93
BLAKE2b-256 f1ff16b02768acc919bcd707a99249da4575934eb17382de9c62d125300c18a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanocoderagent-0.1.0.tar.gz:

Publisher: publish.yml on he-yufeng/NanoCoder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for nanocoderagent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f766711ee5d83157a77620613d4046e9c85b68f4ba310af0183e0462a67f3d5c
MD5 a933c7edce64a0e687d0317a2cdbf614
BLAKE2b-256 5c32422e78a0d846008b89f34e16b42cf3bce6f68bfb290e3491ba7ee6c43ac7

See more details on using hashes here.

Provenance

The following attestation bundles were made for nanocoderagent-0.1.0-py3-none-any.whl:

Publisher: publish.yml on he-yufeng/NanoCoder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page