typescript
lobehub/lobe-chat
LobeHub TypeScript style and type-safety guide for consistent, type-safe code.
What is typescript?
A TypeScript code style guide for the LobeHub project covering type safety, async patterns, imports, code structure, and best practices. Use when editing TypeScript/TSX files, fixing type issues, choosing between interface and type, or handling async flows.
- Enforce type safety: avoid implicit any, use accurate types like Record over object/any
- Guide interface vs type selection: prefer interface for object shapes, type for unions/intersections
- Standardize imports: separate type imports with import type syntax, alphabetical sorting within statements
- Recommend async patterns: prefer async/await and promise-based APIs over callbacks and sync variants
- Enforce code structure: prefer named exports, object destructuring, and descriptive naming
- Integrate with LobeHub ecosystem: use @lobehub/ui components, antd-style tokens, and shared utils from packages/utils
How to install typescript
npx skills add https://github.com/lobehub/lobe-chat --skill typescriptHow to use typescript
- 1.Review the type safety section when writing or fixing TypeScript types in your code
- 2.Use separate import type statements for type-only imports, keeping them distinct from value imports
- 3.Apply async/await patterns instead of callbacks or .then() chains for new async code
- 4.Check packages/utils before creating local helper functions; reuse existing utilities
- 5.Use named exports by default; reserve export default for framework-required files like Next.js pages
Use cases
- Fixing TypeScript compilation errors and type mismatches in LobeHub codebase
- Refactoring existing code to follow consistent import and type declaration patterns
- Designing extensible types using module augmentation instead of namespace patterns
- Choosing between interface and type definitions for new React components or data structures
- Implementing async operations using async/await and Promise utilities for concurrent operations
- TypeScript developers contributing to LobeHub projects
- Teams enforcing consistent code style across a monorepo
- Developers migrating code to follow strict type-safety practices
- Contributors working with React components and UI code
typescript FAQ
Prefer interface for object shapes (e.g., React props); use type for unions, intersections, and other complex type constructs.
Always use import type { ... } for type-only imports as a separate statement. If you need both type and value imports from the same package, keep them as two separate import statements.
Prefer @ts-expect-error over @ts-ignore, and avoid as any. Use @ts-expect-error only when necessary and document why.
Prefer async/await over callbacks or .then() chains. Also prefer async APIs over sync ones (e.g., import from fs/promises instead of fs).
Search packages/utils first before creating local helpers. If a utility already exists or belongs there, import it from @lobechat/utils instead of duplicating code.
Full instructions (SKILL.md)
Source of truth, from lobehub/lobe-chat.
name: typescript description: 'LobeHub TypeScript style and type-safety guide. Use when editing TS/TSX/MTS, fixing types, choosing interface vs type, avoiding any/object, import type, async flow, or ts-expect-error.' user-invocable: false
TypeScript Code Style Guide
Types and Type Safety
- Avoid explicit type annotations when TypeScript can infer
- Avoid implicitly
any; explicitly type when necessary - Use accurate types: prefer
Record<PropertyKey, unknown>overobjectorany - Prefer
interfacefor object shapes (e.g., React props); usetypefor unions/intersections - Prefer
as const satisfies XyzInterfaceover plainas const - Prefer
@ts-expect-errorover@ts-ignoreoveras any - Avoid meaningless null/undefined parameters; design strict function contracts
- Prefer ES module augmentation (
declare module '...') overnamespace; do not introducenamespace-based extension patterns - When a type needs extensibility, expose a small mergeable interface at the source type and let each feature/plugin augment it locally instead of centralizing all extension fields in one registry file
- For package-local extensibility patterns like
PipelineContext.metadata, define the metadata fields next to the processor/provider/plugin that reads or writes them
Async Patterns
- Prefer
async/awaitover callbacks or.then()chains - Prefer async APIs over sync ones (avoid
*Sync) - Use promise-based variants:
import { readFile } from 'fs/promises' - Use
Promise.all,Promise.racefor concurrent operations where safe
Imports
-
This project uses
simple-import-sort/importsandconsistent-type-imports(fixStyle: 'separate-type-imports') -
Separate type imports: always use
import type { ... }for type-only imports, NOTimport { type ... }inline syntax -
When a file already has
import type { ... }from a package and you need to add a value import, keep them as two separate statements:import type { ChatTopicBotContext } from '@lobechat/types'; import { RequestTrigger } from '@lobechat/types'; -
Within each import statement, specifiers are sorted alphabetically by name
Code Structure
- Prefer object destructuring
- Use consistent, descriptive naming; avoid obscure abbreviations
- Replace magic numbers/strings with well-named constants
- Defer formatting to tooling
- Prefer named exports over
export default— keeps refactor renames and IDE auto-import in sync, and avoids thedefaultre-naming drift you get withimport Foo from './foo'. Reserveexport defaultfor files where the framework requires it (Next.js page/route/layout, React.lazy targets, config files likevitest.config.ts) - Before adding local helpers for common guards/parsing/normalization (record checks, string extraction, empty-string handling, timing helpers, JSON-safe utilities, etc.), search
packages/utilsfirst. If the helper already exists or clearly belongs there, import it from@lobechat/utils(or the relevant@lobechat/utils/*subpath) instead of duplicating tiny helpers across feature files.
UI and Theming
- Use
@lobehub/ui, Ant Design components instead of raw HTML tags - Design for dark mode and mobile responsiveness
- Use
antd-styletoken system instead of hard-coded colors
Performance
- Reuse existing utils in
packages/utilsor installed npm packages - Query only required columns from database
Time Consistency
- Assign
Date.now()to a constant once and reuse for consistency
Logging
- Never log user private information (API keys, etc.)
- Don't use
import { log } from 'debug'directly (logs to console) - Use
console.errorin catch blocks instead of debug package - Always log the error in
.catch()callbacks — silent.catch(() => fallback)swallows failures and makes debugging impossible
Related skills
More from lobehub/lobe-chat and the wider catalog.

zustand
LobeHub Zustand state management conventions for store slices, actions, and optimistic updates.

drizzle
Drizzle ORM schema and query patterns for PostgreSQL databases in LobeChat.

hotkey
Add or edit LobeHub keyboard shortcuts with proper scoping, conflict detection, and i18n support.

i18n
Manage multilingual UI strings in LobeHub using react-i18next with flat key conventions.

add-provider-doc
Add documentation for a new AI provider with usage guides, environment variables, Docker config, and image resources.

add-setting-env
Add server-side environment variables to control default values for user settings.