Skip to content

Editor support ​

Install the VS Code extension for the shortest setup. Other editors can run gsx lsp and use the tree-sitter grammar separately.

VS Code ​

Install the gsx extension:

bash
code --install-extension gsxhq.gsx

The extension supplies highlighting and starts the language server when it can find the gsx compiler. It checks gsx.server.path, then PATH, GOBIN, and GOPATH/bin, and verifies each candidate before using it.

If the compiler is missing, run gsx: Install/Update Language Server. Wait for the terminal command to finish, then run gsx: Restart Language Server. Set gsx.server.path to an absolute path when automatic discovery is not right for your setup.

Neovim ​

Use Neovim's built-in LSP client for language features.

Language server ​

lua
vim.filetype.add({ extension = { gsx = "gsx" } })

vim.api.nvim_create_autocmd("FileType", {
	pattern = "gsx",
	callback = function(args)
		vim.lsp.start({
			name = "gsx",
			cmd = { "gsx", "lsp" },
			root_dir = vim.fs.root(args.buf, { "gsx.toml", "go.mod" }),
		})
	end,
})

Syntax highlighting ​

Use the tree-sitter-gsx grammar and source. Neovim needs a compiled parser registered as gsx on runtimepath, plus the grammar's highlight and injection queries under queries/gsx/. Building the parser from source requires a C compiler and the tree-sitter CLI.

The grammar includes Go directly. Only JavaScript and CSS regions are injected, so install those two parsers to highlight <script>, <style>, js literals, and css literals.

Zed ​

The community gsx-zed extension supplies highlighting from tree-sitter-gsx and starts gsx lsp. It is not in the Zed extension registry yet: clone the repository, then run zed: install dev extension from the command palette and select the clone.

The extension launches the first gsx on PATH and has no path setting, so make sure gsx version prints the compiler (see Troubleshooting).

Other editors ​

Configure any LSP client with these values:

SettingValue
Commandgsx lsp
Language IDgsx
Document selector*.gsx
Root markersgsx.toml, go.mod

For highlighting, use tree-sitter-gsx when your editor supports tree-sitter.

Language features ​

FeatureWhat you get
DiagnosticsParse, type, and component errors.
HoverGo types and component signatures.
Go to definitionEvery Go symbol and component, .gsx ↔ .go, module-wide (Go-only packages importing gsx packages included). From a .go file, gsx returns .gsx locations; gopls answers .go.
Find referencesEvery Go symbol declared or used in .gsx — types, funcs, methods, fields, params, locals, components (tag sites and attribute bindings), pipe filters — from .gsx or .go cursors, module-wide. From a .go file, gsx returns .gsx locations; gopls answers .go.
FormattingCanonical gsx fmt output and project settings.
Document symbolsFile components and top-level Go declarations.
Workspace symbolsModule components and top-level Go declarations.
Code actionsOrganize imports and choose missing imports.
CompletionGo identifiers and members, pipe filters, component tags and attributes, HTML tags/attributes/values, and hx-* attributes when the htmx URL preset is enabled. The hx-* table covers htmx 2 and htmx 4; an attribute only one version has says so in its hover text.

Completion returns plain text edits, not snippets. Completing a symbol on a package you have not imported — ui.Button in a Go expression, or <ui.Button as a tag — adds the import along with the name. A tag cursor offers only the package's component-shaped declarations. The symbol graph — find references, and go to definition from a .go cursor — covers module-local packages, so references to an external symbol list module-local sites only; go to definition from a .gsx cursor still travels into external packages. See Status for the current limits.

Organize imports ​

Enable formatting and import organization on save in VS Code:

json
"[gsx]": {
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": "explicit"
  }
}

The organize-imports action removes unused imports, sorts them, and adds a missing import when there is one unambiguous match — including the package half of a component tag, so <ui.Button/> imports ui. When several packages match, use the Add import quick fix to choose one. Run go get first when the package is not in your module.

Import organization still runs when [formatter].imports is "gofmt"; that setting controls formatting, not the explicit code action.

Troubleshooting the gsx binary ​

Ghostscript can also install a command named gsx. Check what your editor will launch:

bash
gsx version

The compiler prints a line beginning with gsx . If you see a Ghostscript banner, find the Go binary directories:

bash
go env GOBIN GOPATH

Both outputs are directories. When GOBIN is non-empty, use <GOBIN>/gsx. Otherwise use <GOPATH>/bin/gsx. Replace the bracketed value with the command's output and enter that concrete executable path in your editor setting. The VS Code extension performs the compiler check itself and skips unrelated binaries; the Zed extension and generic LSP clients do not.