Plateformes

Les stacks par défaut pour le web, le mobile et le desktop, avec leur degré de preuve.

Version texte pour agents : /md/plateformes.md

Trois profils, chacun avec une stack par défaut. Un défaut n'est pas une obligation : c'est le point de départ que /architect discute, et qu'il ne remplace qu'avec une raison écrite dans la spec. Sans défaut, chaque projet rouvre les mêmes débats ; avec un défaut imposé, on force une stack là où elle ne convient pas.

Chaque profil dit aussi son degré de preuve. Un défaut éprouvé en production n'a pas le même poids qu'un défaut recommandé mais jamais livré.

ProfilDegré de preuve
Webéprouvé sur plusieurs projets en production
Mobilerecommandé, à éprouver sur un premier projet
Desktoprecommandé, à éprouver sur un premier projet

Dans tous les cas, les versions installées sont les versions courantes, vérifiées au moment de l'échafaudage (MF-013). Ce document ne fige aucun numéro de version, parce qu'un numéro écrit ici serait périmé avant d'être lu.

Web

CoucheDéfautQuand s'en écarter
FrameworkNext.js (App Router), TypeScript strictVite et React pour une application sans SEO ni rendu serveur
ArchitectureMaedow Arch, mode Light puis Full quand le domaine prend du poidsjamais pour un projet TypeScript
StyleTailwind CSS, primitives dans components/ui/un design system existant imposé
Données et authentificationSupabase (Postgres, Auth, Storage, RLS)Postgres et Drizzle quand le backend nous appartient, ou qu'un modèle d'accès complexe se tient mal en RLS
ValidationZod aux frontières (MF-007)aucune raison courante
TestsVitest, Playwright avec axe pour les parcours et l'accessibilitéaucune raison courante
HébergementVercel : un aperçu par pull request, la production depuis maincontrainte de souveraineté, de coût ou de réseau

Services, installés au moment où une feature en a besoin, pas avant : Resend (e-mails), PostHog (analytique, erreurs, flags), Upstash (limitation de débit, cache), Inngest (tâches de fond), Stripe (paiement).

Ce qui revient souvent :

  • TypeScript strict veut dire strict, noUncheckedIndexedAccess et exactOptionalPropertyTypes, dès le premier jour. Les activer plus tard coûte des centaines d'erreurs d'un coup.
  • En serverless, la connexion à Postgres passe par l'URL du pooler dès le premier jour (Tenir la charge).
  • Un projet Vercel neuf protège ses déploiements derrière une connexion Vercel. Un agent qui vérifie un aperçu (/check verify, curl) reçoit alors une page de connexion, pas l'application. Site public : désactiver la protection. Application privée : utiliser le secret de contournement pour l'automatisation, rangé avec les autres secrets (MF-006).
  • Lier le projet Vercel sans déploiement initial : le premier déploiement d'un projet neuf part en production, même depuis une branche de feature.
  • Un module qui manipule un secret porte import "server-only" (MA-008) : l'importer côté client casse le build au lieu de fuiter.
  • La qualité d'interface a ses propres skills (impeccable, better-interface) : ils s'invoquent pendant /develop sur le volet interface, pas à la place de lui.

Mobile

CoucheDéfautQuand s'en écarter
FrameworkExpo (React Native), Expo Router, TypeScript strictbesoin natif lourd que les modules Expo ne couvrent pas
ArchitectureMaedow Arch : core/ en TypeScript pur, partageable avec un projet webjamais
Données et authentificationle même backend que le web (Supabase par défaut)aucune raison courante
TestsJest avec jest-expo et React Native Testing Library ; Maestro pour les parcoursaucune raison courante
Build et distributionEAS Build, EAS Submit, EAS Update pour les correctifs JavaScriptaucune raison courante

Ce qui revient souvent :

  • Tout ce qui est embarqué dans l'application est public. Une clé dans le bundle est une clé publiée (MF-006). Les appels qui exigent un secret passent par le serveur.
  • Une mise à jour à distance (EAS Update) ne change que le JavaScript. Tout changement natif (module, permission, configuration) exige un nouveau build et une nouvelle soumission : la runtimeVersion doit suivre, sinon l'application reçoit un code qu'elle ne sait pas exécuter.
  • La validation des stores prend des jours. Une date de sortie se planifie avec cette marge.
  • Permissions système, liens profonds et notifications se testent sur un appareil réel avant GA.

Desktop

CoucheDéfautQuand s'en écarter
FrameworkTauri 2 : interface Vite, React et TypeScript, cœur Rust réduit au nécessaireElectron quand le produit dépend de l'écosystème Node côté système ou de modules natifs Node
ArchitectureMaedow Arch côté interface, commandes Rust fines côté systèmeaucune raison courante
Sécuritécapacités Tauri déclarées au plus juste : chaque fenêtre n'accède qu'à ce qu'elle utiliseaucune raison
Mises à jourle plugin updater de Tauri, mises à jour signéesaucune raison
TestsVitest pour l'interface ; WebDriver (tauri-driver) pour les parcours, sur Windows et Linuxaucune raison courante
BuildGitHub Actions avec tauri-action, une cible par systèmeaucune raison courante

Ce qui revient souvent :

  • La signature de code est un poste de coût et de délai : certificat pour Windows, compte développeur et notarisation pour macOS. Sans elle, le système avertit l'utilisateur à l'installation. À prévoir dès le scope, pas la veille de la sortie.
  • Avec Electron : contextIsolation activé, nodeIntegration désactivé, un script de préchargement minimal qui n'expose que des fonctions précises. Jamais le module fs entier.
  • L'interface d'une application desktop reste du web : les règles MF-007 et MF-008 valent entre l'interface et le cœur système, qui joue le rôle du serveur.

Ce qui ne change pas d'un profil à l'autre

Le cycle, les règles, le flux git, la commande verify, la CI, le kit. Un projet mobile et un projet web se conduisent exactement de la même façon ; seuls l'échafaudage, les tests de parcours et la distribution diffèrent.

Sur cette page