Startup & Bootstrap
How Claude Code goes from bun dist/cli.js to a fully interactive REPL — before any conversation begins.
The Big Picture
Think of startup like opening a restaurant before the first customer arrives. You need to turn on the lights (config), check the fridge (auth), set up the menu (tools), and unlock the door (REPL). Only then can you serve anyone.
Fast-Path Routing
The entry point (src/entrypoints/cli.tsx, ~302 lines) is designed to be fast when possible. Before loading the full app, it checks for special flags that need quick responses:
| Flag | What Happens | Imports Needed |
|---|---|---|
--version / -v | Print version string, exit | Zero — fastest path |
--dump-system-prompt | Render full system prompt, exit | Config + prompt system |
--claude-in-chrome-mcp | Launch Chrome MCP server | MCP subsystem |
--computer-use-mcp | Launch computer-use MCP server | MCP subsystem |
--daemon-worker | Start background daemon | Daemon subsystem |
remote-control / bridge | Launch IDE bridge | Bridge subsystem |
| (none of the above) | Load full CLI | Everything |
The key trick is dynamic imports — each path only loads what it needs. The --version path literally imports nothing beyond the entry file itself.
If Claude Code loaded all 489 npm packages for every --version check, startup would be painfully slow. Dynamic imports mean you only pay for what you use.
Full Initialization
When no fast-path flag matches, the entry point dynamically imports main.tsx (~4,683 lines), which runs through 9 initialization phases before the REPL is ready:
What init() Actually Wires Up
The early startup work is split between cli.tsx, entrypoints/init.ts, and main.tsx. init.ts does more than simple config loading:
| Startup Concern | Source-Backed Behavior |
|---|---|
| Config safety | Enables config parsing, applies safe env vars first, and installs extra CA certs before any TLS traffic |
| Managed startup state | Creates loading promises for remote managed settings and policy limits so later systems can wait on them |
| Network stack | Configures global mTLS, proxy-aware HTTP agents, and a fire-and-forget Anthropic API preconnect |
| CCR-specific plumbing | Starts the upstream proxy relay in remote mode so subprocesses inherit the right proxy env |
| Cleanup hooks | Registers graceful shutdown plus cleanup for LSP and team state |
| Scratchpad filesystem | Creates the scratchpad directory if that feature is enabled |
Split Between init.ts and main.tsx
| File | Role |
|---|---|
src/entrypoints/init.ts | Safe env bootstrapping, network configuration, cleanup registration, remote-settings readiness, scratchpad setup |
src/main.tsx | Trust flow, settings/UI initialization, plugin/MCP/tool/command loading, LSP manager init, background settings sync upload, and REPL launch |
That split matters because some systems need to start before the UI exists. For example, remote managed settings, policy limits, proxy config, and preconnect all happen before the interactive shell is fully rendered.
Session Restoration
When you use --resume or --continue, the bootstrap path changes:
- Previous session messages loaded from
~/.claude/sessions/<id> - Conversation state restored to AppState
- REPL opens with your history intact — pick up where you left off
When Things Go Wrong
Startup is designed to be resilient — a single failure shouldn't prevent the whole app from launching:
| Failure | What Happens |
|---|---|
| Missing config | Falls back to sensible defaults |
| Auth failure | Prompts for API key or launches OAuth flow in browser |
| MCP server won't start | Warning logged, that server skipped, everything else works |
| Plugin failure | Warning logged, that plugin skipped |
What Happens Next?
Once launchRepl() fires, the terminal UI is live and waiting for your first input. From here:
- Input & Rendering — how your keystrokes enter the system and how responses render
- The Agent Loop — the cycle that powers every conversation turn
Key Source Files
| File | Lines | Purpose |
|---|---|---|
src/entrypoints/cli.tsx | ~302 | Bootstrap entry, fast-path routing |
src/entrypoints/init.ts | ~300 | Early init: config safety, network stack, cleanup, remote settings readiness |
src/main.tsx | ~4,683 | Full CLI initialization |
src/replLauncher.tsx | — | REPL rendering setup |
src/bootstrap/state.ts | — | Session state initialization |