mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-02-20 09:24:10 +01:00
* 📝 docs: Add AGENTS.md for project structure and coding standards
- Introduced AGENTS.md to outline project workspaces, coding standards, and development commands.
- Defined workspace boundaries for backend and frontend development, emphasizing TypeScript usage.
- Established guidelines for code style, iteration performance, type safety, and import order.
- Updated CONTRIBUTING.md to reference AGENTS.md for coding standards and project conventions.
- Modified package.json to streamline build commands, consolidating frontend and backend build processes.
* chore: Update build commands and improve smart reinstall process
- Modified AGENTS.md to clarify the purpose of `npm run smart-reinstall` and other build commands, emphasizing Turborepo's role in dependency management and builds.
- Updated package.json to streamline build commands, replacing the legacy frontend build with a Turborepo-based approach for improved performance.
- Enhanced the smart reinstall script to fully delegate build processes to Turborepo, including cache management and dependency checks, ensuring a more efficient build workflow.
7.6 KiB
7.6 KiB
LibreChat
Project Overview
LibreChat is a monorepo with the following key workspaces:
| Workspace | Language | Side | Dependency | Purpose |
|---|---|---|---|---|
/api |
JS (legacy) | Backend | packages/api, packages/data-schemas, packages/data-provider, @librechat/agents |
Express server — minimize changes here |
/packages/api |
TypeScript | Backend | packages/data-schemas, packages/data-provider |
New backend code lives here (TS only, consumed by /api) |
/packages/data-schemas |
TypeScript | Backend | packages/data-provider |
Database models/schemas, shareable across backend projects |
/packages/data-provider |
TypeScript | Shared | — | Shared API types, endpoints, data-service — used by both frontend and backend |
/client |
TypeScript/React | Frontend | packages/data-provider, packages/client |
Frontend SPA |
/packages/client |
TypeScript | Frontend | packages/data-provider |
Shared frontend utilities |
The source code for @librechat/agents (major backend dependency, same team) is at /home/danny/agentus.
Workspace Boundaries
- All new backend code must be TypeScript in
/packages/api. - Keep
/apichanges to the absolute minimum (thin JS wrappers calling into/packages/api). - Database-specific shared logic goes in
/packages/data-schemas. - Frontend/backend shared API logic (endpoints, types, data-service) goes in
/packages/data-provider. - Build data-provider from project root:
npm run build:data-provider.
Code Style
Structure and Clarity
- Never-nesting: early returns, flat code, minimal indentation. Break complex operations into well-named helpers.
- Functional first: pure functions, immutable data,
map/filter/reduceover imperative loops. Only reach for OOP when it clearly improves domain modeling or state encapsulation. - No dynamic imports unless absolutely necessary.
DRY
- Extract repeated logic into utility functions.
- Reusable hooks / higher-order components for UI patterns.
- Parameterized helpers instead of near-duplicate functions.
- Constants for repeated values; configuration objects over duplicated init code.
- Shared validators, centralized error handling, single source of truth for business rules.
- Shared typing system with interfaces/types extending common base definitions.
- Abstraction layers for external API interactions.
Iteration and Performance
- Minimize looping — especially over shared data structures like message arrays, which are iterated frequently throughout the codebase. Every additional pass adds up at scale.
- Consolidate sequential O(n) operations into a single pass whenever possible; never loop over the same collection twice if the work can be combined.
- Choose data structures that reduce the need to iterate (e.g.,
Map/Setfor lookups instead ofArray.find/Array.includes). - Avoid unnecessary object creation; consider space-time tradeoffs.
- Prevent memory leaks: careful with closures, dispose resources/event listeners, no circular references.
Type Safety
- Never use
any. Explicit types for all parameters, return values, and variables. - Limit
unknown— avoidunknown,Record<string, unknown>, andas unknown as Tassertions. ARecord<string, unknown>almost always signals a missing explicit type definition. - Don't duplicate types — before defining a new type, check whether it already exists in the project (especially
packages/data-provider). Reuse and extend existing types rather than creating redundant definitions. - Use union types, generics, and interfaces appropriately.
- All TypeScript and ESLint warnings/errors must be addressed — do not leave unresolved diagnostics.
Comments and Documentation
- Write self-documenting code; no inline comments narrating what code does.
- JSDoc only for complex/non-obvious logic or intellisense on public APIs.
- Single-line JSDoc for brief docs, multi-line for complex cases.
- Avoid standalone
//comments unless absolutely necessary.
Import Order
Imports are organized into three sections:
- Package imports — sorted shortest to longest line length (
reactalways first). import typeimports — sorted longest to shortest (package types first, then local types; length resets between sub-groups).- Local/project imports — sorted longest to shortest.
Multi-line imports count total character length across all lines. Consolidate value imports from the same module. Always use standalone import type { ... } — never inline type inside value imports.
JS/TS Loop Preferences
- Limit looping as much as possible. Prefer single-pass transformations and avoid re-iterating the same data.
for (let i = 0; ...)for performance-critical or index-dependent operations.for...offor simple array iteration.for...inonly for object property enumeration.
Frontend Rules (client/src/**/*)
Localization
- All user-facing text must use
useLocalize(). - Only update English keys in
client/src/locales/en/translation.json(other languages are automated externally). - Semantic key prefixes:
com_ui_,com_assistants_, etc.
Components
- TypeScript for all React components with proper type imports.
- Semantic HTML with ARIA labels (
role,aria-label) for accessibility. - Group related components in feature directories (e.g.,
SidePanel/Memories/). - Use index files for clean exports.
Data Management
- Feature hooks:
client/src/data-provider/[Feature]/queries.ts→[Feature]/index.ts→client/src/data-provider/index.ts. - React Query (
@tanstack/react-query) for all API interactions; proper query invalidation on mutations. - QueryKeys and MutationKeys in
packages/data-provider/src/keys.ts.
Data-Provider Integration
- Endpoints:
packages/data-provider/src/api-endpoints.ts - Data service:
packages/data-provider/src/data-service.ts - Types:
packages/data-provider/src/types/queries.ts - Use
encodeURIComponentfor dynamic URL parameters.
Performance
- Prioritize memory and speed efficiency at scale.
- Cursor pagination for large datasets.
- Proper dependency arrays to avoid unnecessary re-renders.
- Leverage React Query caching and background refetching.
Development Commands
| Command | Purpose |
|---|---|
npm run smart-reinstall |
Install deps (if lockfile changed) + build via Turborepo |
npm run reinstall |
Clean install — wipe node_modules and reinstall from scratch |
npm run backend |
Start the backend server |
npm run backend:dev |
Start backend with file watching (development) |
npm run build |
Build all compiled code via Turborepo (parallel, cached) |
npm run frontend |
Build all compiled code sequentially (legacy fallback) |
npm run frontend:dev |
Start frontend dev server with HMR (port 3090, requires backend running) |
npm run build:data-provider |
Rebuild packages/data-provider after changes |
- Node.js: v20.19.0+ or ^22.12.0 or >= 23.0.0
- Database: MongoDB
- Backend runs on
http://localhost:3080/; frontend dev server onhttp://localhost:3090/
Testing
- Framework: Jest, run per-workspace.
- Run tests from their workspace directory:
cd api && npx jest <pattern>,cd packages/api && npx jest <pattern>, etc. - Frontend tests:
__tests__directories alongside components; usetest/layout-test-utilsfor rendering. - Cover loading, success, and error states for UI/data flows.
- Mock data-provider hooks and external dependencies.
Formatting
Fix all formatting lint errors (trailing spaces, tabs, newlines, indentation) using auto-fix when available. All TypeScript/ESLint warnings and errors must be resolved.