nudo — Zed extension
Zed extension that registers the Nudo
language server (@nudojs/lsp) as a secondary language server for JavaScript and TypeScript
(alongside vtsls / typescript-language-server).
Requires @nudojs/lsp ≥ 0.5.0 — that release ships the
nudo-lsp bin and defaults to stdio when no transport flag is passed.
Install
Once published to the Zed extensions registry: Extensions → search “nudo-lsp” → Install.
Dev install (from this repo)
rustup target add wasm32-wasip2 # onceIn Zed: Extensions → Install Dev Extension… → select this repository root.
Language server
The extension installs the latest @nudojs/lsp via Zed’s managed npm
(npm_install_package) and launches node_modules/@nudojs/lsp/dist/server.js --stdio.
No manual install is required.
Settings
{
"languages": {
"JavaScript": {
"language_servers": ["vtsls", "nudo", "..."]
},
"TypeScript": {
"language_servers": ["vtsls", "nudo", "..."]
},
"TSX": {
"language_servers": ["vtsls", "nudo", "..."]
}
},
"code_lens": "on",
"inlay_hints": { "enabled": true }
}Notes:
- Zed's language names are
JavaScript(.js/.mjs/.jsx),TypeScript(.ts),TSX(.tsx) — there are noJavaScript React/TypeScript Reactlanguages in Zed. "..."keeps every other registered server enabled, so once the extension is installed Zed also auto-includesnudoby default; listing it explicitly makes it the primary server, which is usually not what you want — keepvtsls(ortypescript-language-server) primary and letnudorun as the secondary. Hover, diagnostics, inlay hints and code lenses fromnudoare merged alongside the primary server's results.nudoanalyzes.js/.mjs/.tsonly (isNudoTargetPath);.jsx/.tsx/.cjs/.d.tsand sidecar contract modules are not inference targets.- By default only files containing
@nudo:directives are analyzed (analysis.mode: "directives"). To analyze every export, set"nudo": { "analysis": { "mode": "exports" } }inpackage.json#nudo(ornudo.json).
Enable semantic tokens if you want type-aware highlighting:
{
"semantic_tokens": "combined"
}LSP settings passthrough
Like other Zed language-server extensions (and the VS Code client settings face),
lsp.nudo.settings / lsp.nudo.initialization_options are forwarded to the server:
{
"lsp": {
"nudo": {
"settings": {},
"initialization_options": {}
}
}
}Project analysis config still lives in package.json#nudo (or nudo.json) —
analysis.mode / include / exclude are project config, not editor config.
Observation selector: contract vs cases
The lens row is an observation selector — contract is one option alongside
each case, exactly one active at a time (● active / ○ inactive):
● contract / hw|gen|imp(handwritten / generated / implicit tier) — the default. Click to switch back to the contract observation (nudo.selectContract); clicking with no active case is an idempotent no-op.○ case "name"— click to select (nudo.selectCase); the contract option flips to○.⚡ persist contract/⚡ draft contractactions and the synthesizedcall@L6 (5, 3) => 2/entry@observation lenses stay visible regardless.
Hover and Abs type inlays (param constraints, return term/pred) always show — they are the inference surface, not the observation vocabulary. The inlay tier projection (for clients without CodeLens UI) mirrors the active state.
How the server is found
The extension resolves the server the same way as other Zed language-server
extensions (e.g. Astro): npm_install_package("@nudojs/lsp") into the
extension work directory, then run
<node_binary_path>/node_modules/@nudojs/lsp/dist/server.js --stdioBinary override (skip the managed install):
{
"lsp": {
"nudo": {
"binary": {
"path": "nudo-lsp",
"arguments": []
}
}
}
}Or point at a project install:
{
"lsp": {
"nudo": {
"binary": {
"path": "node",
"arguments": ["/abs/path/node_modules/@nudojs/lsp/dist/server.js"]
}
}
}
}Build
Zed compiles the extension (WASM, wasm32-wasip2) when you install a dev extension.
Manual check:
cargo build --target wasm32-wasip2 --releasePublish to the Zed registry
Zed installs extensions as git submodules under zed-industries/extensions.
Push this repo to GitHub (
nudojs/nudo-zed).Open a PR against
zed-industries/extensions:git submodule add https://github.com/nudojs/nudo-zed extensions/nudo-lsp git commit -m "Add nudo-lsp extension"Add to
extensions.toml:[nudo-lsp] submodule = "extensions/nudo-lsp" version = "0.1.3"Run
pnpm sort-extensions, then open the PR.Bump
versioninextension.tomland push when releasing updates.
License
MIT — see LICENSE.