Aller au contenu

Framework backend 100 % Bun

Le backend
à son zénith.

L’ergonomie des décorateurs — contrôleurs, injection de dépendances, cycle de vie — compilée vers la table de routes native de Bun.serve. Le code expressif, l’ombre en moins.

Lire la documentation

Préversion — en attendant la publication npm, lancez le scaffolder depuis le monorepo.

src/main.ts
import { Zenith, Controller, Get } from "zenith";

@Controller("/")
class AppController {
  @Get()
  hello() {
    return { message: "Hello from Zenith" };
  }
}

new Zenith({ controllers: [AppController] }).listen(3000);

douze lignes → une table de routes native, servie par le routeur radix en Zig

dépendance runtime dans le cœur
0
dépendance runtime dans le cœur
réflexion par requête
0
réflexion par requête
plugins officiels, du CORS à Docker
9
plugins officiels, du CORS à Docker
types de la route au navigateur
E2E
types de la route au navigateur

Zéro coût à l’exécution

À midi, les ombres
sont courtes.

Chaque couche exécutée à chaque requête projette une ombre sur vos performances : réflexion, recomposition des middlewares, routage JavaScript. Zenith déplace ces coûts vers la compilation — au zénith, il n’en reste presque rien.

1reflect-metadata

lecture des types par requête

2routeur JS

matching des routes en JavaScript

3recomposition middleware

chaînes rebâties par requête

4résolution DI

graphe résolu par requête

Illustration du principe — la méthodologie et les chiffres vivent dans la page Performance.

La DX d’abord

Écrivez peu.
Tout est typé, tout est testé.

Du contrôleur au client, une seule source de vérité : le schéma valide l’entrée, infère les types, alimente l’OpenAPI et le client RPC.

Des classes décorées, compilées vers la table de routes native de Bun.serve. Le routage radix tourne en Zig, pas en JavaScript. En savoir plus →

todo.controller.ts
@Controller("/todos")
export class TodoController {
  static readonly inject: Deps<typeof TodoController> = [TodoService];
  constructor(private readonly todos: TodoService) {}

  @Get()
  list() {
    return this.todos.list(); // objet → JSON automatique
  }

  @Get("/:id")
  getOne(@Param("id") id: string) {
    const todo = this.todos.get(id);
    if (!todo) throw new NotFound(`Todo ${id} introuvable`);
    return todo;
  }

  @Post()
  create(@Body(CreateTodo) dto: CreateTodo) {
    return this.todos.create(dto.title);
  }
}

Les fondations

Quatre piliers,
aucun compromis.

Système de plugins

Un cœur minimal.
Le reste en orbite.

Le cœur ne fait que routing, DI et cycle de vie. Les neuf plugins officiels — CORS, sécurité, OpenAPI, JWT, Docker… — gravitent autour : vous n’embarquez que ce que vous utilisez.

Bun natif

Ce que vous
n’installez plus.

Si Bun expose une primitive native, Zenith l’utilise plutôt qu’une dépendance tierce. Serveur HTTP, base de données, cache, hachage, WebSockets : le node_modules fond au soleil.

Le catalogue complet des API Bun →
  • express / fastify Bun.serve
  • ws WebSockets natifs
  • uuid Bun.randomUUIDv7()
  • bcrypt / argon2 Bun.password
  • pg Bun.sql
  • ioredis Bun.redis
  • aws-sdk (S3) Bun.s3
  • dotenv Bun.env
  • reflect-metadata macros à la compilation

Passez au zénith.

Un scaffolder, un contrôleur, douze lignes — et une API typée de bout en bout tourne sur Bun.

Suivre le quick start