Adapters
GioJS needs no platform adapter: it is one long-running server process. What a host must provide, where it runs, and where it does not.
Frameworks built around serverless functions need an adapter per platform to split the app into functions, routes and edge handlers. GioJS is built the other way round: the Rust server is a single binary that starts its own Node render workers, answers HTTP/1.1 and HTTP/2, terminates TLS if you want, and keeps the page cache in memory and on disk. Deploying means running that process - the same build runs unchanged on every host that can.
npm start # from source: cross-env NODE_ENV=production giojs-server
node standalone/run.mjs # a standalone build: no node_modules needed on the hostWhat a host must provide
| Requirement | Why |
|---|---|
| A long-running process | The server keeps its workers, page cache, WebSocket rooms and rate-limit buckets in memory between requests. |
| Node.js 20 or newer | The render workers run on Node. |
| A server binary for the platform | Published for Linux x64 (glibc and musl), macOS x64 and arm64, and Windows x64. On other platforms - Linux arm64 included - build it from source and point GIO_SERVER_BIN (or, for standalone builds, GIO_STANDALONE_SERVER_BIN) at it. |
| A port to listen on | GIO_PORT, then PORT (set by most platforms), then [server] port, then 3000. |
| A writable cache directory | .gio/cache/pages by default, or GIO_CACHE_DIR. Without a persistent disk the cache starts empty after each restart, which is fine. |
| A graceful stop | SIGTERM, then enough time to drain (8 seconds) and let the workers exit before a hard kill. The Deploying recipes set this. |
| A health check (optional) | GET /_gio/health answers 200 with nodeReady in its JSON body. |
Where it runs
| Target | Guide |
|---|---|
| Docker, Docker Compose | Deploying: Docker, the starter's Dockerfile |
| Fly.io | Deploying: Fly.io |
| Railway | Deploying: Railway |
| Render | Deploying: Render |
| A Linux server with systemd, behind nginx or Caddy | Deploying: VPS |
| Kubernetes | docs/deployment/kubernetes.md |
| Windows Server (as a service with NSSM) | docs/deployment/windows-nssm.md |
| Any static host (no server features) | Static Export |
For hosts without Node packages at runtime - a slim container, a VM image - gio build standalone bundles the app, its dependencies and the binary into one folder.
Where it does not run
- Serverless functions (AWS Lambda, Vercel or Netlify functions, Cloud Functions): they start a handler per request and freeze it in between, so there is no process to keep a cache, workers or WebSockets. Container-based platforms that keep an instance running (Cloud Run with a minimum instance, App Runner, Azure Container Apps) work like any container host.
- Edge runtimes (Cloudflare Workers, Vercel Edge): GioJS needs Node and its native server binary. Put a CDN in front instead - cached pages send
Cache-Controlwiths-maxagefor it.
Several instances
Each instance has its own page cache, rate-limit buckets and WebSocket rooms - there is no shared backend yet. Behind a load balancer:
- Set the same
GIO_DEPLOYMENT_IDon every instance of a release, so their caches and skew detection agree. - Send
POST /_gio/revalidateto every instance; a purge reaches only the one that receives it. - Expect N instances to allow N times a configured rate limit.
- Use sticky sessions for WebSockets if clients of one room must meet on one instance.
See Proxies, Sizing & Scaling and Known Limitations.
Related
- Deploying
- Standalone Deploys
- Production Checklist
- Environment variables the server reads