Feature Flags and Conditional Compilation: The Art of Compile-Time Code Elimination

A deep dive into Bun's compile-time feature flags -- the feature() API, dead code elimination, and criteria for choosing runtime vs compile-time flags

The Problem

Feature flags in web development are typically a runtime concept -- platforms like LaunchDarkly and Unleash dynamically determine feature switches at request time. But Claude Code faces entirely different constraints:

  1. It's a CLI distributed to external users -- Not all features should appear in public releases
  2. Startup speed is extremely sensitive -- Loading modules for unused features is wasteful
  3. Internal and external versions differ significantly -- Voice mode, Buddy pet, coordinator mode only exist in internal builds

Runtime flags can't solve these problems. Even if code inside if (false) { ... } never executes, its modules are still loaded and parsed. What Claude Code needs is compile-time code elimination -- making unwanted features completely disappear from the final artifact.

This is where bun:bundle's feature() API comes in.

How the feature() API Works

TypeScript
1import { feature } from 'bun:bundle'
2
3// Compile-time constant -- replaced with true or false at build time
4if (feature('VOICE_MODE')) {
5 // This entire branch is eliminated in external builds
6 const VoiceProvider = require('../context/voice.js').VoiceProvider
7}

feature() is not a function call -- it's a compiler directive. Bun's bundler at build time:

  1. Reads feature flag definitions from the build configuration
  2. Replaces feature('FLAG_NAME') with the corresponding boolean literal true or false
  3. The JavaScript engine's constant folding optimization recognizes if (false) { ... } as dead code
  4. Tree-shaking removes all unreachable code paths and their associated require() calls

Internal vs External Builds

...

Complete Flag Inventory

The Claude Code codebase uses over 85 distinct feature flags. Here they are grouped by functional domain:

Core Product Features

FlagPurpose
KAIROSAssistant mode (Claude Assistant)
KAIROS_BRIEFAssistant brief mode
KAIROS_CHANNELSAssistant channels (Telegram/iMessage)
KAIROS_DREAMAssistant autonomous execution
KAIROS_GITHUB_WEBHOOKSGitHub PR subscriptions
KAIROS_PUSH_NOTIFICATIONPush notifications
PROACTIVEProactive execution mode
BRIDGE_MODERemote control bridge
DAEMONBackground daemon process
VOICE_MODEVoice input/output
BUDDYCompanion pet (easter egg)

Context and Models

FlagPurpose
CONTEXT_COLLAPSEContext collapse compression
REACTIVE_COMPACTReactive compaction
CACHED_MICROCOMPACTCached micro-compaction
HISTORY_SNIPHistory trimming
TOKEN_BUDGETToken budget tracking
ULTRATHINKUltra-deep thinking mode
COMPACTION_REMINDERSCompaction reminders
BREAK_CACHE_COMMANDCache break command
PROMPT_CACHE_BREAK_DETECTIONPrompt cache break detection

Tools and Capabilities

FlagPurpose
AGENT_TRIGGERSScheduled triggers (cron)
AGENT_TRIGGERS_REMOTERemote triggers
MONITOR_TOOLMonitor tool
TERMINAL_PANELTerminal panel (tmux)
WEB_BROWSER_TOOLBrowser tool
CHICAGO_MCPComputer Use (macOS)
MCP_SKILLSMCP skill discovery
MCP_RICH_OUTPUTMCP rich text output
WORKFLOW_SCRIPTSWorkflow scripts
TORCHExperimental search

Teams and Collaboration

FlagPurpose
COORDINATOR_MODECoordinator mode
UDS_INBOXUnix Domain Socket message inbox
FORK_SUBAGENTSub-agent forking
TEAMMEMTeam memory sync
BG_SESSIONSBackground sessions
ULTRAPLANRemote ultra planning

Connectivity and Deployment

FlagPurpose
DIRECT_CONNECTDirect connect mode
SSH_REMOTESSH remote execution
CCR_AUTO_CONNECTCCR auto-connect
CCR_MIRRORCCR mirror sync
CCR_REMOTE_SETUPCCR remote setup
SELF_HOSTED_RUNNERSelf-hosted runner
BYOC_ENVIRONMENT_RUNNERBYOC environment runner

Telemetry and Diagnostics

FlagPurpose
ENHANCED_TELEMETRY_BETAEnhanced telemetry
COWORKER_TYPE_TELEMETRYCoworker type telemetry
MEMORY_SHAPE_TELEMETRYMemory shape telemetry
PERFETTO_TRACINGPerfetto tracing
SLOW_OPERATION_LOGGINGSlow operation logging
SHOT_STATSOutput statistics
DUMP_SYSTEM_PROMPTSystem prompt dump

Permissions and Security

FlagPurpose
TRANSCRIPT_CLASSIFIERTranscript classifier (auto mode)
BASH_CLASSIFIERBash command classification
VERIFICATION_AGENTVerification agent
NATIVE_CLIENT_ATTESTATIONNative client attestation
ANTI_DISTILLATION_CCAnti-distillation protection

Conditional Import Patterns

The combination of feature() and require() in Claude Code follows a set of fixed patterns.

Pattern 1: Module-Level Conditional Loading

TypeScript
1// src/tools.ts Lines 26-42
2const cronTools = feature('AGENT_TRIGGERS')
3 ? require('./tools/CronTool/index.js') as typeof import('./tools/CronTool/index.js')
4 : null
5
6const RemoteTriggerTool = feature('AGENT_TRIGGERS_REMOTE')
7 ? require('./tools/RemoteTriggerTool/index.js').RemoteTriggerTool
8 : null
9
10const MonitorTool = feature('MONITOR_TOOL')
11 ? require('./tools/MonitorTool/index.js').MonitorTool
12 : null
13
14const SendUserFileTool = feature('KAIROS')
15 ? require('./tools/SendUserFileTool/index.js').SendUserFileTool
16 : null

This is the most common pattern. feature() serves as the ternary condition, and require() only appears when the flag is true. When the flag is false, the entire require() expression and the corresponding module are eliminated by DCE.

Note the as typeof import(...) type assertion -- it ensures that when the flag is true, the require return value has the correct TypeScript type.

Pattern 2: Component-Level Conditional Rendering

TypeScript
1// src/state/AppState.tsx Lines 14-19
2const VoiceProvider: (props: {
3 children: React.ReactNode;
4}) => React.ReactNode = feature('VOICE_MODE')
5 ? require('../context/voice.js').VoiceProvider
6 : ({ children }) => children;

When VOICE_MODE is off, VoiceProvider is replaced with a passthrough component ({ children }) => children. Upstream code doesn't need to know whether Voice is enabled -- it always wraps children with <VoiceProvider>.

Pattern 3: In-Function Conditional Branches

TypeScript
1// src/main.tsx Lines 76-81
2const coordinatorModeModule = feature('COORDINATOR_MODE')
3 ? require('./coordinator/coordinatorMode.js') as typeof import('./coordinator/coordinatorMode.js')
4 : null
5
6const assistantModule = feature('KAIROS')
7 ? require('./assistant/index.js') as typeof import('./assistant/index.js')
8 : null
9
10const kairosGate = feature('KAIROS')
11 ? require('./assistant/gate.js') as typeof import('./assistant/gate.js')
12 : null

In main.tsx, numerous modules are conditionally loaded using this pattern. Subsequent usage is paired with null checks:

TypeScript
1// src/main.tsx Line 685
2if (feature('KAIROS') && _pendingAssistantChat) {
3 // ... only executes when KAIROS is enabled
4}

A double guard: feature('KAIROS') ensures compile-time elimination, while _pendingAssistantChat is a runtime null check.

Pattern 4: Schema Conditional Fields

TypeScript
1// src/utils/settings/types.ts Lines 61-78
2defaultMode: z.enum(
3 feature('TRANSCRIPT_CLASSIFIER')
4 ? PERMISSION_MODES // Includes 'auto' and other internal modes
5 : EXTERNAL_PERMISSION_MODES // Public modes only
6).optional(),
7...(feature('TRANSCRIPT_CLASSIFIER')
8 ? { disableAutoMode: z.enum(['disable']).optional() }
9 : {}),

The schema shape itself is conditional. The external build's schema simply doesn't have the disableAutoMode field -- not just hidden, but nonexistent in the type system.

Pattern 5: Command Registration

TypeScript
1// src/commands.ts Lines 63-118
2feature('PROACTIVE') || feature('KAIROS')
3 ? require('./commands/proactive.js').default : null
4
5const bridge = feature('BRIDGE_MODE')
6 ? require('./commands/bridge/index.js').default : null
7
8feature('DAEMON') && feature('BRIDGE_MODE')
9 ? require('./commands/daemon.js').default : null
10
11const voiceCommand = feature('VOICE_MODE')
12 ? require('./commands/voice/voice.js').default : null
13
14const ultraplan = feature('ULTRAPLAN')
15 ? require('./commands/ultraplan.js').default : null
16
17const buddy = feature('BUDDY')
18 ? require('./commands/buddy.js').default : null

Each slash command's registration is controlled by feature flags. External version users never see /voice, /buddy, /ultraplan, or similar commands -- their code simply doesn't exist in the artifact.

Compile-Time vs Runtime Flags

...

Claude Code uses both flag systems simultaneously:

Compile-Time Feature Flags (bun:bundle)

  • Decision point: Build/bundling time
  • Granularity: Whether entire modules/features exist
  • Typical use: Internal-only features (Voice, Buddy, Coordinator)
  • Advantages: Zero runtime overhead, reduced artifact size, impossible to accidentally enable in production
  • Disadvantages: Changes require a new release

Runtime Feature Flags (GrowthBook)

  • Decision point: Runtime, possibly using cache
  • Granularity: Behavioral parameters (sample rates, batch sizes)
  • Typical use: Telemetry configuration, A/B experiments, kill switches
  • Advantages: Remotely toggleable, no release needed
  • Disadvantages: Code remains in artifact, requires network requests

Selection Criteria

QuestionCompile-timeRuntime
Does the feature only exist in specific builds?Yes--
Does the feature require loading additional modules?Yes--
Does the feature need A/B testing?--Yes
Does the feature need emergency remote shutdown?--Yes
Toggle frequency?Low (per release)High (anytime)

Compound Flag Patterns

Some features use combinations of multiple flags:

TypeScript
1// src/commands.ts Line 77
2feature('DAEMON') && feature('BRIDGE_MODE')
3 ? require('./commands/daemon.js').default : null

The daemon command only exists when both DAEMON and BRIDGE_MODE are enabled. If either flag is false, &&'s short-circuit evaluation immediately produces false, and the entire expression is eliminated at compile time.

TypeScript
1// src/tools.ts Line 26
2feature('PROACTIVE') || feature('KAIROS')

SendMessageTool is available when either PROACTIVE or KAIROS is enabled -- meaning two independent feature domains share a single tool.

DCE Boundaries and Caveats

require() Must Be Inside a feature() Branch

TypeScript
1// Correct -- require is inside a feature() guard
2const module = feature('X') ? require('./x.js') : null
3
4// Wrong -- import is at module top level, DCE cannot eliminate it
5import { x } from './x.js'
6if (feature('X')) { x() }

ES module import statements are static declarations; the bundler includes the module when analyzing the dependency graph. Only require() (CommonJS dynamic import) inside conditional branches can be eliminated by DCE.

TypeScript Types Remain Available

TypeScript
1const assistantModule = feature('KAIROS')
2 ? require('./assistant/index.js') as typeof import('./assistant/index.js')
3 : null

typeof import(...) is a pure type operation -- it produces no runtime code. Even when KAIROS is false, TypeScript still knows the type shape of assistantModule when it's non-null. This allows subsequent code to perform type-safe null checks:

TypeScript
1if (feature('KAIROS') && assistantModule) {
2 // TypeScript knows the type of assistantModule here
3 assistantModule.isAssistantMode()
4}

Conditional Fields in AppState

TypeScript
1// src/state/AppStateStore.ts Lines 97-98
2// Optional - only present when ENABLE_AGENT_SWARMS is true
3showTeammateMessagePreview?: boolean

AppState uses ?: optional fields to mark state affected by feature flags. Source code comments explicitly document this coupling, helping developers understand which fields are meaningful in which builds.

REPL.tsx: The File with the Highest Flag Density

src/screens/REPL.tsx is the file with the highest density of feature() calls in the entire codebase, containing 70+ invocations. This is because the REPL is the convergence point for all features:

TypeScript
1// src/screens/REPL.tsx Line 3
2import { feature } from 'bun:bundle';
3
4// Conditional module loading
5const useVoiceIntegration = feature('VOICE_MODE')
6 ? require('../hooks/useVoiceIntegration.js').useVoiceIntegration
7 : () => ({ /* noop */ })
8
9const VoiceKeybindingHandler = feature('VOICE_MODE')
10 ? require('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler
11 : () => null
12
13const proactiveModule = feature('PROACTIVE') || feature('KAIROS')
14 ? require('../proactive/index.js') : null
15
16const useScheduledTasks = feature('AGENT_TRIGGERS')
17 ? require('../hooks/useScheduledTasks.js').useScheduledTasks : null
18
19const WebBrowserPanelModule = feature('WEB_BROWSER_TOOL')
20 ? require('../tools/WebBrowserTool/WebBrowserPanel.js') : null

In JSX rendering:

TypeScript
1{feature('VOICE_MODE')
2 ? <VoiceKeybindingHandler ... /> : null}
3
4{feature('WEB_BROWSER_TOOL')
5 ? WebBrowserPanelModule && <WebBrowserPanelModule.WebBrowserPanel />
6 : null}
7
8{feature('BUDDY') && companionVisible
9 ? <CompanionSprite /> : null}
10
11{feature('ULTRAPLAN')
12 ? focusedInputDialog === 'ultraplan-choice' && <UltraplanChoiceDialog ... />
13 : null}

In external builds, all these JSX expressions are replaced with null, and the corresponding component code is completely absent.

Quantified Impact

85+ feature flags means external builds may exclude dozens of complete modules. Assuming each excluded feature module averages 50KB (code + dependencies), DCE could save several megabytes of artifact size. More importantly:

  • Startup time -- Modules that don't need loading don't need parsing, directly shortening cold start
  • Memory footprint -- Nonexistent code doesn't occupy V8's code space
  • Attack surface -- External users cannot reach internal features, even if they discover the corresponding code paths

Comparison with Traditional Approaches

ApproachRuntime overheadArtifact sizeType safetyRemote control
Environment variables if (process.env.X)LowUnchangedWeakRequires restart
LaunchDarkly/UnleashNetwork requestUnchangedNoneReal-time
GrowthBook (runtime)Cache readUnchangedWeakNear real-time
bun:bundle feature()ZeroReducedStrongNot possible

The unique advantage of feature() is the three-in-one combination of compile-time type safety + zero runtime overhead + reduced artifact size. The tradeoff is no remote toggling -- but for decisions like "does this feature exist in this version," remote toggling was never the right answer anyway.

Summary

Claude Code's feature flag system is a masterful use of compiler capabilities:

  • 85+ feature() flags -- Covering product features, tools, connectivity, telemetry, security, and every other dimension
  • bun:bundle compile-time replacement -- feature('X') -> true/false -> constant folding -> DCE
  • Conditional require() pattern -- Ensures excluded features' modules are never loaded and never appear in the artifact
  • Schema conditional fields -- The configuration validation shape itself varies with flags
  • Complementary with runtime GrowthBook -- Compile-time decides "what exists," runtime decides "how it's used"
  • TypeScript type safety -- typeof import(...) assertions maintain correctness at both compile-time and runtime

Not all feature flags need to be runtime. When the question is "should this feature exist in this binary," compile-time flags are the only correct answer.