spark-html-language-server
v1.4.0
Published
Language server (LSP) for spark-html single-file components, including spark-ssr pages — diagnostics (undefined bindings, unused imports, script errors, missing key), spark-ssr-aware inferred page data & ambient helpers, semantic highlighting + formatting
Maintainers
Readme
spark-html-language-server
Language server (LSP) for Spark single-file
.html components. Zero dependencies, speaks LSP over stdio.
What you get
- Diagnostics, live as you type:
{binding}used in the template but never declared in<script>- JS imports that are never used
- script syntax errors (the exact code the runtime would execute)
<div import="…">pointing at a component file that doesn't existeachwithoutkey=(hint — keyed reconciliation is opt-in)- malformed
eachexpressions - an unquoted
on*={…}handler whose expression contains whitespace (onclick={x = y},onclick={f(a, b)}) — HTML ends an unquoted attribute value at the first space, silently breaking the markup - a
<div import>prop name with a hyphen or an uppercase letter (me-name,meName) — it can't reach the child's{expr}as written (HTML lowercases attribute names on parse; a hyphen isn't valid inside a bare identifier)
- Go-to-definition — jump from
<div import="components/card">tocard.html, and from any{symbol}to itslet/function/$:/export letdeclaration. - Autocomplete
- props on import placeholders, read from the target component's
export letdeclarations - filesystem paths inside
import="…"—.htmlcomponent files (inserted without the optional extension) and directories, listed relative to the editing file, the workspace root, and itspublic/ - every template directive (
each,if/else-if/else,await/then/catch,bind:value|checked|group|form,:hidden-style dynamic attributes,key,route,transition:fade|slide|scale,spark-ignore) - script symbols and Spark builtins (
useStore,onMount,props) inside{…}and<script>
- props on import placeholders, read from the target component's
- Hover docs for every directive and declaration.
- Semantic highlighting for
<spark-ssr>block bodies — SQL keywords,'strings', numbers,:params(:session.id,:q), binding names,METHOD /path →endpoint lines, and URL/glob/module sources all get real token colors viatextDocument/semanticTokens/full. HTML grammars see these blocks as plain text; the LSP is what makes them readable. - Document formatting (
textDocument/formatting) — delegated toprettier-plugin-sparkwhen it (and prettier) are installed in your project:<script>/<style>formatted as JS/CSS,<spark-ssr>bodies laid out one binding per line with the=column aligned and long SQL broken before its top-level clauses. If the plugin isn't installed the request is declined quietly — nothing breaks.
spark-ssr
Any file with a <spark-ssr> tag — or living under pages/ / api/
(or middleware.html) of a project with a spark.json — is treated as an
SSR page, tag or no tag — the analyzer
picks up spark-ssr's inferred backend so it doesn't false-flag things the
runtime supplies for you:
- Inferred page data —
<spark-ssr table="todos" live />and named<spark-ssr>blocks (posts = SELECT …,GET /api/x → posts = …, URL/glob/ module sources) declare page vars, including the table/singular fuzzy match spark-ssr itself uses (table="posts"also satisfies{post.title}). - Ambient identifiers —
session,path,flash,errors,values, and the client-side helpersapi_create,api_update,api_delete,refreshare always in scope, with hover docs and autocomplete. - Synthesized handlers & bind targets — an undeclared
onclick={remove}-style handler is assumed auto-synthesized by spark-ssr, and a barebind:value="draft"target is framework-declared state — neither is flagged as undefined (a plain spark-html component still flags both). - Route params —
pages/pin/[id].htmlputsidin scope. - Query params, honestly — spark-ssr spreads
?next=…-style query params into page scope at request time, so an undeclared name on an SSR page is never a warning: it's downgraded to an unobtrusive hint explaining the query-param case (a plain component keeps the real warning). - Directive docs for
table,live,seed,limit,search,cache,guard,redirect,status,flash,job,every,on,auto, and the<spark-pager>/<spark-search>/<spark-flash>elements.
Install
bun add -g spark-html-language-serverThe spark-html-language-server binary starts the server on stdio — the
transport every LSP client speaks.
VS Code
Install the Spark (spark-html) extension from
editors/vscode —
it bundles syntax highlighting and launches this server automatically (globally
installed binary, or node_modules/.bin in your project).
Programmatic use
The analyzer is exported for tooling:
import { analyze } from 'spark-html-language-server';
const { declarations, props, diagnostics } = analyze(componentSource);Scope (v0.x)
The server analyzes one component at a time — the same boundary the runtime
has. It does not type-check across files (props completion reads the target
file's export let names, not their types), and remote URL imports are not
resolved.
The Spark family
Small, single-purpose packages that share one philosophy: no compiler, no virtual DOM, no build step required — built for humans who love hand-writing their web apps. Add only what you use.
| Package | What it does |
|---|---|
| spark-html | The runtime — components, reactivity, stores, forms, scoped styles. ~14.6 kB gzip, 0 deps. |
| spark-html-bun | Dev server, bundler & preview on Bun — scoped HMR, no-build dev, post-build pipeline. |
| spark-html-router | <template route> routing — nested routes/layouts, route.query, active links. |
| spark-html-theme | Dark/light/system theming in one line — persisted, no flash. |
| spark-html-head | Reactive <title>/<meta> per route + a head store. |
| spark-html-motion | Enter/leave transitions on if/each blocks — transition="fade|slide|scale". |
| spark-html-devtools | In-page devtools — live stores, component tree, patch activity. |
| spark-html-query | Declarative async data — a self-fetching store (loading/error/data/refetch). |
| spark-html-persist | Persist stores to localStorage/sessionStorage in one line. |
| spark-html-websocket | A WebSocket as a reactive store — auto-reconnect, JSON, send(). |
| spark-prerender | Build-time SEO prerender + sitemap/robots — no SSR server. |
| spark-ssr | Full-stack SSR on Bun — the template is the backend: inferred DB, REST CRUD, auth, live updates. Precompiled + response-cached: fast by default. |
| spark-html-image | Build-time image optimization — webp/avif + responsive srcset, zero config. |
| spark-html-font | Font loading optimizer — preload + size-adjusted fallbacks, no FOUT. |
| spark-html-manifest | PWA manifest + icons + head tags (and optional service worker) from one config. |
| spark-html-offline | Offline URL imports — a service worker that caches CDN components. |
| spark-html-sri | Subresource Integrity — hash + verify assets and remote components. |
| create-spark-html-app | Scaffold a spark-html app in one command. |
| prettier-plugin-spark | Prettier for components — formats <script>/<style>, markup stays byte-for-byte. |
| spark-html-language-server | LSP — diagnostics, go-to-definition, prop autocomplete, hover docs. |
License
MIT
