@obergodmar/coc-svelte-language-tools
obergodmarSvelte and SvelteKit language support for coc.nvim, maintained with upstream language-tools
Published Package Summary
Svelte language tools for coc.nvim
An independent CoC client maintained in a fork of sveltejs/language-tools. The language server, TypeScript plugin and svelte2tsx are built from the same checkout.
Status
Version 0.2.0. Tested on Linux with Node 24, Neovim 0.12.5, Vim 9.2, a pinned coc.nvim master revision, coc-tsserver 2.4.1, TypeScript 6.0.3, Svelte 4.2.20 / 5.57.1 and SvelteKit 2.70.3. Other coc.nvim revisions and operating systems have not yet been integration-tested.
Available through the Svelte language server:
- Completion, hover, diagnostics, definitions, references and symbol rename.
- Formatting, code actions, document/workspace symbols and folding.
- Semantic tokens, inlay hints, linked editing and call hierarchy, subject to the corresponding CoC settings and server capabilities.
- HTML, CSS and TypeScript features inside Svelte components, including Svelte 5 runes.
The client adds:
- A managed service in
:CocList services, restart and output logging. - Live TS/JS buffer synchronization, including replay after restart and discard on close.
- TypeScript plugin discovery and configuration through coc-tsserver, including unsaved Svelte props, replay after tsserver restart and discard on buffer close.
- Import updates for moves performed through CoC's file operations.
- Reference CodeLens adaptation, compiled JS/CSS previews, extraction and migration commands.
- Restart after saving Svelte, Vite, TypeScript or Prettier configuration.
- Automatic tag closing and native Svelte block snippets.
- SvelteKit route file generation for TypeScript and JavaScript.
Development
Install Nix, devenv 2.1.2 or newer, and direnv with its shell hook. From the fork root:
direnv allow
coc-setup
coc-build
coc-test
coc-test-setup
coc-test-integration
coc-test-vim
Without direnv, prefix each command with devenv shell --.
Node, pnpm, Neovim and Vim come from Nix. pnpm is pinned to the upstream
packageManager version through a fixed-output Nix derivation; Corepack is not required.
JavaScript dependencies use the committed pnpm lockfile. This is a Nix development
environment, not an offline Nix derivation of the entire JavaScript dependency graph.
coc-test-setup downloads a checksum-verified coc.nvim snapshot and installs its
locked dependencies plus the locked test versions of coc-tsserver and SvelteKit.
Integration tests use isolated editor configuration and data directories under
.coc-test/; they do not change your Neovim configuration.
Install from npm
:CocInstall @obergodmar/coc-svelte-language-tools
For automatic installation, add '@obergodmar/coc-svelte-language-tools' to
g:coc_global_extensions. Keep coc-tsserver for TS/JS integration. Remove
session-local registration of the development extension and disable coc-svelte
to avoid duplicate providers. Updates use :CocUpdate.
Every successful push to the fork's coc branch publishes an automatically
numbered version to npm after the full test suite and offline archive tests pass.
These rolling releases use the latest tag. The archive includes the source
commit (gitHead) and npm provenance.
Load the development extension
Build first. Disable/uninstall coc-svelte and remove any manually configured
Svelte language server to avoid duplicate providers. Install coc-tsserver for
Svelte component support in TS/JS buffers.
In Neovim, load the built package using its absolute directory:
:call CocAction('registerExtensions', '/absolute/path/coc-svelte-language-tools/packages/coc-svelte-language-tools')
This registers the extension for the current session. Launch the editor from the
development shell so that CoC uses the Nix Node runtime, or set g:coc_node_path
to a suitable Node executable. The extension requires Node >=24.12.0.
Ensure .svelte buffers have filetype=svelte; do not associate them with HTML.
Syntax highlighting and indentation remain the editor's responsibility.
Editing helpers
svelte.autoClosingTags defaults to true. Tag closing uses
upstream's html/tag request, respects void elements, and discards replies after
further edits, cursor movement or leaving insert mode. Disable it if another
plugin already closes tags.
Type s- at the beginning of a line to complete s-if, s-each, s-await,
s-key, s-snippet, s-render, s-script or s-style. CoC handles snippet
placeholders; coc-snippets is not required. Disable completion with
svelte.snippets.enable: false. :CocCommand svelte.insertSnippet also opens a
picker and supports inserting a selected block at the cursor.
:CocCommand svelte.createRouteFile asks for an absolute route directory, file
kind and TS/JS language. It supports page, layout, their universal/server load
files, endpoints and error pages. Existing files are never overwritten. Custom
route directories, route groups and dynamic parameter directories are supported.
Templates target Svelte 5 and SvelteKit >=2.16; run your project's
svelte-kit sync to generate $types. The generator does not install SvelteKit.
Build and verify an installable archive
coc-build
coc-pack
pnpm --filter @obergodmar/coc-svelte-language-tools test:package
COC_TEST_EDITOR=vim pnpm --filter @obergodmar/coc-svelte-language-tools test:package
The archive is written to artifacts/obergodmar-coc-svelte-language-tools-0.2.0.tgz.
It bundles runtime dependencies, including the server patches from this checkout.
The package test installs it offline using an empty npm cache, then runs the
same headless editor tests against the installed extension.
Publish only the verified archive. A direct publish from the workspace package is blocked because it could substitute unpatched npm releases for workspace dependencies. No npm release has been published yet.
Current boundaries
- Unsaved Svelte buffers are forwarded to the bundled TypeScript plugin. A separately installed, unpatched upstream plugin does not implement this extension protocol.
- External filesystem moves do not carry a reliable rename event; import updates require a move performed through CoC. Complex simultaneous folder moves need more coverage.
- Previews open in a separate read-only scratch window named
[Svelte compiled]. JS/CSS filetypes are set explicitly; no virtual URI or file on disk is needed. Close the window with:close. Previews are snapshots; run the command again after editing. - SvelteKit
$typesand$lib, multiple workspace roots, Svelte 4/5 and Vim are integration-tested. SvelteKit 3, macOS and Windows remain outside the tested matrix. - Tailwind and ESLint require their own providers. Avoid multiple formatting providers or HTML auto-close plugins acting on the same Svelte buffer.
The automated integration suite currently exercises completion, runes, diagnostics,
cross-file definitions, semantic tokens, formatting, unsaved TS/Svelte changes,
server restarts, plugin toggling, coc-tsserver component resolution, import updates,
compiled preview, tag closing, snippets, route generation and overwrite protection.
It also runs SvelteKit sync and verifies generated props, $lib definitions and
Svelte 4/5 isolation in three workspace roots, in both Vim and Neovim.
Run :CocCommand svelte.showEnvironment from the affected project buffer to open a copyable report in Svelte Environment. It distinguishes project package resolution, bundled server dependencies, configured paths and the last launched process. It also works with svelte.enable: false and does not start servers or execute project configuration. Project resolution is an on-disk check, not a claim about modules already loaded by a custom server.
- Svelte and SvelteKit language support for coc.nvim, maintained with upstream language-tools
- onLanguage:svelte
- onLanguage:javascript
- onLanguage:javascriptreact
- onLanguage:typescript
- onLanguage:typescriptreact
- onCommand:svelte.showEnvironment
- onCommand:svelte.restartLanguageServer
- onCommand:svelte.typescript.findFileReferences
- onCommand:svelte.typescript.findComponentReferences
- onCommand:svelte.showCompiledCode
- onCommand:svelte.showCompiledCSS
- onCommand:svelte.extractComponent
- onCommand:svelte.migrate_to_svelte_5
- onCommand:svelte.insertSnippet
- onCommand:svelte.createRouteFile
Want to build, test, or contribute to coc.nvim extensions? Explore our official SDK and testing toolkits.
Open Developer GuideVersion History
Published with @obergodmar/coc-svelte-language-tools@0.2.13 as node_modules/svelte-language-server/CHANGELOG.md.
Changelog
0.18.4
Patch Changes
-
fix: don't log an error for vite configs without a Svelte plugin (#3091)
-
fix: handle SvelteKit 3 having its config merged at the top level (#3104)
-
Updated dependencies [
820daab]:- svelte2tsx@0.7.61
0.18.3
Patch Changes
-
fix: load esm version of Vite (#3065)
-
perf: remove lodash (#3038)
-
feat: provide utils for svelte-check tsgo integration (#3036)
-
Updated dependencies [
7a3464b,a2561fc,459d031]:- @sveltejs/load-config@0.2.0
- svelte2tsx@0.7.57
0.18.2
Patch Changes
-
fix: don't show type inlay hint for component inside snippets (#3041)
-
fix: correct 'occured' typo in
svelte:boundaryonerrordescription (shown in editor IntelliSense) (#3039) -
feat: support reading Svelte config from
vite.config.js/ts(#3031) -
fix: mark optional members with a trailing
?in completion labels (#3044) -
Updated dependencies [
151cf45]:- @sveltejs/load-config@0.1.1
0.18.1
Patch Changes
-
feat: add support for svelte config ts/mts files (#3009)
-
feat: support CSS completions in nested style tags (#3022)
-
fix: support prettier.useEditorConfig setting (#3026)
-
fix: prevent > in expression affects HTML folding (#3029)
-
Updated dependencies [
86fafb1,6bd8b17,4a064e5,e9f4ce9,3474048]:- svelte2tsx@0.7.56
0.18.0
Minor Changes
- feat: typescript 6.0 support (#2985)
Patch Changes
- Updated dependencies [
29e2894]:- svelte2tsx@0.7.55
0.17.31
Patch Changes
-
fix: prevent duplicate diagnostics (#3000)
-
fix: properly place svelte-ignore comment in quickfix when
<script module>presents (#3011) -
fix: prevent incorrect $types imports being injected when moving +page.svelte files (#3010)
-
fix: prevent extra script indentation when inserting svelte-ignore comments (#3011)
-
fix: provide tsconfig.json diagnostics for svelte-check (#3005)
-
Updated dependencies [
8b103ba]:- svelte2tsx@0.7.54
0.17.30
Patch Changes
-
perf: micro-optimizations in hot paths (#2960)
-
fix: prevent config loading message in svelte-check --incremental (#2974)
-
perf: enable incremental TypeScript reparsing via getChangeRange (#2961)
-
perf: various optimization with ast walk (#2969)
-
feat: pull diagnostics support (#2978)
-
fix: prevent error with escape sequence in attribute (#2968)
-
fix: typescript 6.0 compatibility (#2988)
-
Updated dependencies [
5b9a4ac]:- svelte2tsx@0.7.53
0.17.29
Patch Changes
- fix: pass filename to
warningFilter(#2959)
0.17.28
Patch Changes
- feat: support for comments in tags (#2944)
0.17.27
Patch Changes
-
fix: handle relative imports reaching outside working directory when using
--incremental/--tsgoflags (#2942) -
fix: extract style/script tag followed by destructuring in the template (#2921)
-
fix: support SvelteKit zero types in svelte-check --incremental (#2939)
-
Updated dependencies [
6a04679,b914d01]:- svelte2tsx@0.7.49
0.17.26
Patch Changes
-
feat: add links to diagnostic error codes via codeDescription (#2936)
-
chore: provide utils for svelte-check (#2932)
-
Updated dependencies [
0b8af82]:- svelte2tsx@0.7.48
0.17.25
Patch Changes
- fix: apply text synchronize change in order (#2927)
0.17.24
Patch Changes
-
perf: only parse html once in a batch update (#2923)
-
feat: support emmet.extensionsPath config (#2918)
-
feat: custom element JSDoc documentation for completion/hover (#2879)
-
fix: compatibility with prettier-plugin-tailwindcss in monorepo (#2925)
-
Updated dependencies [
e2f09eb]:- svelte2tsx@0.7.47
0.17.23
Patch Changes
-
perf: move return statement in
getCompletionsso it returns immediately if possible (#2899) -
perf: avoid global completion in component start tag (#2904)
-
perf: optimize path normalization (#2907)
-
perf: optimize module resolution cache invalidation check (#2902)
-
fix: add some limit to store auto-import (#2909)
-
[perf]: avoid re-reacting completion items for svelte syntax every time
getCompletionsWithRegardToTriggerCharacteris called (#2900) -
Updated dependencies [
b6ebbd8]:- svelte2tsx@0.7.46
0.17.22
Patch Changes
-
feat: support hierarchical document symbols (#2817)
-
fix: use moustache for svelte5 onhandler completion (#2883)
-
feat: quick fix for adding lang="ts" (#2882)
-
fix: support for @nativescript-community/svelte-native (#2867)
-
fix: always treat a script tag as top-level if it's the first tag in the file (#2886)
-
fix: restrict emmet completion with emmet specific triggerCharacter (#2873)
-
fix: support experimental feature in "Show compiled Code" (#2884)
-
feat: implement 'source.removeUnusedImports' code action (#2875)
0.17.21
Patch Changes
-
perf: check if file content changed in tsconfig file watch (#2859)
-
Updated dependencies [
7468286]:- svelte2tsx@0.7.45
0.17.20
Patch Changes
Contributed Commands
All contributes.commands entries from the published package manifest for @obergodmar/coc-svelte-language-tools@0.2.13.
| Command (:CocCommand) | Description |
|---|---|
| svelte.showEnvironment | Svelte: show environment |
| svelte.restartLanguageServer | Svelte: restartLanguageServer |
| svelte.typescript.findFileReferences | Svelte: typescript.findFileReferences |
| svelte.typescript.findComponentReferences | Svelte: typescript.findComponentReferences |
| svelte.showCompiledCode | Svelte: showCompiledCode |
| svelte.showCompiledCSS | Svelte: showCompiledCSS |
| svelte.extractComponent | Svelte: extractComponent |
| svelte.migrate_to_svelte_5 | Svelte: migrate_to_svelte_5 |
| svelte.insertSnippet | Svelte: insert snippet |
| svelte.createRouteFile | SvelteKit: create route file |
Configuration Schema
All contributes.configuration entries from the published package manifest, including each raw property schema for coc-settings.json.
Raw JSON Schema
{
"type": "boolean",
"default": true,
"description": "Enable the Svelte language server. Restart coc.nvim after changing this setting."
}Raw JSON Schema
{
"type": "boolean",
"default": true,
"description": "Close HTML and component tags while typing in Svelte buffers."
}Raw JSON Schema
{
"type": "boolean",
"default": true,
"description": "Offer Svelte block snippets with s- prefixes in completion."
}Raw JSON Schema
{
"type": "boolean",
"default": true,
"description": "Enable Svelte integration in coc-tsserver for JavaScript and TypeScript files."
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS",
"default": true,
"description": "Enable the CSS plugin"
}Raw JSON Schema
{
"type": "string",
"title": "CSS: Global Files",
"default": "",
"description": "Which css files should be checked for global variables (`--global-var: value;`). These variables are added to the css completions. String of comma-separated file paths or globs relative to workspace root."
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML",
"default": true,
"description": "Enable the HTML plugin"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte",
"default": true,
"description": "Enable the Svelte plugin"
}Raw JSON Schema
{
"type": "boolean",
"default": false,
"description": "Enable verbose Svelte language server logging."
}Raw JSON Schema
{
"type": "string",
"scope": "application",
"description": "Optional absolute path to a custom language server entry point."
}Raw JSON Schema
{
"type": "string",
"scope": "application",
"description": "Node executable used to launch the server. Defaults to the coc.nvim Node runtime."
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Hover Info",
"default": true,
"description": "Enable hover info for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Hover Info",
"default": true,
"description": "Enable hover info for HTML"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript",
"default": true,
"description": "Enable the TypeScript plugin"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Hover",
"default": true,
"description": "Enable hover information for Svelte"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Format",
"default": true,
"description": "Enable formatting for Svelte (includes css & js). You can set some formatting options through this extension. They will be ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Rename",
"default": true,
"description": "Enable rename/move Svelte files functionality"
}Raw JSON Schema
{
"type": "array",
"items": {
"type": "string"
},
"scope": "application",
"default": [],
"description": "Additional Node arguments for the language server."
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Include Emmet Completions",
"default": true,
"description": "Enable emmet auto completions for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Auto Complete",
"default": true,
"description": "Enable auto completions for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Diagnostics",
"default": true,
"description": "Enable diagnostic messages for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Include Emmet Completions",
"default": true,
"description": "Enable emmet auto completions for HTML"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Auto Complete",
"default": true,
"description": "Enable auto completions for HTML"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Tag Auto Closing",
"default": true,
"description": "Enable HTML tag auto closing"
}Raw JSON Schema
{
"type": "object",
"title": "Svelte: Compiler Warnings Settings",
"default": {},
"description": "Svelte compiler warning codes to ignore or to treat as errors. Example: { 'css-unused-selector': 'ignore', 'unused-export-let': 'error'}",
"additionalProperties": {
"enum": [
"ignore",
"error"
],
"type": "string"
}
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Hover Info",
"default": true,
"description": "Enable hover info for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"default": true,
"description": "Update Svelte imports for file moves performed through coc.nvim."
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Document Colors",
"default": true,
"description": "Enable document colors for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: SelectionRange",
"default": true,
"description": "Enable selection range for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Linked Editing",
"default": true,
"description": "Enable Linked Editing for HTML"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Code Actions",
"default": true,
"description": "Enable Code Actions for Svelte"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Completions",
"default": true,
"description": "Enable auto completions for Svelte"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Diagnostics",
"default": true,
"description": "Enable diagnostic messages for Svelte"
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Symbols in Outline",
"default": true,
"description": "Enable document symbols for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "HTML: Symbols in Outline",
"default": true,
"description": "Enable document symbols for HTML"
}Raw JSON Schema
{
"enum": [
"none",
"ts"
],
"type": "string",
"title": "Svelte: Default Script Language",
"default": "none",
"description": "The default language to use when generating new script tags"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Selection Range",
"default": true,
"description": "Enable selection range for Svelte"
}Raw JSON Schema
{
"type": "boolean",
"title": "CSS: Color Picker",
"default": true,
"description": "Enable color picker for CSS"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Code Actions",
"default": true,
"description": "Enable code actions for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Completions",
"default": true,
"description": "Enable completions for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Diagnostics",
"default": true,
"description": "Enable diagnostic messages for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Document Highlight",
"default": true,
"description": "Enable document highlight support. Requires a restart."
}Raw JSON Schema
{
"type": "number",
"title": "Svelte Format: Print Width",
"default": 80,
"description": "Maximum line width after which code is tried to be broken up. This is a Prettier core option. If you have the Prettier extension installed, this option is ignored and the corresponding option of that extension is used instead. This option is also ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Signature Help",
"default": true,
"description": "Enable signature help (parameter hints) for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte Format: Quotes",
"default": false,
"description": "Use single quotes instead of double quotes, where possible. This is a Prettier core option. If you have the Prettier extension installed, this option is ignored and the corresponding option of that extension is used instead. This option is also ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Selection Range",
"default": true,
"description": "Enable selection range for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Semantic Tokens",
"default": true,
"description": "Enable semantic tokens (semantic highlight) for TypeScript."
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Symbols in Outline",
"default": true,
"description": "Enable document symbols for TypeScript"
}Raw JSON Schema
{
"type": "boolean",
"title": "TypeScript: Workspace Symbols",
"default": true,
"description": "Enable workspace symbols for TypeScript."
}Raw JSON Schema
{
"type": "string",
"title": "Svelte Format: Sort Order",
"default": "options-scripts-markup-styles",
"description": "Format: join the keys `options`, `scripts`, `markup`, `styles` with a - in the order you want. This option is ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte Format: Strict Mode",
"default": false,
"description": "More strict HTML syntax. This option is ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte: Legacy/Runes mode Code Lens",
"default": true,
"description": "Show a code lens at the top of Svelte files indicating if they are in runes mode or legacy mode. Only visible in Svelte 5 projects."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte Format: Allow Shorthand",
"default": true,
"description": "Option to enable/disable component attribute shorthand if attribute name and expression are the same. This option is ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte Format: Bracket New Line",
"default": true,
"description": "Put the `>` of a multiline element on a new line. This option is ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}Raw JSON Schema
{
"type": "boolean",
"title": "Svelte Format: Indent Script And Style",
"default": true,
"description": "Whether or not to indent code inside `<script>` and `<style>` tags. This option is ignored if there's any kind of configuration file, for example a `.prettierrc` file."
}