Skip to content

CLI

Use gsx to scaffold a project, run the development loop, generate Go, and format .gsx files.

text
gsx [global flags] <command> [arguments]

Choose a command

TaskCommand
Create a starter projectgsx init [dir]
Generate, build, and reload while editinggsx dev [dir]
Generate .x.go filesgsx generate [paths...]
Format .gsx filesgsx fmt [paths...]
Inspect the resolved project setupgsx info
Remove the generation cachegsx clean --cache
Start the editor language servergsx lsp
Show version and build informationgsx version
List commandsgsx help

Global flags

-C is the only true global flag. It must appear before the command name and sets the base directory for commands that resolve project paths or configuration:

bash
gsx -C ./web generate .
FlagEffect
-C dirUse dir as the base for project paths and configuration.

-q and -v may also appear before or after generate, but they affect that command only:

bash
gsx -q generate
gsx generate -v ./views

gsx init

Create the simple gsx + Vite starter in a new directory:

bash
gsx init myapp
text
gsx init [dir] [flags]
FlagEffect
--template simpleSelect the starter template. simple is the only current template.
--module pathSet the Go module path. The default is the target directory name.
--forceOverwrite an existing go.mod or package.json.
--yes, -yRun setup commands without prompting.

Interactive setup

In a terminal, gsx init asks for a project name when dir is omitted. It then scaffolds the project and asks before running each setup command.

bash
gsx init

Press Enter, y, or yes to run a step. Skipping one step does not skip the remaining steps.

Non-interactive setup

Use --yes when a script should scaffold and run every setup command:

bash
gsx init myapp --module example.com/acme/myapp --yes

When standard input is a pipe or regular file (not a character device) and --yes is omitted, init scaffolds the files, then prints the setup commands instead of running them.

init exits 0 on success, 2 for invalid usage or an existing protected project file, and 1 when scaffolding or a setup command fails.

gsx dev

Run the development loop from the project directory:

bash
gsx dev

Pass an optional project directory with gsx dev [dir].

Relevant source changes regenerate as needed, build, swap the server, and reload the browser. After the first successful build, later generation or build failures leave the last working server running. A .env change only restarts the backend with fresh environment values; it does not regenerate or build. See the development loop for the full file-by-file behavior.

FlagEffect
--web commandSet the front-door command. The default is npx vite.
--no-webRun generation and the Go server without the front door.
--build commandSet the server build command.
--run commandSet the built-server command.
--logCopy backend output to the default per-project log file.
--log-file pathCopy backend output to path.
--no-logDisable backend file logging, including logging from gsx.toml.

Common customizations

Run without Vite when another tool provides the front door:

bash
gsx dev --no-web

Override the build and run commands for one session:

bash
gsx dev --build "go build -o ./tmp/app ./cmd/site" --run "./tmp/app"

Command flag values are split on whitespace. For arguments that need exact boundaries, use arrays in the [dev] configuration.

Before the first successful build there is no previous server to keep alive. Fix the startup error and save again. A clean signal-driven shutdown exits 0; invalid flags exit 2, and fatal startup errors exit 1.

gsx generate

Generate a sibling .x.go file for every .gsx file under the selected paths:

bash
gsx generate
gsx generate ./views ./email

With no path, the command uses .. Directory paths are searched recursively.

FlagEffect
--no-cacheRegenerate without reading or writing cached results.
--jsonWrite diagnostics as one JSON array to stdout.
--watchKeep running and regenerate when source files change.
--format=ndjsonIn watch mode, write one machine-readable event per line.
-qSuppress the success summary.
-vList each written or removed file before the summary.

Generate flags may appear before or after path arguments.

Diagnostics and exit status

Normal diagnostics go to stderr. Use JSON when another program consumes them:

bash
gsx generate --json ./views
ExitMeaning
0Generation succeeded, including when everything was already current.
1A source diagnostic or operational error prevented generation.
2The command, configuration, or a path was invalid.

When a .gsx file has a generation error, gsx replaces its previous generated file with a deliberately non-compiling marker. This prevents go build from silently using stale output. Fix the .gsx file and run generate again.

Deleting a .gsx file removes its generated sibling on the next generation run. Only files with gsx's generated-file header are removed; a hand-written file with the same name is left alone. I/O and project-loading failures do not replace files with error markers.

Watch mode

Use watch mode when an integration needs generation without the full dev loop:

bash
gsx generate --watch

For a machine-readable stream, use newline-delimited JSON:

bash
gsx generate --watch --format=ndjson

Human watch output goes to stderr. In NDJSON mode, stdout contains only event objects; diagnostic fields use the same shape as --json.

gsx fmt

Rewrite .gsx files in place before committing:

bash
gsx fmt -w .

Paths may be files or directories. Directories are searched recursively; with no path, the command formats .. Hidden directories, .git, vendor, node_modules, and testdata are skipped.

FlagEffect
noneWrite formatted source to stdout.
-wRewrite changed files in place.
-lList files whose source would change.
-dShow a unified diff.
-imports=goimportsRemove unused imports and normalize import declarations. This is the default.
-imports=gofmtFormat existing imports without removing, merging, or regrouping them.
-no-importsAlias for -imports=gofmt.

The goimports mode cannot add a missing import; it organizes imports already present in the .gsx file. A CLI import mode overrides the [formatter] setting.

gsx fmt also formats CSS in <style> and JavaScript in executable <script> bodies. Interpolation holes are preserved. If an embedded body cannot be formatted safely, that body is left unchanged.

js`/css` attribute values are re-indented the same way as <script>/<style> bodies. Plain "…" string attributes are left verbatim.

Text flow

Inline elements (code, a, span, em, b, img, and other phrasing-content tags) stay in the surrounding text flow: the formatter never breaks their children open to meet the width budget. If a line has no other legal break point, it stays over budget rather than exploding an inline element.

Long prose wraps between words instead: a newline between two words collapses back to a single space, a newline where two pieces of markup touch adds nothing, but a newline against a space next to a tag would delete that space — so the formatter only ever breaks where no space can be lost.

{" "} sticks to the word before it and never starts a line.

Author layout still wins: breaking the line right after an opening tag's > keeps that element block-formatted, even if its content would otherwise fit inline.

Check formatting in CI

-l and -d exit 1 when any file differs, so either works as a CI check:

bash
gsx fmt -l .

Parse, analysis, and write failures also exit 1. Invalid flags, import-mode combinations, or paths exit 2; otherwise formatting exits 0.

gsx info

Inspect the configuration that gsx resolves for the current project:

bash
gsx info

The human view shows the active config path and resolved filters, renderers, attribute rules, minification, formatter width, and environment overrides. Use JSON for automation:

bash
gsx info --json

Human and JSON output are different inspection views, not identical encodings of the same fields. Scripts should consume --json rather than parse the human table.

Resolution failures exit 1. Invalid arguments or project configuration exit 2; a successful inspection exits 0.

gsx clean

Remove the generation cache:

bash
gsx clean --cache

The command exits successfully when the cache is disabled or absent. It refuses to remove a directory that does not contain gsx's cache marker, which protects against an unsafe GSXCACHE value. A refusal or removal failure exits 1; invalid flags exit 2.

gsx lsp

Editors start the language server over standard input and output:

bash
gsx lsp

You normally do not run this command yourself. See Editor setup for VS Code, Neovim, and generic client configuration.

gsx version

Print the installed version:

bash
gsx version

When available, the output also includes the commit revision, commit time, dirty-tree state, and Go toolchain version. Local builds without an embedded module version report (devel).

Environment variables

VariableEffect
`GSX_MINIFY=nonefull`
GSXCACHE=offDisable the generation cache.
GSXCACHE=pathUse path instead of the operating-system user cache directory.

For minification, a programmatic option in a custom gsx binary wins over GSX_MINIFY, which wins over gsx.toml. Use --no-cache for a single uncached generation run.

Stability

The CLI is alpha. This page lists the commands that are available now; see Status for the broader shipped surface.