Deploy a Vite App
Push your Vite project to GitHub and Faable builds and serves it β no Dockerfile, no YAML. The builder detects Vite from your package.json, installs your dependencies, runs npm run build, and serves the contents of dist/ from Faableβs shared static runtime behind automatic SSL at https://<app>.faable.link, hosted 100% in Europe.
It works the same whether your Vite app is React, Vue, Svelte, Solid or Preact β detection keys on the vite dependency, not on the UI framework.
What Faable does with a Vite repo
Nothing to configure. The builder:
- Detects
vitein yourdependenciesordevDependencies. - Installs your dependencies (including dev ones β
viteitself lives there). - Runs your
buildscript. - Ships only
dist/to the static runtime: no Node.js process boots, nothing is installed at runtime, and the deploy is over in seconds. - Turns on SPA fallback β unknown paths rewrite to
index.html, so React Router, Vue Router and friends work on a hard refresh.
Do not add a start script
This is the one thing that changes the outcome.
A start script disables static serving entirely. The builder trusts it: if package.json defines one, Faable stops generating a serve command and runs npm run start in a Node.js container instead. That is correct for a project that ships a real server β and wrong for a Vite SPA, where start is almost always just the preview server:
{
"scripts": {
"build": "vite build",
"start": "vite preview" // β binds 127.0.0.1:4173
}
}vite preview with no flags listens on localhost, port 4173. Inside a container nothing outside can reach it, the health check never passes, and the deployment fails as a startup crash β after a build that went perfectly green.
Pick one:
-
Recommended β delete the
startscript. Faable servesdist/statically, which is what a Vite SPA wants. -
Or, if you want to keep it, make it honour the platform contract:
{ "scripts": { "start": "vite preview --host 0.0.0.0 --port $PORT" } }This works, but you pay for a Node.js process to serve static files.
See Start command precedence for the full rule.
Deploy
From the dashboard β the normal path:
- Create a Project and an App in the Faable DashboardΒ .
- Click Link repository and pick your Vite repo.
- Push to your release branch. Faable builds and takes it live.
Or from your laptop, for an ad-hoc deploy:
npm i -g @faable/faable
faable login
faable deployYour app is ready at https://<app>.faable.link, with automatic SSL and the WAF already inspecting traffic.
Environment variables
Vite variables are compiled into your bundle at build time, not read at runtime, and only the ones prefixed VITE_ are exposed to your code. Two consequences:
- Set them before you build, with the CLI or the dashboard, then redeploy β changing a variable does not affect an already-built app.
- Anything in a
VITE_variable is public. It ships inside the JavaScript your visitors download. Never put an API secret there; call a backend instead.
faable deploy secrets set VITE_API_URL=https://api.example.comA different output directory
Faable expects the Vite default, dist/. If your vite.config.js sets build.outDir to something else, the build fails the post-build check with Static build output 'dist' not found after the build.
Either drop the override, or force the static buildpack and point it at your directory in faable.json:
{ "buildpack": "static", "static": { "spa": true } }Monorepos
If the Vite app lives in a subdirectory, point rootDir at it in faable.json at the repository root:
{ "rootDir": "apps/web" }The builder installs from the workspace root (so hoisted dependencies resolve) and builds in your subdirectory. See Monorepos.
Troubleshooting
- The deployment fails as a startup crash right after a green build β you have a
startscript. See above. Static build output 'dist' not foundβ yourbuild.outDiris notdist/, or the build wrote nothing.- Every route except
/404s β this should not happen on Vite (SPA fallback is on by default). If you forced thestaticbuildpack, add{ "static": { "spa": true } }. - A
VITE_variable is empty in the browser β it was set after the build. Redeploy. npm cifails βpackage-lock.jsonis out of sync withpackage.json. Commit an updated lockfile.
Related
- What the Builder Expects β detection rules, static frontends, the
$PORTcontract - Deploy Astro β the static sibling, without SPA fallback
- Deploy Next.js Β· Deploy Node.js Express
- Migrate from Vercel Β· Migrate from Netlify
- Custom domains Β· WAF
- Add authentication to your app β Faable Auth is included in the same subscription
Last updated on