Editor tooling for Nix.js: syntax highlighting for html tagged templates and raw() function-wrapped templates, event binding autocomplete, diagnostics, quick fixes, formatting, and snippets.
Architecture
This extension is a thin LSP client that launches @deijose/nix-js-language-server. All editor intelligence (diagnostics, completion, hover, code actions, formatting) lives in the LSP server, which also powers Neovim, Helix, Zed, and Emacs.
vscode-nix-js (this extension)
├── extension.js ← thin LSP client (~95 lines)
├── syntaxes/*.json ← TextMate grammars (VS Code native)
├── snippets/ ← code snippets
└── @deijose/nix-js-language-server ← LSP server (bundled in .vsix)
Features
- HTML highlighting inside
htmltagged template literals andraw()function-wrapped templates - Event bindings highlighted as first-class attributes (
@click,@input,@submit, ...) - Event modifier highlighting with dedicated scopes (
@click.prevent.stop,@keydown.enter) - Template expressions (
${...}) highlighted inside templates - Nested templates support (
htmlinside${...}) - Autocomplete for common Nix event bindings and directive attributes inside
htmltemplates - Chained modifier autocomplete after
.with key-aware suggestions for keyboard events - Diagnostics for invalid modifier combinations (
.passive+.prevent, unknown modifiers, duplicates, key modifiers on non-key events, non-canonical order) - Quick fixes for modifier diagnostics (remove duplicates, resolve conflicts, replace unknowns, normalize order)
- Hover help for modifiers (
.prevent,.stop,.enter, etc.) - Document formatting for
htmltemplates - Configurable template tags (
nixjs.tags) - Command to inspect active TextMate scopes (
Nix.js: Inspect Template Scopes) - Snippets for common Nix patterns (component, effect cleanup, computed, router, store)
- Works in
.ts,.tsx,.js,.jsx
Quick Example
function App() {
const count = signal(0);
return html`
<p>Count: ${() => count.value}</p>
<button @click=${() => count.value++}>+1</button>
`;
}
Snippets
nix:component— function component with signal + html templatenix:effect-cleanup— effect with listener cleanupnix:computed— computed valuenix:router— basic router setupnix:store— store with actions
Settings
| Setting | Default | Description |
|---|---|---|
nixjs.tags |
["html", "raw"] |
Template tag names where Nix autocomplete should be active (html tagged templates and raw() function-wrapped templates) |
nixjs.completions.enableEventBindings |
true |
Enable @event completion items |
nixjs.completions.enableModifierSuggestions |
true |
Enable .modifier suggestions |
nixjs.diagnostics.enable |
true |
Enable diagnostics for invalid modifier combinations |
nixjs.diagnostics.enableStyleHints |
true |
Enable canonical modifier order hints |
nixjs.format.enable |
true |
Enable the html template formatter |
nixjs.format.formatOnSave |
true |
Format templates on save |
Commands
Nix.js: Inspect Template Scopes— inspect active TextMate scopesNix.js: Format html`` Templates— format all templates in the current file
Development
npm install
npm test
npx vsce package
Install the generated .vsix locally:
code --install-extension vscode-nix-js-0.6.0.vsix --force
Other Editors
The same LSP server works in:
- Neovim:
:MasonInstall nix-js-language-server - Helix: configure
languages.toml - Zed: configure
settings.json - Emacs: via eglot
For CI formatting, use prettier-plugin-nix-js.
Links
- npm: www.npmjs.com/package/@deijose/nix-js
- LSP: www.npmjs.com/package/@deijose/nix-js-language-server
- GitHub: github.com/DeijoseDevelop/nix-js
- Website: nix-js.dev
License
MIT