GioJSdocs
On this page

CLI

The gio command runs, inspects and packages GioJS apps. It ships with @gio.js/server; create-giojs scaffolds new ones.

npx gio --help

Commands

CommandWhat it does
gio devStart the development server: file watcher, error overlay, live reload
gio startStart the production server
gio buildExplain deploys: there is no build step
gio build standalonePackage a self-contained deploy directory
gio exportRender the app to static HTML in out/
gio routesList every route the app serves
gio typegenWrite .gio/routes.d.ts without starting the server
gio doctorCheck the environment and project, with a fix for each problem
gio infoPrint versions and environment details for bug reports
gio cache explainExplain how the cache served a URL
gio benchLoad-test a running server
gio migrateMigrate a Next.js app (runs create-giojs migrate)
gio addAdd starter features to the app (runs create-giojs add)
gio helpThe command list, one command's options, --version
giojs-serverStart the server with the caller's NODE_ENV; --check-config validates the configuration
create-giojsScaffold a new app (npm create giojs@latest)
bash
gio --help             # the command list
gio help dev           # one command's options (same as: gio dev --help)
gio --version          # CLI, server binary and @gio.js/core package versions (-v)

In a project, run gio through your package manager (npx gio, pnpm gio) or from a package.json script. A mistyped command or option is an error with a suggestion (gio strat → did you mean gio start?), never a silently started server. gio with no command prints the help and exits with code 2.

Exit codes

CodeMeaning
0Success
1The command failed: the server exited with an error (its own exit code is passed through), gio doctor found an error, no server binary, a route conflict, an unreachable server
2Usage error: unknown command or option, missing or malformed argument

Every command keeps this contract, including the ones that parse their own options (gio build standalone, gio bench, gio migrate and gio add): a usage error exits with 2 before the command does anything. An argument a command does not take is one too, after --help or --version as well: gio --version --bogus and gio help dev extra exit with 2. --help wins only over arguments that parse (gio bench / --help prints the help).

gio --version prints package versions, read from the installed package.json files: gio is @gio.js/server's version, the server binary its platform package's (a binary from GIO_SERVER_BIN or a repository build prints its path instead), and @gio.js/core its own. It never runs the binary. See gio --version.

gio dev

bash
gio dev [--port <port>] [--host <ip>] [--open]

Starts the server with NODE_ENV=development and prints the local and network URLs once the worker is ready. The listen address comes from --port / --host (or GIO_PORT / GIO_HOST), then PORT - from the environment or the .env files - then gio.toml, then 0.0.0.0:3000. See gio dev.

Dev mode file watching

The whole project is watched: changes in app/, source files elsewhere and root config files restart the Node worker and reload open tabs, and edits under public/ only reload the browser. A gio.toml edit restarts the worker too, but its settings do not apply: the Rust server reads gio.toml (and the .env files) once, at startup, so stop and start gio dev after changing it. node_modules, hidden directories and build output are never watched. The rules, and the [dev] watch / watch_ignore keys, are on the gio dev page.

gio start

bash
gio start [--port <port>] [--host <ip>] [--open]

PORT=8080 gio start          # hosting platforms that assign the port

The same with NODE_ENV=production, whatever NODE_ENV the shell has. There is no build step before it. Both commands stay in the foreground and exit with the server's code. See gio start.

gio build

bash
gio build                                          # explains: normal deploys have no build step
gio build standalone [--out <dir>] [--target <platform>]

gio build standalone packages the app into one directory - the Rust binary, the whole Node side bundled into worker.js, prebuilt chunks, public/ and gio.toml - that runs anywhere Node is installed with node run.mjs. See gio build and Standalone Deploys.

gio export

bash
gio export       # → out/

Renders every page to static HTML with the client chunks that hydrate it, for static hosts, without the Rust server. GIO_APP_DIR and GIO_OUT_DIR override the input and output directories. See gio export and Static Export.

gio routes

bash
gio routes [--json]

Lists every URL the app serves - pages with their layouts and loading / error / not-found files, route handlers with their methods, WebSocket handlers and metadata routes - discovered exactly as the server discovers them, without starting it. See gio routes.

gio typegen

bash
gio typegen && tsc --noEmit

Writes .gio/routes.d.ts and .gio/css-modules.d.ts, the declarations behind typed href(), PageProps and CSS Module imports, for CI or a project with no server running. Your tsconfig.json must list ".gio/routes.d.ts" in include. See gio typegen.

gio doctor

bash
gio doctor [--dev | --prod] [--json]

Checks Node.js, the platform binary, package versions, gio.toml (with the server's own validation), tsconfig.json, the session secret, the port, trusted proxies and the cache directory, and prints a fix for every problem. Exits 1 when a check fails. See gio doctor.

gio info

bash
gio info [--json]

Prints the OS, Node.js and package manager versions, the server binary in use and the installed @gio.js/* versions. See gio info.

gio cache explain

bash
gio cache explain <url-or-path> [--base <url>]

Requests the URL and decodes its X-Gio-Cache header. A path goes to the local server at the address it listens on, or to --base. See gio cache explain.

gio bench

bash
gio bench <url-or-path> [--connections 32] [--duration 10] [--warmup 2]
gio bench --suite /,/posts/1 [--base <url>]

A zero-dependency load generator. See gio bench and Benchmarks.

gio migrate

bash
gio migrate ./my-next-app [--dry-run] [-y] [--config <file>]

Migrates a Next.js project in place and writes MIGRATION_REPORT.md, by running create-giojs migrate (the installed one, else the same version through npx / pnpm dlx / bunx). See gio migrate and the Migration Guide.

gio add

bash
gio add tailwind auth [--dry-run] [--force]

Adds starter features (tailwind, api, auth, db, docker, ci) by running create-giojs add. See gio add.

Environment variables

VariableUsed byEffect
GIO_SERVER_BINdev, start, build standalone, doctor, info, cache explain, bench, --version, giojs-serverUse this giojs-server binary instead of the installed platform package (a source build, a custom target)
GIO_APP_DIRallThe app/ directory; the project root is its parent
GIO_PORT / PORT / GIO_HOSTdev, start, cache explain, bench, doctorThe listen address (--port / --host set the GIO_* ones)
NODE_ENVexport, routes, typegen, doctor, giojs-serverdevelopment selects development mode and the .env.development* files; gio dev / gio start set it themselves
GIO_ENV_FILESall that read .env files0 loads no .env files, 1 loads them whatever [env] files says; any other value is the error the server refuses to start with (gio doctor reports it)
GIO_OUT_DIR, GIO_SITE_URLexportThe output directory; the site origin for sitemap.xml
GIO_STANDALONE_SERVER_BINbuild standaloneThe binary to package, over --target

Every variable the server itself reads is listed under Environment Variables.

When the server binary is missing

The Rust server ships as an optional dependency picked by OS and CPU (@gio.js/server-linux-x64, -linux-x64-musl, -darwin-arm64, -darwin-x64, -win32-x64). When it is missing, every command that needs it says which package to install, for your package manager:

text
gio: the GioJS server binary for linux-x64 is not installed.

  Install it:  npm install --save-optional @gio.js/server-linux-x64@0.1.0-beta.8

  @gio.js/server ships its Rust binary in @gio.js/server-linux-x64, an optional
  dependency picked by OS and CPU. It is usually missing because:
    - optional dependencies were skipped (--no-optional, --omit=optional,
      or omit=optional in .npmrc)
    - the lockfile was written on another OS and left this platform out:
      delete node_modules and the lockfile, then install again
    - node_modules was copied from another machine or OS
  Or point GIO_SERVER_BIN at a giojs-server binary you built.

Linux on ARM64 has no prebuilt binary yet: build one with cargo build --release -p giojs-server (Rust 1.89 or newer) and point GIO_SERVER_BIN at it, or run the app in a linux-x64 container. A GIO_SERVER_BIN that points at a missing file is reported as such. gio export, gio routes, gio typegen, gio migrate and gio add do not need the binary.

giojs-server

The giojs-server bin starts the server with no command parsing: it keeps the caller's NODE_ENV and passes its arguments to the binary (which takes only --check-config: any other argument exits with 2), as the scripts of scaffolded projects use it (cross-env NODE_ENV=development giojs-server). See giojs-server.

giojs-server --check-config

bash
giojs-server --check-config
{"cacheDir":"/srv/app/.gio/cache/pages","configFile":"gio.toml","envFiles":[".env"],"envFilesDisabledBy":null,
 "errors":[],"listen":{"host":"0.0.0.0","port":3000,"portSource":"default","tls":false},"mode":"production",
 "ok":true,"proxyHeaders":"x-forwarded","rateLimitRules":0,"sessionGuards":1,"sessionSecret":"valid",...}

Loads the .env files and gio.toml exactly as startup does, runs the same validation, prints a JSON report and exits - 0 when the server would start, 1 with the reasons in errors - without binding a port or starting a worker. The fields are described on the giojs-server page.

create-giojs

bash
npm create giojs@latest [directory] -- [options]

Scaffolds a new project, asking on a terminal for whatever the flags leave open: language (--ts / --js), server app or static site (--server / --static), starter features (--tailwind, --api, --auth, --db, --docker, --ci), and whether to install. Every flag, prompt and exit code is on create-giojs.

Adding features to an existing app

Adds starter features to an existing project without overwriting files you changed; gio add runs it. See create-giojs add.