Code Style Conventions Observed in OpenClaw
This document captures observations about OpenClaw's code formatting, linting, and TypeScript configuration based on analysis of the codebase. These conventions ensure consistency and pass CI checks.
Linter: Oxlint (NOT ESLint)
OpenClaw uses Oxlint, not ESLint. Configuration is in .oxlintrc.json.
Key Configuration
Critical Rules
typescript/no-explicit-any: "error" - Never useanytype (strict enforcement)curly: "error" - Always use braces for control flow statements- Categories as errors - Correctness, performance, and suspicious patterns are all errors, not warnings
Formatter: Oxfmt (NOT Prettier)
OpenClaw uses Oxfmt, not Prettier. Configuration is in .oxfmtrc.jsonc.
Key Configuration
Formatting Rules
- 2-space indentation, no tabs
- Experimental sort imports enabled - Import statements are automatically sorted
- Oxfmt handles all formatting; no need to run Prettier
TypeScript Configuration
TypeScript config is in tsconfig.json with strict mode enabled.
Key Settings
Notable Settings
strict: true- All strict type-checking options enabledexperimentalDecorators: true- Required for legacy decorators in Control UI Lit componentsnoEmit: true- TypeScript is used for type checking only, not compilation- ES2023 target - Modern JavaScript features available
- NodeNext module resolution - Supports ESM with
.jsextensions in imports
Type Definition Preferences
Prefer type Over interface
For object shapes, the codebase prefers type over interface.
Pattern observed:
Not:
Always Include JSDoc
Public types and functions should have JSDoc comments explaining their purpose.
Critical Rules from Contributing Docs
These rules are explicitly documented in CONTRIBUTING.md and CLAUDE.md:
Never Disable Type Safety
- Never use
@ts-nocheck- Fix type errors instead of suppressing them - Never disable
no-explicit-any- Always provide explicit types - If you can't type something properly, ask for guidance rather than using
any
Never Use Prototype Mutation
- Never mutate prototypes for behavior sharing
- Use
extendsinstead - Proper class inheritance or composition
Bad:
Good:
File Size Target
- Target: ~500-700 lines of code per file
- Split larger files into focused modules
- Exceptions for complex modules (with justification)
Product Naming
- Product name: "OpenClaw" - Used in user-facing messages and documentation
- CLI/config/paths: "openclaw" - Used in commands, config files, and directory names
Examples:
Error Handling Patterns
Use formatErrorMessage() with Automatic Redaction
The codebase uses a centralized error formatting function that automatically redacts sensitive information.
Pattern observed:
Automatic Redaction
formatErrorMessage() automatically calls redactSensitiveText() to remove:
- API keys
- Tokens
- Passwords
- File paths (partially redacted)
Barrel Exports
Selective, Not Universal
The codebase uses barrel exports (index.ts) selectively:
- Some modules have
index.ts- Re-exporting public APIs - Some modules don't - Direct imports from specific files
Not a universal pattern - Check existing module structure before adding barrel exports.
Running Linting and Formatting
Pre-Commit Hooks
Pre-commit hooks (installed via prek install) automatically run Oxlint and Oxfmt before commits. See PR and Commit Conventions for details.
Why This Matters
Following these conventions ensures:
- CI passes - Linting and formatting checks are part of CI
- Consistency - Code looks the same across the entire codebase
- Type safety - Strict TypeScript catches bugs early
- Security - Automatic redaction prevents sensitive data leaks
- Reviewability - Consistent style makes code reviews easier
Cross-References
- Testing Patterns: Test file organization and structure
- PR and Commit Conventions: Pre-commit hooks and quality gates
- Error Handling Patterns (planned): Detailed error handling patterns