
Je pourrais remplacer SQLite par Postgres, déployer sur Vercel, installer un framework CSS et écrire davantage de JavaScript pur. Ce seraient des choix défendables.
Mais ils ne correspondent pas à la forme actuelle de mes projets.
Mon portfolio et mon dashboard ont un point commun important : je suis le seul à les développer, à les déployer et à les maintenir. Ils tournent sur mon VPS. Je ne choisis donc pas ma stack pour une équipe hypothétique ou une charge que je n’ai pas. Je la choisis pour ce que j’exploite aujourd’hui.
## SQLite tant que la base reste locale au produit
Le contenu de mon portfolio vit dans SQLite via Prisma. La base est sur la même machine que l’application. Je n’ai pas un service séparé à installer, configurer et surveiller. SQLite fonctionne directement avec un fichier local, ce qui correspond exactement à ce projet. C’est aussi le modèle décrit dans la documentation officielle de SQLite : l’application lit et écrit elle-même dans le fichier, sans processus de base de données intermédiaire.
Postgres m’apporterait une architecture client-serveur plus adaptée à plusieurs applications, plusieurs machines ou beaucoup d’écritures concurrentes. Je n’ai rien de tout ça sur mon portfolio. Ajouter Postgres maintenant créerait surtout un service de plus à administrer.
La limite est claire. SQLite n’autorise qu’un seul écrivain à un instant donné. Sa propre documentation recommande un moteur client-serveur lorsque beaucoup de processus doivent écrire simultanément ou lorsque le site doit fonctionner sur plusieurs serveurs. Ces cas sont détaillés dans les usages appropriés de SQLite.
Si mon portfolio atteint cette forme, je changerai. Pour l’instant, l’admin maison reste le principal chemin d’écriture. SQLite suffit.
## Mon VPS et pm2 parce que je veux exploiter le serveur
Je ne déploie pas sur mon VPS parce que Vercel serait incapable d’héberger un projet Next.js. Je le fais parce que le serveur fait partie de ce que je veux apprendre et maintenir.
Sur mon portfolio, je possède le processus Node, les variables d’environnement, les fichiers envoyés, la base SQLite et le reverse proxy. Le guide d’auto-hébergement de Next.js prévoit ce fonctionnement et recommande notamment de placer un reverse proxy devant le serveur Next.js.
pm2 reste une couche assez petite dans cette chaîne. Il lance l’application, expose son état et ses logs, puis permet de la redémarrer. Sa documentation de démarrage couvre aussi la restauration des processus après un redémarrage du serveur.
Le compromis est moins confortable. Quand un déploiement sert une ancienne image, quand une redirection récupère l’origine interne du serveur ou quand un script continue avec sa propre ancienne version, personne ne corrige la chaîne à ma place. Mon VPS me donne le contrôle, donc il me donne aussi les pannes liées à ce contrôle.
Je passerais à une plateforme gérée si l’exploitation du serveur devenait seulement une corvée extérieure au projet. Aujourd’hui, elle fait encore partie du projet.
## Du CSS écrit à la main pour construire cette interface précise
Le portfolio a une direction terminal avec un accent cyan. Je ne voulais pas assembler une interface à partir d’un vocabulaire visuel déjà préparé. J’ai donc écrit le CSS moi-même, avec des modules.
Next.js prend directement en charge les CSS Modules et génère des noms de classes locaux pour éviter les collisions, comme l’explique sa documentation CSS. Cela me donne l’isolation dont j’ai besoin sans ajouter un framework de classes utilitaires.
C’est plus lent. Je dois décider des espacements, des états, des breakpoints et de la structure des composants. Je ne présente pas ce temps comme un avantage automatique. Sur une interface plus standard, ou sur un projet où la vitesse d’assemblage passerait avant la direction visuelle, TailwindCSS pourrait être plus raisonnable.
Ici, cette lenteur m’oblige à comprendre ce que chaque règle produit. C’était aussi un objectif de la v2.
## TypeScript pour garder les contrats visibles
Dans mes projets web, TypeScript traverse les composants React, les routes, les données et l’admin. Son rôle n’est pas de rendre le code correct par magie. C’est un vérificateur statique : il analyse les types avant l’exécution, selon la présentation officielle de TypeScript.
Je l’utilise surtout pour garder visibles les formes qui circulent entre les couches. Un widget du dashboard, une entrée du portfolio ou une réponse d’API ne devrait pas changer silencieusement sans faire réagir le reste du projet.
La limite apparaît dès qu’une donnée entre depuis l’extérieur. Un type TypeScript ne valide pas, à lui seul, un formulaire ou une réponse reçue au runtime. C’est pour cela que mon admin utilise aussi zod. TypeScript décrit ce que mon code attend. La validation vérifie ce qu’il reçoit réellement.
Je garde donc cette stack tant que ses seuils restent ceux de mes projets : une machine, peu d’écritures concurrentes, une interface très spécifique et un écosystème web partagé. Le prochain point ouvert n’est pas de remplacer un outil pour moderniser la liste. C’est de surveiller lequel de ces seuils sera franchi en premier.
Image de couverture générée par IA — faute d'illustration officielle disponible pour ce sujet.