Web Hosting
Static releases for Expo web, React Native Web, Flutter, and any finished web build.
Mach Web Hosting is the managed static delivery product. It is separate from mach host, which keeps the existing AWS S3 and CloudFront workflow, and it is separate from OTA updates. Your computer or CI builds the site; Mach receives only the finished static output and serves it through Mach's managed global delivery edge.
This makes it a good fit for Expo Router web exports, React Native Web, Flutter web, landing pages, and SPAs. It does not run customer server code, SSR, databases, or deployable serverless functions.
What you get
Stable aliases
Every project has Production and Staging addresses. Promote or roll back without rebuilding.
Immutable previews
Every upload has its own permanent preview URL, ideal for review and QA.
Private origin
Files upload directly with short-lived signed URLs; only Mach's delivery edge can read them.
Profile-aware
Reuse an existing mobile profile with an explicit web alias and output folder.
1. Choose the project address
In Dashboard → Web Hosting, the project owner chooses the production subdomain before the first release. Mach starts with the project slug, so a project named shopreceives the following addresses:
Release URLs
Production https://shop.getmach.dev
Staging https://shop--staging.getmach.dev
Preview https://shop--d_<deployment-id>.getmach.dev
The selected subdomain is globally reserved and becomes locked after the first deployment. This protects links already shared with users, reviewers, and search engines. Service names such as api, ota, files, and mcp cannot be claimed.
2. Add an explicit web mapping to a profile
Mobile profile names and web aliases solve different problems. Keep your existing names such as qa-mobileor store-release, then map each profile explicitly. Mach never guesses a public URL from a profile name and never copies mobile build secrets into a static web export.
mach.config.json
{
"build": {
"qa-mobile": {
"distribution": "internal",
"web": { "alias": "staging", "output": "dist" }
},
"store-release": {
"distribution": "store",
"web": { "alias": "production", "output": "dist" }
}
}
}
web.alias
The stable address to promote after upload: production or staging. Production is the default when omitted.
web.output
Finished static directory, such as dist for Expo/React Native Web or build/web for Flutter.
3. Deploy a static release
Build where your source already lives—on a developer machine or in CI. The CLI uploads only the output directory. A deployment must contain index.html at its root.
Common workflows
# Upload an existing Expo or React Native Web export
mach web deploy --output dist
# Let Mach run Expo export locally, then upload the result
mach web deploy --build --profile store-release
# Flutter builds locally with flutter build web --release
mach web deploy --build --profile qa-mobile
# Create a preview only; leave Production and Staging unchanged
mach web deploy --output build/web --alias staging --no-promote
Uploads are batched and sent directly to private Mach storage using short-lived signed URLs. The Mach API stores deployment metadata and does not proxy your website files.
4. Promote, roll back, and review
Each upload is immutable. Promotion changes the small alias record that points Production or Staging to one release. Rolling back points that alias at an earlier ready release, so neither action rebuilds or overwrites files.
Release controls
mach web list
mach web promote d_0123abcd --alias production
mach web rollback --alias production
mach web status
Dashboard → Web Hosting has the same controls, the immutable preview link, file count, output size, profile, branch, and commit. The unified Release History also shows web deployments alongside native builds.
5. Free hosting usage
Free accounts receive 1 GB of retained static storage and 100,000 hosted requests per UTC calendar month, shared by every project the account owns. Open Dashboard → Web Hosting → Usage to see the account totals.
Storage is measured from retained deployment output when a release completes. Requests are reconciled from the previous complete UTC day, so request enforcement is intentionally daily rather than instant. Mach does not write an analytics event or call the Mach API for each visitor request.
CI pattern
Give CI a scoped Mach token, install the CLI, and let the repository build the web output. The profile mapping keeps release intent visible in source control.
Example CI step
npm install -g @radhya/mach@latest
mach web deploy --build --profile store-release --message "${GIT_COMMIT}"
The CLI records available branch and commit metadata automatically. Use --no-promotefor pull-request previews, then promote a reviewed deployment by ID.
Customer domains and safe scope
The included *.getmach.devaddresses are ready immediately. Customer-owned domains are a Premium capability that the Mach operator enables after automated certificate and fallback-origin setup is complete. When enabled, a customer domain always serves Production for now—not Staging.
Production-only custom domain
mach web domain add --domain www.customer.com
After adding a domain, open Dashboard → Web Hosting → Domains. Mach displays the CNAME and, when needed, the HTTPS verification record for that hostname, with copy buttons for each value. The table marks detected records separately from records that still need action. Add only the records marked Action required, wait for DNS to update, then select Refresh. The address is not ready until both DNS and HTTPS are active. A subdomain such as www.customer.com is usually easiest; a root domain needs a DNS provider that supports ALIAS, ANAME, or CNAME flattening.
Static web apps can call your normal Mach API or another backend, but browser-visible environment values are public by nature. Keep database credentials and server secrets out of the web bundle; use a backend for privileged work.
Troubleshooting
“index.html was not uploaded”
Point --output at the finished export directory. index.html must be directly inside it, not one directory deeper.
“Subdomain is unavailable”
Choose another name before the first deployment. Reserved Mach service names and names already claimed by another project are rejected.
Preview works but alias does not
Promote the ready deployment to Production or Staging in the dashboard or with mach web promote.
SPA route returns 404
Make sure the request accepts HTML and that the export includes index.html. The edge uses an HTML fallback for browser navigation.
Custom domain is unavailable
This is expected until Premium custom domains are enabled by the Mach operator. Managed getmach.dev addresses do not depend on it.