Code Formatting
We use Biome for linting and formatting. Configuration is inbiome.json at the project root.
Running Biome
Biome Configuration
Key settings frombiome.json:
- 4 spaces for indentation (not tabs)
- 100 character line width
- Single quotes for JavaScript/TypeScript
- Double quotes for JSX attributes
- Always use semicolons
- Always use trailing commas
- Always use parentheses around arrow function parameters
TypeScript
Strict Mode
Always use TypeScript strict mode:Type Safety
DO:- Use explicit types for function parameters and return values
- Use
unknowninstead ofanywhen type is truly unknown - Use type guards to narrow types
- Export types from their defining module
Interfaces vs Types
- Use interfaces for object shapes
- Use type aliases for unions, primitives, and utility types
Enums
Use string enums with initializers:File Organization
File Structure
Naming Conventions
-
Files: PascalCase for classes, camelCase for utilities
ThemeManager.ts(class)logger.ts(utility)index.ts(barrel export)
-
Classes: PascalCase
-
Interfaces: PascalCase with
Iprefix for implementations -
Functions: camelCase
-
Constants: UPPER_SNAKE_CASE for true constants
-
Variables: camelCase
Imports
Import order:- External packages
- Internal packages (from
@inkdown/) - Relative imports (same package)
- Type imports (at the end)
Styling
CSS Files
ALWAYS use external CSS files, never inline styles:CSS Variables
ALWAYS use CSS variables for colors and theme values:CSS Organization
Comments
When to Comment
DO comment:- Complex algorithms or logic
- Non-obvious workarounds
- Public APIs (JSDoc)
- Type definitions
- Obvious code
- What the code does (code should be self-documenting)
JSDoc
Use JSDoc for public APIs:Code Organization
Class Structure
Function Length
Keep functions focused and small:- Maximum ~50 lines per function
- Extract complex logic into helper functions
- One function, one purpose
Cross-Platform Guidelines
Platform Abstraction
Never access platform-specific APIs directly in core code:UI Abstraction
Always use UIBridge for UI operations:Error Handling
Result Type
Use theResult type for operations that can fail:
AppError
UseAppError for application-specific errors:
Performance
Memoization
Memoize expensive computations:Debouncing
Debounce frequent operations:Testing
See Testing Guide for detailed testing practices.Linting Rules
Key Rules
- No unused variables/imports (warning)
- No
anytype (disabled, useunknown) - No
console.login production code (off in dev) - Exhaustive dependency arrays for React hooks
- No implicit boolean attributes
Overrides
Test files have relaxed rules:Pre-commit Checklist
Before committing, ensure:Summary
- Use Biome for formatting and linting
- Follow TypeScript strict mode
- Use CSS files with CSS variables for styling
- Write self-documenting code with JSDoc for public APIs
- Use platform abstractions (NativeBridge, UIBridge)
- Keep functions small and focused
- Handle errors with Result type or AppError
- Always run
bun run checkbefore committing
