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é.
| Profil | Degré de preuve |
|---|---|
| Web | éprouvé sur plusieurs projets en production |
| Mobile | recommandé, à éprouver sur un premier projet |
| Desktop | recommandé, à é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
| Couche | Défaut | Quand s'en écarter |
|---|---|---|
| Framework | Next.js (App Router), TypeScript strict | Vite et React pour une application sans SEO ni rendu serveur |
| Architecture | Maedow Arch, mode Light puis Full quand le domaine prend du poids | jamais pour un projet TypeScript |
| Style | Tailwind CSS, primitives dans components/ui/ | un design system existant imposé |
| Données et authentification | Supabase (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 |
| Validation | Zod aux frontières (MF-007) | aucune raison courante |
| Tests | Vitest, Playwright avec axe pour les parcours et l'accessibilité | aucune raison courante |
| Hébergement | Vercel : un aperçu par pull request, la production depuis main | contrainte 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 strictveut direstrict,noUncheckedIndexedAccessetexactOptionalPropertyTypes, 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/developsur le volet interface, pas à la place de lui.
Mobile
| Couche | Défaut | Quand s'en écarter |
|---|---|---|
| Framework | Expo (React Native), Expo Router, TypeScript strict | besoin natif lourd que les modules Expo ne couvrent pas |
| Architecture | Maedow Arch : core/ en TypeScript pur, partageable avec un projet web | jamais |
| Données et authentification | le même backend que le web (Supabase par défaut) | aucune raison courante |
| Tests | Jest avec jest-expo et React Native Testing Library ; Maestro pour les parcours | aucune raison courante |
| Build et distribution | EAS Build, EAS Submit, EAS Update pour les correctifs JavaScript | aucune 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
runtimeVersiondoit 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
| Couche | Défaut | Quand s'en écarter |
|---|---|---|
| Framework | Tauri 2 : interface Vite, React et TypeScript, cœur Rust réduit au nécessaire | Electron quand le produit dépend de l'écosystème Node côté système ou de modules natifs Node |
| Architecture | Maedow Arch côté interface, commandes Rust fines côté système | aucune raison courante |
| Sécurité | capacités Tauri déclarées au plus juste : chaque fenêtre n'accède qu'à ce qu'elle utilise | aucune raison |
| Mises à jour | le plugin updater de Tauri, mises à jour signées | aucune raison |
| Tests | Vitest pour l'interface ; WebDriver (tauri-driver) pour les parcours, sur Windows et Linux | aucune raison courante |
| Build | GitHub Actions avec tauri-action, une cible par système | aucune 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 :
contextIsolationactivé,nodeIntegrationdésactivé, un script de préchargement minimal qui n'expose que des fonctions précises. Jamais le modulefsentier. - 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.