Migrating production infrastructure? Get up to ₹10,000 in migration credits. Apply now
voroaDocs
Quickstarts

Deploy a React Vite app from GitHub: step by step

Deploy a React app built with Vite from GitHub. Voroa runs npm run build, serves the dist folder with working client-side routes, and puts it on free HTTPS.

To deploy a React app built with Vite on Voroa, push it to GitHub, create a Web Service from the repository, leave the build and start commands empty, and select Deploy. Voroa installs your dependencies, runs npm run build, and serves the dist folder on a live HTTPS URL, with client-side routes that keep working when a visitor refreshes the page.

The short version:

  1. Check that package.json has "build": "vite build" and that Vite writes to dist (the default).
  2. Push the project to GitHub.
  3. In Voroa, select New service, choose Web Service, and pick the repository and branch.
  4. Leave Build command and Start command empty.
  5. Add any VITE_ environment variables and tick Build-time for each.
  6. Select Deploy and open your URL.

How a React (Vite) app deploys: install dependencies, run your build script, serve the dist folder, then live on HTTPS with client-side routes working

What you need before you start

  • A React project created with Vite, in a GitHub repository.
  • A build script in package.json. Projects created with npm create vite@latest already have "build": "vite build".
  • The build output in the dist folder, which is Vite’s default.

You do not need a Dockerfile, a server or nginx. You also do not need to add a static file server such as serve to your dependencies.

Step 1: Check your Vite build output

Run the build once on your machine:

bash
npm run build

Vite writes the finished site to dist/, with an index.html at the top of that folder. That dist/index.html is what Voroa serves.

If you changed build.outDir in vite.config.js, keep it as dist, or at least as a plain string Voroa can read. A path that is computed in code (for example with path.resolve) is not detected:

js
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  build: { outDir: 'dist' },
})

If the folder is wrong, the deploy stops with a clear message instead of publishing an empty site: “Your build finished, but there is no site to serve: index.html was not found.”

Step 2: Create a web service

In the Voroa dashboard, select New service, choose Web Service, and pick your repository and branch. If the React app lives in a subfolder, such as /frontend in a monorepo, set Root directory to that folder.

The new web service form: branch, root directory, build and start commands, pre-deploy command, health check path and instance

Step 3: Leave the build and start commands empty

For a Vite app, Voroa detects the project and does the work itself:

Stage What Voroa runs
Install Your package manager’s install, chosen from your lock file
Build Your build script, run with your package manager
Serve The files in dist, on the port Voroa provides

If you do set a Build command, make it one that builds. A Build command replaces the automatic build step. npm install on its own builds nothing, and installing again only makes the build slower, because Voroa has already installed your dependencies. Use npm run build, or leave the field empty.

Client-side routes keep working

React Router and other client-side routers handle paths such as /dashboard in the browser. When a visitor refreshes on that path, the server has to answer with index.html instead of a 404. Voroa does this for you, so deep links and refreshes work without any rewrite rules.

Step 4: Add environment variables

Vite reads environment variables while it builds, not when the page loads, and it only exposes variables whose names start with VITE_:

js
const apiUrl = import.meta.env.VITE_API_URL

Open the service, go to Environment, add each variable, and tick Build-time so the build can see it.

The Environment tab with write-only variables and the Add variable button

Two rules matter here:

  • Anything starting with VITE_ ends up in the JavaScript your visitors download. Put only public values there, such as an API URL. Never put a secret key in a VITE_ variable.
  • A change needs a new build. Because the value is baked into the bundle, redeploy after you change a VITE_ variable.

Step 5: Deploy

Select Deploy. The build log shows each stage live: cloning your branch, installing dependencies, running vite build, and starting the site. When it finishes, your app is live at https://your-app.onvoroa.com.

Turn on auto-deploy and every push to your branch ships a new build. Choose the Node.js version under Environment if your project needs a specific one.

Web service or static site?

Voroa can host a React app in two ways:

Web service (this guide) Static site
Who runs npm run build Voroa, on every deploy You, before you commit
What you commit Source code only The built dist folder
VITE_ variables Set in Voroa, applied at build Baked in when you build locally
Best for Most React apps Sites you already build in CI

If you are unsure, use a web service. You never have to commit build output, and every push rebuilds.

Common React (Vite) deploy errors and fixes

Error Cause Fix
“index.html was not found” The Build command only installs, or Vite writes somewhere other than dist Leave the Build command empty or set it to npm run build, and keep outDir as dist
import.meta.env.VITE_... is undefined The variable is missing, lacks the VITE_ prefix, or is not marked Build-time Rename it with VITE_, tick Build-time, then redeploy
A blank page with 404s for /assets/... base in vite.config.js points at a sub-path Remove base or set it to '/'
The build runs out of memory A large app needs more memory to bundle than the build machine has Builds run on the build machine your plan includes, not on your service’s instance type; a paid plan gets a larger one. See build pipeline
The live site still calls your development API The API URL is hard-coded in the source Read it from import.meta.env.VITE_API_URL

Frequently asked questions

Do I need serve or nginx to host a React app?

No. Voroa builds your Vite app and serves the dist folder itself, including the fallback to index.html that client-side routing needs. Leave the Start command empty.

Does this work for Vue, Svelte or other Vite apps?

Voroa builds and serves single-page apps made with Vite the same way, including Vue, Svelte, Preact and Solid. SvelteKit, Remix and React Router in framework mode are different: they run their own server, so deploy them like a Node.js app.

Can I use pnpm or Yarn?

Yes. Commit your lock file (pnpm-lock.yaml or yarn.lock), and Voroa installs with the matching package manager.

How do I connect my React app to a backend?

Deploy the backend as its own web service, for example a Node.js API, and pass its URL to the React app as VITE_API_URL. Allow your frontend’s domain in the backend’s CORS settings.

Can I use my own domain?

Yes. Add a custom domain to the service, and Voroa issues and renews its HTTPS certificate.

Next steps

Last updated November 12, 2026