Architecture Intermediaire

Architecture d'EmDash : comprendre le CMS de demain

Plongee technique dans l'architecture d'EmDash, le CMS serverless open-source construit sur Astro 6.0. Decouvrez la structure du monorepo, le pattern d'integration Astro, la chaine de middlewares et le systeme de base de donnees.

E
Equipe EmDash FR
|
#emdash #architecture #astro #cloudflare #serverless #monorepo

Architecture d’EmDash : comprendre le CMS de demain

EmDash n’est pas simplement un autre CMS. C’est une refonte complete de ce que devrait etre un systeme de gestion de contenu a l’ere du serverless. Cree par Matt Kane chez Cloudflare, EmDash repose sur une architecture moderne qui tire parti d’Astro 6.0, de Cloudflare Workers et d’une approche monorepo soigneusement orchestree. Dans ce guide, nous allons dissequer chaque couche de cette architecture pour comprendre pourquoi EmDash represente un tournant dans l’histoire des CMS.

La structure du monorepo

Le code source d’EmDash est organise en monorepo, une approche qui permet de maintenir tous les packages dans un seul depot tout en preservant une separation claire des responsabilites. Voici la structure principale :

emdash/
├── packages/
│   ├── core/          # Le coeur du CMS
│   ├── admin/         # Interface d'administration
│   ├── auth/          # Systeme d'authentification
│   ├── blocks/        # Blocs de contenu Portable Text
│   ├── cloudflare/    # Adaptateur Cloudflare Workers
│   ├── cli/           # Outil en ligne de commande
│   ├── db/            # Couche base de donnees (Kysely)
│   ├── media/         # Gestion des medias
│   ├── plugins/       # [Systeme de plugins](/guides/securite-plugins)
│   └── mcp/           # [Serveur Model Context Protocol](/guides/mcp-server-emdash)
├── apps/
│   ├── docs/          # Documentation officielle
│   └── playground/    # Environnement de test
└── templates/         # Templates de demarrage

Chaque package est autonome avec ses propres dependances, ses tests et sa configuration TypeScript. Le gestionnaire de packages utilise les workspaces pour lier les packages entre eux lors du developpement, ce qui permet de travailler sur plusieurs composants simultanement sans publier de versions intermediaires.

Le package core

C’est le coeur nevralgique d’EmDash. Il contient la logique metier fondamentale : la definition des collections, la gestion des schemas, le routage du contenu et l’orchestration des middlewares. Le core est volontairement agnostique vis-a-vis de la plateforme de deploiement — il ne fait aucune hypothese sur l’environnement d’execution, ce qui ouvre la porte a de futurs adaptateurs au-dela de Cloudflare.

Le package admin

L’interface d’administration est une application Astro a part entiere qui s’integre dans le site principal via un montage de route. Elle utilise des composants React pour l’editeur de contenu (base sur TipTap) et offre une experience utilisateur moderne avec un design systeme coherent. L’admin est concu pour etre entierement personnalisable : vous pouvez remplacer n’importe quel composant de l’interface par le votre.

Le package cloudflare

Cet adaptateur fait le pont entre le core d’EmDash et l’infrastructure Cloudflare. Il gere la connexion a D1 (la base de donnees SQLite distribuee de Cloudflare), R2 (le stockage d’objets pour les medias), et Workers KV (pour le cache). C’est ce package qui transforme EmDash d’une application Node.js classique en une application edge-native qui s’execute au plus pres de vos utilisateurs.

Le pattern d’integration Astro

EmDash s’integre dans Astro de maniere elegante grace au systeme d’integrations d’Astro 6.0. Plutot que d’etre un framework independant qui impose ses conventions, EmDash est une integration Astro que vous ajoutez a votre projet existant :

// astro.config.mjs
import { defineConfig } from 'astro/config';
import emdash from '@emdash-cms/astro';

export default defineConfig({
  integrations: [
    emdash({
      collections: './src/collections',
      plugins: ['@emdash-cms/plugin-seo', '@emdash-cms/plugin-analytics'],
    }),
  ],
});

Cette approche a plusieurs avantages majeurs. Premierement, vous conservez le controle total de votre projet Astro : les routes, les layouts, les composants — tout reste sous votre responsabilite. EmDash ne fait qu’ajouter une couche de gestion de contenu par-dessus.

Deuxiemement, vous beneficiez de tout l’ecosysteme Astro. Les centaines d’integrations existantes (Tailwind, MDX, Sitemap, etc.) fonctionnent parfaitement avec EmDash. Vous ne sacrifiez rien en adoptant ce CMS.

Troisiemement, les mises a jour d’Astro et d’EmDash sont independantes. Vous pouvez mettre a jour l’un sans affecter l’autre, ce qui reduit considerablement le risque de regressions.

La chaine de middlewares

L’une des pieces les plus elegantes de l’architecture d’EmDash est sa chaine de middlewares. Chaque requete traversant le CMS passe par une serie d’etapes soigneusement ordonnees :

1. Runtime Init (Initialisation de l’environnement)

La premiere etape consiste a initialiser l’environnement d’execution. Sur Cloudflare Workers, cela signifie lier les ressources (D1, R2, KV) et configurer le contexte d’execution. Cette etape garantit que tous les services sont disponibles avant de traiter la moindre requete.

// Simplifie pour illustration
async function runtimeInit(context) {
  context.db = createDatabase(context.env.DB);
  context.storage = createStorage(context.env.R2_BUCKET);
  context.cache = createCache(context.env.KV_CACHE);
  return next(context);
}

2. Setup (Configuration dynamique)

L’etape de setup charge la configuration du site depuis la base de donnees. Cela inclut les schemas de collections, les parametres du site, les plugins actifs et leurs configurations respectives. Cette approche permet de modifier la configuration sans redeployer le site.

3. Auth (Authentification et autorisation)

Le middleware d’authentification verifie les identifiants de l’utilisateur. EmDash utilise les passkeys (WebAuthn) comme methode d’authentification principale, eliminant completement les mots de passe traditionnels. Ce middleware determine aussi les permissions de l’utilisateur et les injecte dans le contexte de la requete.

4. Request Context (Contexte de requete)

La derniere etape construit le contexte complet de la requete, incluant les informations de l’utilisateur, les donnees du site, les helpers d’acces aux collections et les utilitaires de rendu. Ce contexte est ensuite disponible dans tous les composants Astro via Astro.locals.

// Dans un composant Astro
---
const { cms } = Astro.locals;
const articles = await cms.collection('articles').findMany({
  where: { status: 'published' },
  orderBy: { publishedAt: 'desc' },
  limit: 10,
});
---

La beaute de cette chaine est qu’elle est entierement composable. Vous pouvez inserer vos propres middlewares entre n’importe quelles etapes, ou remplacer une etape existante par votre propre implementation.

La base de donnees : du vrai SQL avec Kysely

Contrairement a beaucoup de CMS headless qui s’appuient sur des API tierces ou des bases de donnees NoSQL, EmDash utilise de vraies tables SQL pour stocker le contenu. Chaque collection que vous definissez dans votre schema se traduit en une table SQLite sur Cloudflare D1.

EmDash utilise Kysely comme query builder TypeScript. Kysely offre une API fluide et entierement typee pour construire des requetes SQL, ce qui signifie que les erreurs de requete sont detectees a la compilation plutot qu’a l’execution.

// Definition d'une collection
export const articles = defineCollection({
  name: 'articles',
  fields: {
    title: field.text({ required: true }),
    slug: field.slug({ from: 'title' }),
    content: field.portableText(),
    author: field.relation('authors'),
    publishedAt: field.datetime(),
    tags: field.array(field.text()),
    featured: field.boolean({ default: false }),
  },
});

Cette definition genere automatiquement :

  • Une table SQL articles avec les colonnes appropriees
  • Les types TypeScript correspondants
  • Les migrations necessaires pour mettre a jour le schema
  • Les validations cote serveur

L’avantage de D1 est qu’il s’agit d’une base SQLite distribuee globalement. Vos donnees sont repliquees sur le reseau edge de Cloudflare, ce qui signifie des lectures extremement rapides depuis n’importe quel point du globe. Les ecritures passent par un noeud primaire, mais le systeme de replication assure une coherence eventuelle quasi-instantanee.

Portable Text pour le contenu

EmDash a fait le choix audacieux d’adopter Portable Text comme format de stockage du contenu riche. Plutot que de stocker du HTML serialise (comme WordPress) ou du Markdown (comme Hugo), le contenu est stocke sous forme de JSON structure.

Ce choix architectural a des implications profondes. Le contenu n’est plus lie a un mode de rendu specifique. Le meme contenu peut etre rendu en HTML pour le web, en composants natifs pour une application mobile, en texte brut pour un email, ou en n’importe quel autre format. La structure arborescente du JSON permet aussi des transformations et des analyses qui seraient impossibles ou tres couteuses avec du HTML.

Nous explorons ce sujet en profondeur dans notre guide dedie au Portable Text.

Conclusion

L’architecture d’EmDash est le resultat d’annees d’experience dans le developpement web et d’une reflexion approfondie sur les limites des CMS existants. En combinant la puissance d’Astro 6.0, la distribution globale de Cloudflare, la rigueur de TypeScript et des choix techniques modernes comme Portable Text et Kysely, EmDash pose les bases d’un CMS qui ne se contente pas de reproduire le passe, mais qui invente l’avenir de la gestion de contenu.

Chaque decision architecturale — du monorepo a la chaine de middlewares, du SQL type au Portable Text — a ete prise avec un objectif precis : offrir aux developpeurs un outil puissant, flexible et maintenable sur le long terme. C’est cette coherence architecturale qui fait d’EmDash bien plus qu’un simple concurrent de WordPress : c’est une nouvelle vision de ce que peut etre un CMS.

Pour aller plus loin