To deploy static HTML website for free, connect your GitHub repository to RunxBuild, choose the right deployment type, set the build or start command, add required environment variables, and deploy. RunxBuild builds the project, publishes a live route, shows deploy logs, and gives you a path to add domains, databases, and backend services as the project grows.
That is the short version. The rest is where the deploy usually succeeds or quietly trips over a folder named dist.
Table of contents
- What this guide covers
- Before you deploy
- Step 1: Push the project to GitHub
- Step 2: Create the RunxBuild deployment
- Step 3: Configure build settings
- Step 4: Add environment variables
- Step 5: Deploy and verify
- Troubleshooting
- FAQ
What this guide covers
This guide shows how to deploy static HTML website for free with a practical deployment flow: prepare the repository, set the build or start command, add environment variables, deploy, connect domains, and troubleshoot the common mistakes.
You do not need a pile of platform tabs open to ship the first version. You need the project in GitHub, the right RunxBuild resource, and logs clear enough to tell you what happened.
You will cover:
- the repository setup
- the RunxBuild deployment type
- the build or start command
- the output directory or service route
- environment variables
- deployment logs
- custom domains
- common failure modes
Useful RunxBuild docs:
Before you deploy
A static HTML website deploys as static files. Run the build, publish the output folder, and add an SPA rewrite if the app uses client-side routing. The important part is not dramatic: the output directory must match the framework. Wrong folder, blank page. Infrastructure comedy, but the kind nobody asked for.
Run the project locally first. A remote deploy should not be the first time the app meets production settings.
# install dependencies
npm install
# or use the package manager your project already uses
Then run the framework-specific build or start command. If the project fails locally, fix that first. Remote build logs are useful, but they should not be the first witness.
For background reading, use these authoritative references:
Step 1: Push the project to GitHub
RunxBuild deploys from GitHub. Commit the working project and push it to the branch you want to deploy.
git add .
git commit -m "Prepare static HTML website for deployment"
git push origin main
If this is a new repository, create it first and add the remote:
git remote add origin https://github.com/YOUR-USER/YOUR-REPO.git
git push -u origin main
Do not commit secrets. Put production credentials in RunxBuild environment variables.
Step 2: Create the RunxBuild deployment
Open the RunxBuild dashboard and create a new deployment for the project.
Choose the resource type that matches the app:
- Static Website for static builds and frontend apps
- Service for APIs, backends, and containers
- WordPress for WordPress sites
- Database when the app needs persistent data
Select the GitHub repo and branch. Use a name you will understand in six months. final-final-api-v3 is funny once and annoying forever.
Step 3: Configure build settings
Use these settings as the starting point:
Root Directory: ./
Build Command: no build command
Publish Directory: ./ or public
If the app lives in a monorepo, set the root directory to the subfolder that contains the app.
Root Directory: apps/web
Most failed deployments come down to two settings: what command runs, and where the result lives. Get those right and most of the drama leaves the room.
Step 4: Add environment variables
Add production environment variables in RunxBuild before deploying.
Common examples:
API_URL=https://api.example.com
DATABASE_URL=postgres://user:password@host:5432/db
NODE_ENV=production
PORT=3000
Static frontends can only safely use public variables. Backends can use private secrets because the code runs server-side. If users can download the bundle, assume they can read anything inside it.
Step 5: Deploy and verify
Click deploy and watch the logs.
Check these before calling the deployment finished:
- The build completes without dependency errors.
- The live route opens.
- Required assets load.
- API requests hit the production endpoint.
- Environment variables have the expected values.
- Logs show no startup crash.
- The custom domain works after DNS propagation.
Hard refresh a nested route if the site uses client-side routing.
Handle routing, rewrites, and cache behavior
Static apps often fail after the first click because a deep URL asks the host for a file that does not exist. Add a fallback rewrite when routes are handled in the browser.
/* -> /index.html
Use this for dashboards, docs apps, and any app with client-side routing. Skip it for plain HTML pages where every URL has a real file.
When the static site grows up
A static frontend can ship the first version. When the project needs private API keys, file uploads, account logic, webhooks, or database writes, add a backend service instead of stuffing secrets into client-side code. AI can sketch the interface. The backend decides whether the thing is real.
Troubleshooting
The build command fails
Run the same command locally. If it fails there, the issue is in the project, not the platform. Check dependencies, lockfiles, and case-sensitive imports.
The deploy succeeds but the page or API does not load
Check the publish directory for static apps and the port for services. The platform can only route what the app actually exposes.
Environment variables are missing
Add them in RunxBuild and trigger a new deploy. Build-time variables are baked into static output, so changing them after the build is not enough.
The app works locally but not in production
Look for local-only paths, missing production config, and secrets that were never added to the dashboard. Localhost is not a production architecture. It just dresses confidently.
Production checklist before launch
Use this final pass before sharing the URL with users:
- Confirm the deployed branch is the branch you expected.
- Save the build command in the dashboard, not only in your memory.
- Keep environment variables named clearly.
- Add a health check or simple test route for services.
- Keep deploy logs close during the first real traffic.
- Add a custom domain only after the generated route works.
This is the part that makes the deploy repeatable. Fast is useful. Repeatable is what keeps the project alive after the first version ships.
Final launch pass
Before you move traffic, run one practical check from start to finish. Push a small change, watch the deploy start, open the generated route, test the main user path, and read the latest logs. If that path works, the deployment is not just live. It is repeatable.
That is the real production upgrade: fewer disconnected tools, fewer guessing games, and a clear place to see what changed when the app starts acting clever.
FAQ
How do I deploy static HTML website for free?
Push the project to GitHub, create the matching RunxBuild resource, set the build or start command, add environment variables, and deploy. RunxBuild publishes the result with logs and a live route.
Can I deploy static HTML website for free without a credit card?
RunxBuild includes a free monthly allocation for small projects. Heavier usage, larger instances, or production traffic may need a paid plan.
What command should I use to deploy a static HTML website?
Use no build command as the starting point, then adjust it for your project. The exact command depends on the framework, package manager, and repository layout.
Do I need environment variables?
Use environment variables for API URLs, database connections, tokens, and configuration that should change between local and production environments.
Can I add a custom domain?
Yes. Deploy the app first, verify the generated RunxBuild route, then add the custom domain and update DNS.
What should I check after deployment?
Open the live route, check logs, test navigation, and verify production behavior. Hard refresh a nested route if the site uses client-side routing.
About the author
Written by Sean, Platform Writer at RunxBuild. Last updated: June 6, 2026.