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:
code --install-extension gsxhq.gsxThe 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
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:
| Setting | Value |
|---|---|
| Command | gsx lsp |
| Language ID | gsx |
| Document selector | *.gsx |
| Root markers | gsx.toml, go.mod |
For highlighting, use tree-sitter-gsx when your editor supports tree-sitter.
Language features
| Feature | What you get |
|---|---|
| Diagnostics | Parse, type, and component errors. |
| Hover | Go types and component signatures. |
| Go to definition | Every 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 references | Every 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. |
| Formatting | Canonical gsx fmt output and project settings. |
| Document symbols | File components and top-level Go declarations. |
| Workspace symbols | Module components and top-level Go declarations. |
| Code actions | Organize imports and choose missing imports. |
| Completion | Go 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:
"[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:
gsx versionThe compiler prints a line beginning with gsx . If you see a Ghostscript banner, find the Go binary directories:
go env GOBIN GOPATHBoth 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.