Skip to main content
LibreChat is joining ClickHouse to power the open-source Agentic Data Stack 🎉 Learn more
LibreChat

Code-standaarden en conventies

Codeerstandaarden, werkruimtegrenzen en conventies voor bijdragen aan LibreChat.

Workspace Boundaries

LibreChat is een monorepo. Alle nieuwe code moet gericht zijn op de juiste workspace:

WorkspaceTaalKantDoel
/apiJS (legacy)BackendExpress server — minimaliseer wijzigingen hier
/packages/apiTypeScriptBackendNieuwe backend-code bevindt zich hier (alleen TS, wordt verbruikt door /api)
/packages/data-schemasTypeScriptBackendDatabasemodellen/schema's en database-specifieke gedeelde logica
/packages/data-providerTypeScriptGedeeldAPI-types, endpoints, data-service — gebruikt door frontend en backend
/clientTypeScript/ReactFrontendFrontend SPA
/packages/clientTypeScriptFrontendGedeelde frontend-hulpprogramma's
  • Alle nieuwe backend-code moet TypeScript zijn in /packages/api.
  • Houd /api wijzigingen tot een absoluut minimum (dunne JS-wrappers die /packages/api aanroepen).
  • Database-specifieke gedeelde logica staat in /packages/data-schemas.
  • Gedeelde API-logica voor frontend/backend (endpoints, types, data-service) bevindt zich in /packages/data-provider.
  • Bouw alle gecompileerde code vanuit de project root: npm run build.
  • Bouw gedeelde data-provider code opnieuw op na API/type wijzigingen: npm run build:data-provider.

Algemene richtlijnen

  • Gebruik "clean code"-principes: houd functies en modules klein, hanteer het single responsibility principle en schrijf expressieve en leesbare code.
  • Gebruik betekenisvolle en beschrijvende namen voor variabelen en functies.
  • Geef prioriteit aan de leesbaarheid en onderhoudbaarheid van code boven beknoptheid.
  • Gebruik de meegeleverde .eslintrc en .prettierrc bestanden voor consistente code-opmaak.
  • Los alle opmaak-lintfouten op met behulp van auto-fix waar beschikbaar. Alle TypeScript/ESLint-waarschuwingen en -fouten moeten zijn opgelost.

Naamgeving en bestandsorganisatie

  • Gebruik waar mogelijk bestandsnamen van één woord, zoals permissions.ts, capabilities.ts of service.ts.
  • Wanneer meerdere woorden nodig zijn, heeft een map met één woord de voorkeur die context geeft aan het bestand, zoals admin/capabilities.ts in plaats van adminCapabilities.ts.
  • Laat de directory context bieden. Geef de voorkeur aan app/service.ts boven app/appConfigService.ts.

Codestructuur

  • Never-nesting: gebruik early returns, vlakke code, minimale inspringing. Splits complexe operaties op in goed benoemde helpers.
  • Functioneel eerst: pure functies, immutable data, map/filter/reduce boven imperatieve loops. Gebruik OOP alleen wanneer dit het domeinmodel of de inkapseling van de status duidelijk verbetert.
  • Geen dynamische imports tenzij absoluut noodzakelijk.
  • Extraheer herhaalde logica naar toegewezen utility-functies (DRY). Geef de voorkeur aan geparametriseerde helpers, constanten, gedeelde validators, gecentraliseerde foutafhandeling en gedeelde types boven bijna-duplicaat implementaties.

Iteratie en prestaties

  • Minimaliseer looping — vooral over gedeelde datastructuren zoals bericht-arrays, waar vaak overheen wordt geïtereerd. Elke extra doorloop telt op bij schaalvergroting.
  • Consolideer sequentiële O(n)-operaties waar mogelijk in één enkele doorloop; loop nooit twee keer over dezelfde collectie als het werk gecombineerd kan worden.
  • Kies datastructuren die de noodzaak om te itereren verminderen (bijv. Map/Set voor opzoekingen in plaats van Array.find/Array.includes).
  • Vermijd het onnodig aanmaken van objecten; overweeg de afwegingen tussen ruimte en tijd.
  • Voorkom geheugenlekken: wees voorzichtig met closures, ruim resources/event listeners op en vermijd circulaire referenties.

Type Safety

  • Gebruik nooit any. Expliciete types voor alle parameters, retourwaarden en variabelen.
  • Beperk unknown — vermijd unknown, Record<string, unknown> en as unknown as T assertions. Een Record<string, unknown> duidt bijna altijd op een ontbrekende expliciete typedefinitie.
  • Dupliceer geen types — controleer of een type al bestaat in het project (vooral in packages/data-provider) voordat je een nieuwe definieert. Hergebruik en breid bestaande types uit.
  • Gebruik union types, generics en interfaces op de juiste manier.

Opmerkingen en documentatie

  • Schrijf zelfdocumenterende code; gebruik geen inline-commentaar dat beschrijft wat de code doet.
  • JSDoc alleen voor complexe/niet-voor-de-hand-liggende logica of intellisense op publieke API's.
  • Single-line JSDoc voor beknopte documentatie, multi-line voor complexe gevallen.
  • Vermijd zelfstandige // commentaren tenzij absoluut noodzakelijk.

Importvolgorde

Imports zijn onderverdeeld in drie secties (in deze volgorde):

  1. Package imports — gesorteerd van kortste naar langste regel ( react is altijd de eerste import).
  2. import type imports — gesorteerd van lang naar kort (eerst pakket-types, daarna lokale types; lengtesortering wordt gereset tussen subgroepen).
  3. Lokale/project-imports — gesorteerd van langste naar kortste.
  • Consolideer waarde-imports uit dezelfde module zoveel mogelijk.
  • Gebruik altijd standalone import type { ... } voor type-imports; gebruik nooit het inline type trefwoord binnen waarde-imports (bijv. import { Foo, type Bar } is fout).

Loop-voorkeuren

  • Beperk lussen zoveel mogelijk. Geef de voorkeur aan transformaties in één doorgang en vermijd het herhaaldelijk doorlopen van dezelfde gegevens.
  • for (let i = 0; ...) voor prestatiekritieke of index-afhankelijke operaties.
  • for...of voor eenvoudige array-iteratie.
  • for...in alleen voor het opsommen van objecteigenschappen.

Node.js API-server

API-ontwerp

  • Volg RESTful-principes bij het ontwerpen van API's.
  • Gebruik betekenisvolle en beschrijvende namen voor routes, controllers, services en models.
  • Gebruik de juiste HTTP-methoden (GET, POST, PUT, DELETE) voor elke route.
  • Gebruik de juiste statuscodes en responsstructuren voor consistente API-antwoorden (2xx voor succes, 4xx voor een foutief verzoek van de client, 5xx voor een serverfout).
  • Gebruik try-catch-blokken om uitzonderingen op een correcte manier op te vangen en af te handelen.
  • Implementeer correcte foutafhandeling en retourneer consistent passende foutmeldingen.
  • Gebruik het logsysteem in de utils directory om belangrijke gebeurtenissen en fouten te loggen.
  • Voer JWT-gebaseerde, stateless authenticatie uit met behulp van de requireJWTAuth middleware.

Bestandsstructuur

Nieuwe backend-code komt in /packages/api als TypeScript. De legacy /api directory volgt deze structuur:

Routes

Specificeert elke HTTP-requestmethode, eventuele te gebruiken middleware en de controllerfunctie die voor elke route moet worden aangeroepen.

  • Definieer routes met behulp van de Express Router in afzonderlijke bestanden voor elke resource of logische groepering.
  • Gebruik beschrijvende routenamen en houd je aan RESTful-conventies.
  • Houd routes beknopt en gericht op één enkele verantwoordelijkheid.
  • Voorzie alle routes van het /api namespace-voorvoegsel.

Controllers

Bevat de logica voor elke route, inclusief het aanroepen van de juiste servicefuncties en het retourneren van de juiste respons-statuscode en JSON-body.

  • Maak een apart controller-bestand voor elke route om de request/response-logica af te handelen.
  • Geef controllerbestanden een naam volgens de PascalCase-conventie en voeg "Controller" toe aan de bestandsnaam (bijv. UserController.js).
  • Houd controllers slank door complexe operaties te delegeren aan service- of modelbestanden.

Services

Bevat complexe bedrijfslogica of bewerkingen die worden gedeeld door meerdere controllers.

  • Geef servicebestanden een naam volgens de PascalCase-conventie en voeg "Service" toe aan de bestandsnaam (bijv. AuthService.js).
  • Vermijd het nauw koppelen van services aan specifieke modellen of databases voor een betere herbruikbaarheid.
  • Handhaaf het principe van een enkele verantwoordelijkheid binnen elke service.

Modellen

Definieert Mongoose-modellen om data-entiteiten en hun relaties weer te geven.

  • Gebruik enkelvoudige, PascalCase namen voor modelbestanden en hun bijbehorende collecties (bijv. User.js en users collectie).
  • Neem alleen de noodzakelijke velden, indexen en validaties op in de models.
  • Houd modellen onafhankelijk van de API-laag door directe verwijzingen naar request/response-objecten te vermijden.

Databasetoegang (MongoDB en Mongoose)

  • Gebruik Mongoose (https://mongoosejs.com) als de MongoDB ODM.
  • Maak afzonderlijke modelbestanden voor elke entiteit en zorg voor een duidelijke scheiding van verantwoordelijkheden.
  • Gebruik Mongoose schema-validatie om gegevensintegriteit af te dwingen.
  • Beheer databaseverbindingen efficiënt en voorkom verbindingslekken.
  • Gebruik Mongoose query builders om beknopte en leesbare database-queries te maken.

React Client

Algemene TypeScript en React best practices

  • Gebruik TypeScript best practices om te profiteren van statische typering en verbeterde tooling.
  • Groepeer gerelateerde bestanden in feature-mappen (bijv. SidePanel/Memories/).
  • Geef componenten een naam volgens de PascalCase-conventie.
  • Gebruik beknopte en beschrijvende namen die het doel van de component nauwkeurig weergeven.
  • Splits complexe componenten in kleinere, herbruikbare componenten wanneer dit gepast is.
  • Houd de rendering-logica binnen componenten minimaal.
  • Extraheer herbruikbare onderdelen naar afzonderlijke functies of hooks.
  • Pas prop type-definities toe met behulp van TypeScript types of interfaces.
  • Gebruik formuliervalidatie waar van toepassing (we gebruiken React Hook Form voor formuliervalidatie en verzending).

Lokalisatie

  • Alle tekst die voor de gebruiker zichtbaar is, moet worden gelokaliseerd met behulp van de useLocalize() hook.
  • Update alleen de Engelse sleutels in client/src/locales/en/translation.json (andere talen worden extern geautomatiseerd).
  • Gebruik semantische lokalisatiesleutel-voorvoegsels: com_ui_, com_assistants_, enz.
  • Zorg er altijd voor dat er zinvolle fallback-tekst is voor nieuwe lokalisatiesleutels.

Data Services

  • Maak data provider hooks aan in client/src/data-provider/[Feature]/queries.ts.
  • Exporteer alle hooks vanuit client/src/data-provider/[Feature]/index.ts.
  • Voeg feature-exports toe aan de hoofd client/src/data-provider/index.ts.
  • Gebruik React Query (@tanstack/react-query) voor alle API-interacties.
  • Implementeer correcte query-invalidation bij mutations.
  • Voeg QueryKeys en MutationKeys toe aan packages/data-provider/src/keys.ts.

Bij het toevoegen van gedeelde API-integratie, update:

  • packages/data-provider/src/api-endpoints.ts (endpoints)
  • packages/data-provider/src/data-service.ts (data service functies)
  • packages/data-provider/src/types/queries.ts (TypeScript-types)

Prestaties

  • Geef prioriteit aan geheugen- en snelheidsefficiëntie op schaal.
  • Implementeer de juiste cursor-paginering voor grote datasets.
  • Vermijd onnodige re-renders met de juiste dependency arrays.
  • Maak gebruik van de caching- en achtergrond-refetching-functies van React Query.

Testen en documentatie

  • Schrijf unit tests voor alle kritieke en complexe functionaliteiten met behulp van Jest.
  • Schrijf integratietests voor alle API-endpoints met behulp van Supertest.
  • Schrijf end-to-end tests voor alle client-side functionaliteiten met behulp van Playwright.
  • Gebruik beschrijvende testcase- en functienamen om het doel van de test duidelijk uit te drukken.
  • Voer tests uit vanuit hun werkmap: cd api && npx jest <pattern>, cd packages/api && npx jest <pattern>, enz.
  • Dek laad-, succes- en foutstatussen voor UI/data-flows.
  • Gebruik test/layout-test-utils voor het renderen van componenten in frontend-tests.
  • Geef de voorkeur aan echte logica boven mocks. Mock alleen wat niet lokaal kan worden beheerd, zoals externe HTTP API's, diensten met rate-limiting en niet-deterministische systeemaanroepen.
  • Gebruik spies wanneer je aanroepen wilt verifiëren zonder de onderliggende implementatie te vervangen.
  • Gebruik mongodb-memory-server voor tests die gebaseerd zijn op MongoDB, zodat queries en schema-validatie het gedrag van een echte database simuleren.

Hoe is deze gids?