Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>wgsl.runNew to Visual Studio Code? Get it now.
wgsl.run

wgsl.run

Ugur Toprakdeviren

|
3 installs
| (0) | Free
WGSL language support — diagnostics, hover, go-to-definition, semantic highlighting. All semantics from a wasm-compiled WGSL frontend (no client-side regex/grammar fallbacks).
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

wgsl.run — VS Code extension

Diagnostics, hover, go-to-definition, find references, rename, completions, and semantic highlighting for WGSL. Every semantic decision flows from a wasm-compiled libwgsl frontend — the same spec-conformant pipeline that ships as a C library.

v1.0 status

Spec coverage W3C WGSL Recommendation §3–§18 — full
WGSL spec pin CRD-2026-05-07
Engine libwgsl wasm (single source of truth)
Performance ~0.37 ms / Kloc warm — well under the 16 ms frame budget
Bundle wasm + ~1 KLoc TypeScript glue, no regex grammar

Design — wasm first, TS minimum

Conventional WGSL extensions ship a TextMate grammar (regex-driven) for instant offline coloring, then layer LSP semantic tokens on top for resolver-aware refinement. This extension deliberately omits the regex grammar — every coloured byte comes from the wasm frontend's wgsl_semantic_tokens walk over the resolved AST.

Tradeoff: until the wasm bundle finishes loading on extension activation (~50 ms cold), the document is uncoloured. In return:

  • one source of truth for what every identifier means;
  • no second classification regex that can drift away from the real spec rules over time;
  • the same engine that produces the diagnostics also produces the highlights, so they can never disagree;
  • the engine that powers diagnostics is the same one shipped in libwgsl.a for C consumers — what you see in the editor is what any downstream pipeline will see.

language-configuration.json is the only declarative metadata: it tells VS Code which characters are bracket pairs and what the comment markers look like, purely for editing UX (auto-close-bracket, comment-toggle). No grammar.

Architecture

        (wasm bundle)
   wgsl_compiler.{js,wasm}
            │
            ▼  WGSLClient (FFI wrapper, src/extension.ts)
            │
            ▼
   DocumentCompiler  ── for each .wgsl document:
            │            1. resolve preamble (wgslconfig.toml or _shared.wgsl)
            │            2. split on `// --- KERNEL: <name> ---`
            │            3. build N synthetic sources:
            │                 preamble ++ file_preamble ++ section_body
            │            4. wgsl_check on each → WGSLResult * per section
            │            5. cache by (uri, version)
            ▼
   { split, results[] }
            │
   ┌────┬────┬────┬────┬────┬─────┬──────────┐
   ▼    ▼    ▼    ▼    ▼    ▼     ▼
 diags hover def  refs rename completion semantic-tokens
   │    │    │    │    │     │           │
   └─── line/col remap: synth → original ┘

Kernel-split + preamble injection

Multi-kernel .wgsl files (the WebGPU ML pattern: one resource set per // --- KERNEL: <name> --- section, helper preamble at the top, shared utilities in a sibling file) are recognised automatically. The runtime engine that ships these shaders prepends the shared preamble and splits each section before handing it to the driver; the extension does the same to keep diagnostics in sync.

Example: activation.wgsl declares two kernels (gelu_inplace, swiglu_combine), both reference flat_id from a shared preamble, both redeclare n as their own uniform. Without kernel-split, the extension would flag flat_id undeclared and n redeclaration (false positives — those are real WGSL semantics on the fused single-module view, but the engine never compiles it that way). With kernel-split, each section is its own clean compilation.

Preamble resolution

Two paths, in priority order:

  1. wgslconfig.toml (recommended) — discovered by walking up from the document's directory. Driven by the C-side wgsl_project_match (same logic as the CLI). Supports a list of preamble files + glob-based auto_inject_into rules. Files listed never inject into themselves.

    # wgslconfig.toml
    [preamble]
    files = [
        "_enables.wgsl",   # enable subgroups; enable f16;
        "_shared.wgsl",    # helpers used by every kernel
    ]
    auto_inject_into = ["*.wgsl"]
    
  2. Legacy _shared.wgsl — back-compat for projects without a config. If a sibling _shared.wgsl exists, it's prepended.

Diagnostics in preamble files are surfaced when the user opens the preamble file itself, never on the dependent files. When a preamble is saved, every open .wgsl document is re-compiled so its dependents catch any new errors.

Try it

Open any .wgsl file — diagnostics appear in the Problems panel, hover shows the resolved type, Cmd-click jumps to declarations, semantic-tokens colour the source according to the resolver's classification.

Capabilities matrix

Feature Status Source
Error diagnostics ✅ wgsl_check + wgsl_diagnostic*
Hover (resolved type) ✅ wgsl_hover_at_into
Go-to-definition ✅ wgsl_definition_at_into
Find references ✅ sweep over wgsl_semantic_tokens + wgsl_definition_at_into
Rename symbol ✅ same sweep + WorkspaceEdit (refused on shared decls)
Code completion ✅ static keyword/type/builtin tables + file-local decls (heuristic)
Semantic-tokens colour ✅ wgsl_semantic_tokens
Bracket / comment UX ✅ language-configuration.json
wgslconfig.toml ✅ wgsl_project_open_from_string + wgsl_project_match
Kernel-split ✅ // --- KERNEL: <name> --- markers
Re-check on preamble save ✅ onDidSaveTextDocument workspace walk

Configuration

The extension reads wgslconfig.toml from the closest ancestor directory of the open document. Without a config, the legacy _shared.wgsl sibling lookup applies.

No VS Code settings are exposed — every behavior is driven by source files (config + preambles + the wasm engine's diagnostics).

Performance

Operation Cold Warm
Activation (wasm boot) ~50 ms (in-process)
wgsl_check per Kloc ~0.4 ms ~0.37 ms
Hover / definition (cached) ~0.1 ms ~0.05 ms
Find references (1 Kloc) ~2–5 ms (per query)

Per-keystroke re-check on a 1 Kloc shader sits comfortably under the 16 ms frame budget on any modern CPU.

Limitations

  • Cold-start flash: source has no colour for ~50 ms while the wasm bundle initialises on activation. Acceptable for v1.
  • Position encoding: WGSL columns are 1-based byte distances; VS Code uses UTF-16 code units. ASCII identifiers are exact; non-ASCII XID names land 1–3 code units off. v1.x will switch to positionEncodingKind: utf-8 once VS Code adopts it more widely.
  • No incremental re-check: every edit re-runs the full pipeline. The corpus benchmark says 0.37 ms/Kloc warm, so a 1 KLOC shader is comfortably below the 16 ms frame budget on any modern CPU.
  • References / rename are quadratic-ish per call: each query resolves the cursor's decl and then walks every identifier-like token in the document, calling wgsl_definition_at_into per token. For a 1 KLoc shader that's a few hundred wasm hops — fine for a one-shot user action, but heavy enough that we don't recompute on every keystroke. v1.x: a wgsl_uses_of_decl C export that returns the use list in one round-trip.
  • Completions are heuristic: the resolver doesn't expose scope-at-position, so the suggestion list mixes (a) the static WGSL keyword / type / builtin tables and (b) every named decl the document defines. Function-local lets show up outside their function; a future scope-aware C query removes that noise.
  • Renaming a preamble decl from a dependent file is refused to avoid silently missing the other dependents — open the preamble file directly and rename there.

What's powered by the same engine

The extension and the C library are the same compile pipeline. Anything flagged in the IDE is exactly what wgsl_check(source) would report from C / WASM. The implementation covers WGSL §3–§18 in full: 146 reserved words, all 17 attributes, all 19 type constructors, all 11 atomic builtins, all 16 pack/unpack builtins, all 15 texture builtins, behavior-set analysis, layout calculator, uniformity analysis, alias analysis — the whole grammar and rule set.

v1.x roadmap

  • UTF-8 position encoding (positionEncodingKind: utf-8)
  • Scope-aware completion via a new C-side scope query
  • One-round-trip wgsl_uses_of_decl for references / rename
  • WASM bundle size reduction (target < 200 KB gzipped, < 50 ms init)
  • LSP enrichments: signature help, document symbols, inlay hints, code actions ("add enable f16;", "import preamble", …)

License

MIT.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft