Deploy a Vite App
Push your Vite project to GitHub and Faable builds and serves it — no Dockerfile, no YAML, no server. The builder detects Vite from your package.json, installs your dependencies, runs npm run build, and serves the contents of dist/ directly, with no container, behind automatic SSL at https://<app>.faable.link, hosted 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. - Serves only
dist/, directly and with no container: no Node.js process boots, there is no cold start, files are compressed, and fingerprinted assets are cached for a year. - Turns on SPA fallback — a page route that isn’t a file (
/settings/profile) returnsindex.html, so React Router, Vue Router and friends work on a hard refresh. A missing file (/assets/old.js) still returns 404.
You don’t need a server
A Vite app is a folder of files once it is built, and serving that folder — with the SPA fallback — is what Faable does for you. So:
- Don’t write an Express server to serve
dist/. Aserver.jswithexpress.static('dist')and a catch-all that sendsindex.htmldoes exactly what Faable already does, and turns your site into a Node.js process that has to start before it answers. - You don’t need a
startscript either. Without one, Faable servesdist/statically. Astartthat only serves the build output —vite preview,serve -s dist— is recognized and served statically anyway.
A start script that runs your own code is a different thing: Faable runs it in a Node.js container, which is what you want when the app has a real backend next to the frontend (an Express API in the same repo, server-side rendering). If the backend is a separate app, keep the frontend static and call the API from the browser.
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