Formatting with Biome
Gorkie uses Biome for code formatting and linting. The configuration enforces:- 2 spaces for indentation (not tabs)
- Single quotes for strings
- Always include semicolons
Auto-formatting
Format your code before committing:TypeScript Conventions
Strict Mode
The project uses TypeScript in strict mode with additional checks:Type-Only Imports
Useimport type for type-only imports (enforced by verbatimModuleSyntax):
Path Alias
The~/ alias references the server/ directory:
Import Patterns
Import Order
- External packages (from
node_modules) - Internal modules (using
~/alias) - Type-only imports last
No Unused Imports
Unused imports are treated as errors. Remove them:Naming Conventions
Files
Use kebab-case for file names:Variables and Functions
Use camelCase:Types and Interfaces
Use PascalCase:Exports
Prefer named exports over default exports:Type Definitions
Slack Event Properties
Cast Slack event properties when accessing dynamic fields:Explicit Return Types
Use explicit return types for exported functions when they enhance clarity:Error Handling Patterns
Structured Error Logging
Log errors with structured context data:Return Structured Errors
Return structured error objects from tools:Early Returns
Prefer early returns over nested conditionals:Async Patterns
Consistent Async/Await
Always useasync/await instead of promise chains:
Parallel Operations
UsePromise.all for independent parallel operations:
Fire-and-Forget
Usevoid prefix for fire-and-forget promises:
Slack API Patterns
Always Check for Undefined
Slack event properties may be undefined:Use WebClient from Context
Always use theWebClient from the message context:
Environment Variables
Define in env.ts
All environment variables must be defined inserver/env.ts using Zod schemas:
Access via env Object
Never useprocess.env directly. Import and use the validated env object:
Logging
Structured Logging
Use the Pino logger with structured context:Log Levels
logger.debug()- Verbose debugging informationlogger.info()- General informational messageslogger.warn()- Warning messages for potential issueslogger.error()- Error messages for failures
Core Principles
Type Safety
- Use explicit types for function parameters and return values
- Prefer
unknownoveranywhen the type is genuinely unknown - Use const assertions (
as const) for immutable values - Leverage TypeScript’s type narrowing instead of type assertions
Modern JavaScript/TypeScript
- Use arrow functions for callbacks and short functions
- Prefer
for...ofloops over.forEach()and indexedforloops - Use optional chaining (
?.) and nullish coalescing (??) - Prefer template literals over string concatenation
- Use destructuring for object and array assignments
- Use
constby default,letonly when reassignment is needed, nevervar
Clean Code
- Keep functions focused with low cognitive complexity
- Extract complex conditions into well-named boolean variables
- Use early returns to reduce nesting
- Prefer simple conditionals over nested ternary operators
- Group related code together and separate concerns
Security
- Validate and sanitize user input
- Don’t use
eval()or assign directly todocument.cookie - All bot responses must be SFW (enforced at multiple levels)
What Biome Can’t Help With
Focus on what the linter can’t check:- Business logic correctness - Biome can’t validate your algorithms
- Meaningful naming - Use descriptive names for functions, variables, and types
- Architecture decisions - Component structure, data flow, and API design
- Edge cases - Handle boundary conditions and error states
- Documentation - Add comments for complex logic, but prefer self-documenting code