Ce que contient le zip, et ce qu’il ne contient pas
Lovable, v0 et Bolt produisent tous à peu près la même chose : un projet Vite + React, en TypeScript, souvent avec Tailwind et des composants shadcn/ui. Ouvrez l’archive, vous y trouverez un package.json, un dossier src/, un index.html qui ne contient presque rien, et un vite.config.
Ce que vous n’y trouverez pas, c’est votre site. L’index.html d’un projet Vite contient une div vide et une balise script : tout le contenu est produit par du JavaScript qui n’a pas encore été compilé. Déposez ce dossier tel quel chez un hébergeur classique et vous obtiendrez une page blanche. Non pas parce que quelque chose est cassé, mais parce qu’il manque l’étape que votre machine n’a jamais faite.
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<title>Mon app générée par IA</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>Il manque trois choses entre ce fichier et un site en ligne : l’installation des dépendances (npm install), la compilation (npm run build, qui écrit un dossier dist/), et un serveur pour servir ce dossier en HTTPS. Un hébergeur qui accepte des projets d’IA est simplement un hébergeur qui fait ces trois étapes à votre place.

Les trois choses qui bloquent, et leur correction
Elles n’ont rien de propre à un hébergeur : elles tiennent à ce que le zip ne transporte pas, c’est-à-dire à tout ce que votre machine fournissait sans le dire. Les messages d’erreur ci-dessous sont reproduits tels quels, pour que vous reconnaissiez le vôtre.
La version de Node n’est pas déclarée
C’est de loin le cas le plus fréquent. Un projet qui ne dit pas de quelle version il a besoin laisse le constructeur choisir, et celui-ci prend une valeur prudente, souvent plus ancienne que la vôtre. La chaîne de compilation moderne de Vite, elle, ne tourne plus sous Node 18.
> demo-vite@0.0.0 build
> tsc -b && vite build
SyntaxError: The requested module 'node:util' does not provide an export
named 'styleText'
import { formatWithOptions, styleText } from "node:util";
^^^^^^^^^
Node.js v18.20.5
ERROR: process "/bin/bash -ol pipefail -c npm run build" did not complete
successfully: exit code: 1styleText est une fonction apparue dans Node 20. Le message ne parle jamais de version : il signale un export absent d’un module interne, ce qui n’oriente personne. La correction tient en trois lignes, et c’est souvent la seule chose qu’un export d’IA réclame. Le détail, version par version, est dans notre guide sur cette erreur.
{
"engines": {
"node": "22"
}
}Le verrou de dépendances vient de votre Mac
Celui-ci se reconnaît à un message qui ne dit pas son vrai sujet.
Error: Cannot find native binding. npm has a bug related to optional
dependencies (https://github.com/npm/cli/issues/4828). Please try
`npm i` again after removing both package-lock.json and node_modules
directory.
cause: Error: Cannot find module '@rolldown/binding-linux-x64-gnu'
cause: Error: Cannot find module '../rolldown-binding.linux-x64-gnu.node'En clair : le package-lock.json de l’archive a été produit sur un Mac. Il fige les binaires compilés pour macOS et ignore ceux de Linux, sur lequel tourne le serveur. C’est un défaut de npm connu depuis 2022, et il touche tous les outils qui embarquent du code natif, de rolldown à esbuild, swc ou sharp.
La parade est contre-intuitive : n’envoyez pas votre verrou de dépendances s’il a été fabriqué sur une autre plateforme que celle qui compile. Le serveur résoudra les versions lui-même, sur Linux, avec les bons binaires.
tar czf mon-app.tar.gz \
--exclude=node_modules \
--exclude=dist \
--exclude=package-lock.json \
-C mon-app .Attention : le même message a une autre cause, plus fréquente depuis Vite 8. Sous un Node trop ancien, npm écarte le binaire sans rien dire, et supprimer le verrou n’y change rien. Nous avons reproduit les deux cas séparément dans notre guide sur « Cannot find native binding ».
Le numéro de version est juste en dessous du seuil
Le plus discret des trois. Demander « Node 22 » ne dit pas quel Node 22 : un constructeur peut fournir 22.11 quand Vite exige >=22.12. Une version corrective d’écart suffit.
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'vite@8.2.2',
npm warn EBADENGINE required: { node: '^20.19.0 || >=22.12.0' },
npm warn EBADENGINE current: { node: 'v22.11.0', npm: '10.9.0' }
npm warn EBADENGINE }Retenez surtout ceci : npm émet un avertissement, pas une erreur. La compilation continue et casse plus loin, sur un message qui ne mentionne plus aucune version. La ligne qui explique la cause défile donc bien avant celle qui l’annonce, et c’est ce qui rend ce cas difficile à diagnostiquer.
Le dossier racine du zip
Un détail propre aux exports, et qui casse la compilation chez la plupart des hébergeurs : le zip ne contient pas votre projet, il contient un dossier qui contient votre projet. Décompressé, on obtient mon-app-export/package.json et non package.json. Un constructeur qui cherche le manifeste à la racine ne trouve rien et s’arrête.
→ téléchargement de l'archive
→ extraction du .zip
→ projet dans le sous-dossier mon-app-export/
→ nixpacks build /tmp/swc-build-65z3SQ/mon-app-export
║ setup │ nodejs_22, npm-9_x ║
✓ en ligne : https://export-zip-test.swigs.cloudChez nous, ce niveau est retiré tout seul. Ailleurs, si votre compilation se plaint de ne pas trouver de package.json, c’est presque toujours ça : rezippez le contenu du dossier plutôt que le dossier.
Ce que fournit chaque valeur d’engines
Puisque tout se joue sur une version, autant donner la table plutôt que des conseils. Nous avons déployé le même projet avec chaque valeur possible, sans rien changer d’autre, et relevé la version réellement installée.
| Ce que vous écrivez | Node installé | Vite 8 compile |
|---|---|---|
| rien | 22 | oui |
| "node": "20" | 20.18.1 | non |
| "node": "22" | 22 | oui |
| "node": "24" | 24 | oui |
Deux enseignements. Sans rien déclarer, vous obtenez Node 22, ce qui suffit à la quasi-totalité des exports d’IA d’aujourd’hui. Et n’épinglez pas Node 20 : le paquet fournit 20.18.1 quand Vite en demande ^20.19.0, à dix-huit centièmes près. Si vous devez rester sur cette version, épinglez aussi une version de Vite qui s’en contente.
Ce qui a fonctionné, et en combien de temps
Reprenons avec une pile réaliste, celle que produisent réellement Lovable et Bolt aujourd’hui, c’est-à-dire Vite 6 et React 18, et non le tout dernier échafaudage de npm que nous avions pris au départ. Le package.json tient en quinze lignes et déclare sa version de Node.
╔═══════════════════════ Nixpacks v1.34.1 ═══════════════════════╗
║ setup │ nodejs_22, npm-9_x ║
║ caddy │ pkgs: caddy ║
║ install │ npm i ║
║ build │ npm run build ║
║ start │ exec caddy run --config /assets/Caddyfile ║
╚════════════════════════════════════════════════════════════════╝
✓ build en 49.9s
→ déploiement de la charge wl_proj_01M1GSZ44J4596NZCFFVA90CFZ
✓ charge running
✓ en ligne : https://demo-ia-blog.swigs.cloudCinquante-cinq secondes entre l’envoi de l’archive et le site en ligne, dont cinquante de compilation. Le certificat HTTPS a été émis dans la foulée, sans intervention.
Un point mérite d’être relevé dans le journal : la ligne start ne lance pas Node, elle lance Caddy. Le constructeur a reconnu une application à page unique, compilé le dossier dist/, et l’a confié à un serveur de fichiers. Vous n’avez donc pas besoin d’ajouter un script start à votre projet. C’est une erreur fréquente, et elle est inutile.
La liste à vérifier avant d’envoyer
| À vérifier | Pourquoi | Comment |
|---|---|---|
| La version de Node est déclarée | Sans elle, le constructeur choisit, et il choisit vieux. | "engines": { "node": "22" } dans le package.json. |
| node_modules n’est pas dans l’archive | Des centaines de mégaoctets inutiles, et souvent faux pour Linux. | L’exclure de l’archive. |
| Le verrou vient de la même plateforme | Sinon, binaires natifs manquants au moment de compiler. | L’exclure aussi, ou le régénérer sous Linux. |
| Les clés d’API ne sont pas dans le code | Une clé compilée dans un fichier JavaScript est publique. | Variables d’environnement, préfixées VITE_ seulement pour ce qui peut être public. |
| Le projet compile chez vous | Un projet qui échoue en local échouera sur le serveur. | rm -rf node_modules && npm i && npm run build |
Ce qu’il faut retenir
Un export d’IA n’est pas un site, c’est un projet à compiler. Les trois obstacles tiennent tous à la même cause : ce qui marche sur votre machine dépend de choses que le zip ne transporte pas, à savoir votre version de Node, votre système d’exploitation et vos variables d’environnement. Déclarez la première, ne transportez pas les traces du deuxième, gardez les troisièmes hors du code.
Le reste est l’affaire de l’hébergeur, et se compte en secondes.
Sources
- [1]npm/cli, ticket 4828 : dépendances optionnelles et binaires natifs, le défaut à l’origine du deuxième obstacle, ouvert en 2022 et toujours d’actualité.
- [2]Journaux de déploiement, les quatre déploiements cités ont eu lieu le 2 septembre 2026 entre 12h11 et 12h18 sur le nœud sw6c-3 de Swigs Cloud. Les identifiants figurent dans les extraits.
- [3]Nixpacks, le constructeur qui détecte le type de projet et fabrique l’image. Version 1.34.1 au moment de l’expérience.