InkdownInkdown
Start writing

Claude-Code

62 files·4 subfolders

Shared Workspace

Claude-Code
codex

13-build-system

Shared from "Claude-Code" on Inkdown

Build System & Dead Code Elimination

Overview

Claude Code uses Bun for building with a sophisticated dead code elimination (DCE) system. The binary size matters - we need to exclude internal features from external builds.

Plain text
┌─────────────────────────────────────────────────────────────────────────────┐
│                      BUILD PIPELINE                                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐                │
│  │   Source     │───►│    Bun       │───►│   Binary     │                │
│  │   (TypeScript)│    │   Bundle     │    │  (compiled)  │                │
│  └──────────────┘    └──────┬──────┘    └──────────────┘                │
│                             │                                               │
│                             ▼                                               │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                    BUILD PHASES                                      │   │
│  │                                                                       │   │
│  │  1. TRANSPILE    TypeScript → JavaScript (SWC)                       │   │
│  │  2. TREE SHAKE   Remove unused code                                  │   │
│  │  3. MACRO EVAL   Evaluate feature() at build time                    │   │
│  │  4. BUNDLE       Single file output                                  │   │
│  │  5. MINIFY       Compress & optimize                                 │   │
│  │  6. COMPILE      Native binary (bun build --compile)                 │   │
│  │                                                                       │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
0000_start_here_index_and_recommended_reading_order.md
0100_project_overview_tech_stack_runtime_modes_and_folder_map.md
0200_startup_flow_entry_points_and_cold_start_sequence.md
0300_codebase_modules_layers_state_models_and_schemas.md
0400_system_architecture_and_design_rationale.md
0500_interactive_repl_request_flow_end_to_end.md
0600_headless_sdk_and_print_mode_request_flow_end_to_end.md
0700_mcp_integration_connection_and_tool_call_flow.md
0800_external_services_sdks_storage_and_local_dependencies.md
0900_environment_variables_settings_feature_flags_and_failure_modes.md
1000_non_obvious_patterns_gotchas_and_debugging_traps.md
1100_full_codebase_file_inventory_grouped_by_directory.md
kimi
00-overview.md
01-entrypoints.md
02-state-management.md
03-query-system.md
04-tools-system.md
05-tasks-system.md
06-ui-components.md
07-bridge-remote.md
08-services.md
09-skills-plugins.md
10-commands.md
11-testing-architecture.md
12-permission-system.md
13-build-system.md
14-ink-internals.md
15-git-internals.md
16-context-compaction.md
17-vim-mode.md
18-mailbox-notifications.md
19-session-persistence.md
20-hooks-system.md
21-error-recovery.md
README.md
qwen
00-overview.md
01-entry-points.md
02-query-engine.md
03-tools-and-tasks.md
04-commands-and-skills.md
05-state-management.md
06-ink-rendering.md
07-bridge-remote.md
08-mcp-services.md
09-services-overview.md
10-multi-agent.md
11-system-prompt-constants.md
12-tool-interface.md
13-memory-system.md
14-buddy-companion.md
15-keybindings.md
16-stop-hooks.md
17-vim-mode.md
18-upstreamproxy.md
19-cost-tracking-history.md
20-contexts-styles-onboarding.md
21-hooks.md
22-screens.md
tweets-explain
claude-code-memory-analysis.md
compact
memory-system
agentic-architecture

Core Files

File/DirectoryPurpose
package.jsonDependencies, scripts
tsconfig.jsonTypeScript config
build.tsCustom build script
bun.buildBun bundler config
features.tsFeature flag definitions
macros/Bun macro definitions

Dead Code Elimination (DCE)

The Problem

Claude Code has internal-only features (assistant mode, bridge, daemon). We don't want these in public builds:

TypeScript
// Without DCE, this code stays in binary
import { assistantFeature } from './assistant/index.js'

if (process.env.USER_TYPE === 'ant') {
  // This code exists in all builds, even though only
  // 'ant' users can access it. Waste of space.
  assistantFeature()
}
The Solution: Build-Time Macros
TypeScript
// With DCE using bun:bundle feature()
import { feature } from 'bun:bundle'

// This is EVALUATED AT BUILD TIME
if (feature('KAIROS')) {
  // If KAIROS is false at build, this ENTIRE BLOCK
  // is removed from the output. Zero bytes.
  const assistant = require('./assistant/index.js')
  assistant.initialize()
}
How feature() Works
TypeScript
// bun:bundle is a special module handled by Bun
// At build time, it evaluates and replaces calls

import { feature } from 'bun:bundle'

// Build config specifies:
// features: { KAIROS: false, BRIDGE_MODE: true }

// In code:
if (feature('KAIROS')) {
  console.log('Assistant mode')
}

// After bundling (KAIROS=false):
if (false) {  // Dead code, removed by tree shaker
  console.log('Assistant mode')
}
// Result: Entire if block removed

// After bundling (KAIROS=true):
if (true) {   // Condition known, body kept
  console.log('Assistant mode')
}
// Result: Becomes just the console.log

Feature Flags

Feature Definition
TypeScript
// features.ts - Single source of truth
export const FEATURES = {
  // Public features (always true)
  TOOLS: true,
  TASKS: true,
  MCP: true,

  // Beta features (conditional)
  BRIDGE_MODE: process.env.BUILD_TYPE === 'internal',
  DAEMON: process.env.BUILD_TYPE === 'internal',
  VOICE_MODE: process.env.BUILD_TYPE === 'internal',

  // Internal only (false for public)
  KAIROS: process.env.BUILD_TYPE === 'internal',
  PROACTIVE: process.env.BUILD_TYPE === 'internal',
  ABLATION_BASELINE: false,

  // Development
  OVERFLOW_TEST_TOOL: process.env.NODE_ENV === 'development',
  CONTEXT_COLLAPSE: process.env.BUILD_TYPE === 'internal',
} as const

export type FeatureFlag = keyof typeof FEATURES
Conditional Imports
TypeScript
// Pattern for conditional module loading
import { feature } from 'bun:bundle'

/* eslint-disable @typescript-eslint/no-require-imports */

// This entire block vanishes if feature is false
const SleepTool = feature('PROACTIVE') || feature('KAIROS')
  ? require('./tools/SleepTool/SleepTool.js').SleepTool
  : null

const cronTools = feature('AGENT_TRIGGERS')
  ? [
      require('./tools/ScheduleCronTool/CronCreateTool.js').CronCreateTool,
      require('./tools/ScheduleCronTool/CronDeleteTool.js').CronDeleteTool,
    ]
  : []

const coordinatorModeModule = feature('COORDINATOR_MODE')
  ? require('./coordinator/coordinatorMode.js')
  : null

/* eslint-enable @typescript-eslint/no-require-imports */

// Usage - TypeScript knows it might be null
export function getCoordinatorUserContext(): UserContext {
  return coordinatorModeModule?.getCoordinatorUserContext?.() ?? {}
}

Build Configuration

Build Script
TypeScript
// build.ts
import { build } from 'bun'

const result = await build({
  entrypoints: ['./src/entrypoints/cli.tsx'],
  outdir: './dist',

  // Target
  target: 'bun',  // Bun runtime

  // Optimization
  minify: {
    whitespace: true,
    identifiers: true,
    syntax: true,
  },

  // Dead code elimination
  define: {
    'process.env.BUILD_TYPE': JSON.stringify(process.env.BUILD_TYPE),
    'MACRO.VERSION': JSON.stringify(getVersion()),
    'MACRO.FEATURES': JSON.stringify(getFeatures()),
  },

  // External dependencies (not bundled)
  external: [
    'node:*',  // Node.js built-ins
  ],

  // Plugins
  plugins: [
    // Custom macro plugin
    {
      name: 'feature-macros',
      setup(build) {
        build.onLoad({ filter: /bun:bundle/ }, () => {
          return {
            contents: `
              export function feature(name) {
                return ${JSON.stringify(getFeatures())}[name] ?? false
              }
            `,
            loader: 'js',
          }
        })
      },
    },
  ],
})

console.log(`Built ${result.outputs.length} files`)
Package Scripts
JSON
{
  "scripts": {
    "build": "bun run build.ts",
    "build:public": "BUILD_TYPE=public bun run build.ts",
    "build:internal": "BUILD_TYPE=internal bun run build.ts",
    "compile": "bun build --compile ./dist/cli.js --outfile ./claude",
    "dev": "bun run --hot src/entrypoints/cli.tsx"
  }
}

Tree Shaking

What Gets Removed
TypeScript
// INPUT (src/utils/helper.ts)
export function usedFunction() {
  return 'I am used'
}

export function unusedFunction() {
  return 'I will be removed'
}

// INPUT (src/main.ts)
import { usedFunction } from './utils/helper.js'

console.log(usedFunction())

// OUTPUT (bundled)
function usedFunction() {
  return 'I am used'
}

console.log(usedFunction())
// unusedFunction is completely gone
Side-Effect Handling
TypeScript
// Files with side effects are preserved
// Mark in package.json:
{
  "sideEffects": [
    "./src/polyfills.js",
    "*.css"
  ]
}

// Or in code:
// @side-effects
import './initializeAnalytics.js'

Macro Examples

Version Macro
TypeScript
// Built-in: MACRO.VERSION
console.log(`Claude Code ${MACRO.VERSION}`)

// Becomes at build:
console.log(`Claude Code 1.2.3`)  // Inlined
Feature Table Macro
TypeScript
// Check multiple features efficiently
const features = {
  bridge: feature('BRIDGE_MODE'),
  daemon: feature('DAEMON'),
  kairos: feature('KAIROS'),
}

// Becomes:
const features = {
  bridge: true,   // or false
  daemon: false,  // evaluated at build
  kairos: false,
}
Environment Macro
TypeScript
// process.env becomes constants
if (process.env.NODE_ENV === 'development') {
  enableDebugLogs()
}

// Becomes (in production build):
if (false) {  // Removed by DCE
  enableDebugLogs()
}

Bundle Analysis

Size Reporting
TypeScript
// build.ts - Size analysis
const result = await build({...})

for (const output of result.outputs) {
  const size = (await output.text()).length
  console.log(`${output.path}: ${formatBytes(size)}`)
}

// Example output:
// dist/cli.js: 2.4 MB
// dist/main.js: 1.8 MB (BRIDGE_MODE=false)
Visualizing Bundle
Bash
# Generate bundle stats
bun build --sourcemap ./src/main.tsx

# Analyze with webpack-bundle-analyzer
npx webpack-bundle-analyzer dist/stats.json

Conditional Compilation

Platform-Specific Code
TypeScript
// Platform detection at build time
const isMacOS = process.platform === 'darwin'
const isWindows = process.platform === 'win32'

if (isMacOS) {
  // macOS-specific code
  const { setInKeychain } = require('./utils/secureStorage/keychain.js')
} else if (isWindows) {
  // Windows-specific code
  const { setWindowsCredential } = require('./utils/secureStorage/windows.js')
}

// Only relevant platform code is included
User Type Conditional
TypeScript
// Ant-only features
const agentsPlatform =
  process.env.USER_TYPE === 'ant'
    ? require('./commands/agents-platform/index.js').default
    : null

const REPLTool =
  process.env.USER_TYPE === 'ant'
    ? require('./tools/REPLTool/REPLTool.js').REPLTool
    : null

// Becomes for public builds:
const agentsPlatform = null
const REPLTool = null

Compilation to Binary

Bash
# Development (interpreted)
bun run src/entrypoints/cli.tsx

# Production (compiled binary)
bun build --compile ./dist/cli.js --outfile claude

# Result: Single executable file
./claude --version  # No dependencies needed!
Compile Options
TypeScript
// bun.config.js
export default {
  compile: {
    // Embed these in the binary
    embed: [
      './assets/logo.txt',
      './ bundled/node_modules/ripgrep/binary',
    ],

    // Compression
    compression: 'gzip',  // or 'brotli', 'none'

    // Target platform
    target: [
      'bun-darwin-x64',
      'bun-darwin-arm64',
      'bun-linux-x64',
      'bun-windows-x64',
    ],
  },
}

Development vs Production

TypeScript
// Hot reload in development
if (process.env.NODE_ENV !== 'production') {
  // Watch files, reload on change
  setupHotReload()
}

// Debug logging
const debug = process.env.NODE_ENV === 'development'
  ? console.log
  : () => {}

debug('This only logs in dev')

// Assertions
console.assert(process.env.NODE_ENV === 'development', 'Debug check')

Build Performance

Caching
Bash
# Bun caches builds
bun build --cache-dir ./.bun-cache

# Incremental builds
bun build --incremental
Parallel Builds
TypeScript
// Build multiple targets in parallel
await Promise.all([
  build({ entrypoints: ['./cli.tsx'], outdir: './dist/macos', target: 'bun-darwin-arm64' }),
  build({ entrypoints: ['./cli.tsx'], outdir: './dist/linux', target: 'bun-linux-x64' }),
  build({ entrypoints: ['./cli.tsx'], outdir: './dist/windows', target: 'bun-windows-x64' }),
])

Key Concepts

  1. Build-Time Evaluation: feature(), MACRO.* evaluated at compile, not runtime
  2. Tree Shaking: Unused code automatically removed
  3. Conditional Imports: require() inside if (feature()) vanishes when false
  4. Single Binary: Bun compiles to standalone executable
  5. Platform Optimization: Platform-specific code only includes relevant paths

Debugging Builds

Bash
# See what features are enabled
BUILD_TYPE=internal bun run build.ts --verbose

# Analyze bundle
bun build --analyze

# Check if code is eliminated
grep -r "SleepTool" dist/  # Should be empty if feature false

# Source maps for debugging
bun build --sourcemap