This document covers all naming conventions used throughout the Claude Code codebase, with real examples from the source.
All local variables, module-level variables, parameters, and function names use camelCase:
// Functions
export function getCommands(): Command[] { ... }
export function isDebugMode(): boolean { ... }
export function logError(error: unknown): void { ... }
export function findCommand(name: string): Command | undefined { ... }
export function enableDebugLogging(): boolean { ... }
export function captureAPIRequest(params: BetaMessageStreamParams): void { ... }
// Variables
let runtimeDebugEnabled = false
let systemPromptInjection: string | null = null
let debugWriter: BufferedWriter | null = null
let hasFormattedOutput = false
const customInstructions = args.trim()
const absolutePath = path ? expandPath(path) : getCwd()Prefix with is, has, should, can, or similar:
export function isAbortError(e: unknown): boolean { ... }
export function isENOENT(e: unknown): boolean { ... }
export function isFsInaccessible(e: unknown): boolean { ... }
export function hasExactErrorMessage(error: unknown, message: string): boolean { ... }
function shouldLogDebugMessage(message: string): boolean { ... }
function shouldUseSandbox(): boolean { ... }
let hasFormattedOutput = false
const isAutonomousPrompt = log.firstPrompt?.startsWith(`<${TICK_TAG}>`)
const useFirstPrompt = strippedFirstPrompt && !isAutonomousPromptUse get/set prefixes for module-level state accessors:
export function getSystemPromptInjection(): string | null { ... }
export function setSystemPromptInjection(value: string | null): void { ... }
export function getHasFormattedOutput(): boolean { ... }
export function setHasFormattedOutput(value: boolean): void { ... }
export function getDebugLogPath(): string { ... }
export function getDebugFilePath(): string | null { ... }
export function getMinDebugLogLevel(): DebugLogLevel { ... }All type aliases, interfaces, classes, and enums use PascalCase:
// Type aliases
export type SessionId = string & { readonly __brand: 'SessionId' }
export type AgentId = string & { readonly __brand: 'AgentId' }
export type DebugLogLevel = 'verbose' | 'debug' | 'info' | 'warn' | 'error'
export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'killed'
export type PermissionBehavior = 'allow' | 'deny' | 'ask'
export type PermissionMode = InternalPermissionMode
export type AxiosErrorKind = 'auth' | 'timeout' | 'network' | 'http' | 'other'
// Compound types
export type ToolUseContext = { ... }
export type ToolPermissionContext = DeepImmutable<{ ... }>
export type LocalCommandResult = { type: 'text'; value: string } | { ... }
export type AggregatedHookResult = { ... }
export type PromptRequest = z.infer<ReturnType<typeof promptRequestSchema>>
// Classes
export class ClaudeError extends Error { ... }
export class AbortError extends Error { ... }
export class ShellError extends Error { ... }
export class ConfigParseError extends Error { ... }
export class TeleportOperationError extends Error { ... }
// Interfaces (via type, not interface keyword)
export type ErrorLogSink = {
logError: (error: Error) => void
logMCPError: (serverName: string, error: unknown) => void
...
}When deriving types from Zod schemas, follow this pattern:
const inputSchema = lazySchema(() => z.strictObject({ ... }))
type InputSchema = ReturnType<typeof inputSchema> // The schema type
export type FileEditInput = z.output<InputSchema> // The parsed output type
export type FileEditOutput = z.infer<OutputSchema> // The inferred typeModule-level constants and configuration values use UPPER_SNAKE_CASE:
// Numeric constants
const MAX_EDIT_FILE_SIZE = 1024 * 1024 * 1024 // 1 GiB
const DEFAULT_HEAD_LIMIT = 250
const MAX_IN_MEMORY_ERRORS = 100
const PROGRESS_THRESHOLD_MS = 2000
const ASSISTANT_BLOCKING_BUDGET_MS = 15_000
const PREVIEW_SIZE_BYTES = 4096
// String constants
const EOL = '\n'
const TASK_ID_ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'
export const FILE_EDIT_TOOL_NAME = 'Edit'
export const GREP_TOOL_NAME = 'Grep'
export const BASH_TOOL_NAME = 'Bash'
// Array/Set constants
const VCS_DIRECTORIES_TO_EXCLUDE = ['.git', '.svn', '.hg', '.bzr', '.jj', '.sl'] as const
const BASH_SEARCH_COMMANDS = new Set(['find', 'grep', 'rg', 'ag', 'ack', 'locate'])
const BASH_READ_COMMANDS = new Set(['cat', 'head', 'tail', 'less', 'more', 'wc', 'stat'])
const BASH_SILENT_COMMANDS = new Set(['mv', 'cp', 'rm', 'mkdir', 'rmdir', 'chmod'])
// Object constants
const LEVEL_ORDER: Record<DebugLogLevel, number> = {
verbose: 0, debug: 1, info: 2, warn: 3, error: 4,
}
// Pattern constants
const AGENT_ID_PATTERN = /^a(?:.+-)?[0-9a-f]{16}$/
export const CLAUDE_FOLDER_PERMISSION_PATTERN = '/.claude/**'Constants shared across the codebase go in src/constants/:
// src/constants/toolLimits.ts
export const TOOL_SUMMARY_MAX_LENGTH = 100
// src/constants/xml.ts
export const TICK_TAG = 'tick'Tool names are PascalCase strings stored as UPPER_SNAKE_CASE constants:
export const GREP_TOOL_NAME = 'Grep'
export const BASH_TOOL_NAME = 'Bash'
export const FILE_EDIT_TOOL_NAME = 'Edit'
export const NOTEBOOK_EDIT_TOOL_NAME = 'NotebookEdit'
export const AGENT_TOOL_NAME = 'Agent'src/tools/GrepTool/
src/tools/BashTool/
src/tools/FileEditTool/
src/tools/AgentTool/
src/tools/WebFetchTool/
src/commands/add-dir/
src/commands/install-github-app/
src/commands/install-slack-app/
src/commands/debug-tool-call/
src/commands/output-style/
src/commands/break-cache/
src/utils/errors.ts
src/utils/debug.ts
src/utils/sleep.ts
src/utils/envUtils.ts
src/utils/stringUtils.ts
src/utils/fileRead.ts
src/utils/lazySchema.ts
src/utils/semanticBoolean.ts
src/utils/cleanupRegistry.ts
src/utils/bufferedWriter.ts
src/components/Spinner.tsx
src/components/Markdown.tsx
src/components/MessageResponse.tsx
src/components/CtrlOToExpand.tsx
src/components/FallbackToolUseErrorMessage.tsx
src/components/HelpV2/HelpV2.tsx
src/types/command.ts
src/types/hooks.ts
src/types/ids.ts
src/types/logs.ts
src/types/message.ts
src/types/permissions.ts
src/types/plugin.ts
src/Tool.ts # Core type — PascalCase
src/Task.ts # Core type — PascalCase
src/commands.ts # Registry — camelCase
src/tools.ts # Registry — camelCase
src/context.ts # Utility — camelCase
src/query.ts # Core loop — camelCase
src/main.tsx # Entry — camelCase
src/cost-tracker.ts # Service — kebab-case (rare)
src/history.ts # Service — camelCase
Mark unused parameters with an underscore prefix:
// Unused function parameters
function renderToolResultMessage(
output: Output,
_progressMessagesForMessage: ProgressMessage<ToolProgressData>[],
{ verbose }: { verbose: boolean },
): React.ReactNode { ... }
// Unused destructured properties
const { numLines: _numLines, ...rest } = output
// Unused loop variables
results.map((_, i) => ...)
// Exhaustive check variable
const _exhaustive: never = statusWhen a name carries a security or privacy obligation, make it deliberately long to force the developer to acknowledge they've verified the safety:
// Error class — name forces you to verify message content
export class TelemetrySafeError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS extends Error {
readonly telemetryMessage: string
...
}
// Type — name forces you to verify metadata content
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS = string
// Usage — the long name is intentional friction
throw new TelemetrySafeError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS(
'MCP server connection timed out'
)function SearchResultSummary({ count, countLabel, content, verbose }) { ... }
function BackgroundHint() { ... }
// Exported components
export function HelpV2({ commands, onClose }) { ... }
export function MessageResponse({ children, height }) { ... }
export function CtrlOToExpand() { ... }
export function FallbackToolUseErrorMessage({ result, verbose }) { ... }// File: src/hooks/useCanUseTool.ts
export type CanUseToolFn = ...
// React hooks follow standard React naming
function useAppState() { ... }
function useMessages() { ... }Not prefixed with on — use descriptive function names:
// Module-level handlers
function onAbort(): void { ... }
function appendAsync(...): Promise<void> { ... }
function noop(): void {}
// Callback props use `on` prefix
type Props = {
onClose: () => void
onDone: LocalJSXCommandOnDone
onChangeAPIKey: () => void
onChangeDynamicMcpConfig?: (config: ...) => void
onInstallIDEExtension?: (ide: IdeType) => void
}| Category | Convention | Real Examples |
|---|---|---|
| Functions | camelCase |
getCommands, isDebugMode, logError, toError |
| Variables | camelCase |
runtimeDebugEnabled, debugWriter, absolutePath |
| Types/Interfaces | PascalCase |
SessionId, ToolUseContext, AppState, TaskStatus |
| Classes | PascalCase |
ClaudeError, AbortError, ShellError |
| Constants | UPPER_SNAKE_CASE |
DEFAULT_HEAD_LIMIT, BASH_TOOL_NAME, EOL |
| Tool names | PascalCase string |
'Grep', 'Bash', 'Edit', 'NotebookEdit' |
| Tool dirs | PascalCase/ |
GrepTool/, BashTool/, FileEditTool/ |
| Command dirs | kebab-case/ |
add-dir/, install-github-app/ |
| Util files | camelCase.ts |
errors.ts, debug.ts, lazySchema.ts |
| Component files | PascalCase.tsx |
Spinner.tsx, Markdown.tsx |
| Unused params | _ prefix |
_input, _ctx, _numLines, _exhaustive |
| Safety names | Long explicit | TelemetrySafeError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS |
| Booleans | is/has/should |
isAbortError, hasFormattedOutput, shouldLog |
| Getters/Setters | get/set prefix |
getSystemPromptInjection, setHasFormattedOutput |
| React components | PascalCase |
SearchResultSummary, HelpV2, MessageResponse |
| Hooks | use prefix |
useAppState, useCanUseTool |