From bd8669b4f7938a70de463d727e4104332b8bba56 Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Wed, 9 Sep 2026 15:44:55 +0200 Subject: [PATCH 1/4] Add motoko.lite setting to disable the language server The extension boots a full language server that embeds the moc.js WASM compiler (~8MB bundled) and type-checks every open .mo file on each edit, which is heavy in both compute and memory. While we can't slim that down, we can let users opt out of it. Add a per-workspace `motoko.lite` setting (default false) that skips the language server entirely at activation: startup skips the eager compiler context, the Mops/Vessel/dfx workspace scan, and the typed-AST reparse loop, so the compiler never loads into the extension host. Lightweight features that don't depend on the server keep working - syntax highlighting (TextMate grammar), prettier formatting, snippets, and dfx.json schema validation. The `Motoko: Restart language server` command becomes a no-op with an explanatory message instead of silently failing. Disables in lite mode: diagnostics/type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the Import Mops Package command. Co-Authored-By: Claude Code --- README.md | 1 + package.json | 8 +++++++- src/extension.ts | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aaea93a..c080b4c5 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Below are the default key bindings for commonly used features supported in the e - `motoko.canister`: The default canister name to use in multi-canister projects - `motoko.formatter`: The formatter used by the language server - `motoko.mocJsPath`: Path to moc.js file for using a custom Motoko version +- `motoko.lite`: Light mode. Disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the "Import Mops Package" command) to reduce memory and CPU usage. Syntax highlighting, formatting, snippets, and `dfx.json` schema validation keep working, since none of those come from the language server. Set this (e.g. `"motoko.lite": true`) in your `settings.json` when you want a minimal, lightweight Motoko editing experience — it takes effect after reloading the window. ## Advanced Configuration diff --git a/package.json b/package.json index 9263bead..070bd3ba 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-motoko", "displayName": "Motoko", "description": "Motoko language support", - "version": "0.23.6", + "version": "0.24.0", "publisher": "dfinity-foundation", "repository": "https://github.com/caffeinelabs/vscode-motoko", "engines": { @@ -125,6 +125,12 @@ "type": "string", "default": "", "description": "Path to moc.js file for using a custom Motoko version (absolute, or relative to workspace root). Only load moc.js files from trusted sources." + }, + "motoko.lite": { + "scope": "resource", + "type": "boolean", + "default": false, + "description": "Light mode: disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the 'Import Mops Package' command) to reduce memory and CPU usage. Keeps syntax highlighting, formatting, and snippets. Takes effect after reloading the window." } } }, diff --git a/src/extension.ts b/src/extension.ts index 549b73e2..48faed07 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -36,6 +36,19 @@ import { ignoreGlobPatterns, watchGlob } from './common/watchConfig'; let client: LanguageClient; export function activate(context: ExtensionContext) { + // Lite mode: skip the language server entirely (and everything that depends + // on it) to reduce memory and CPU usage. Keeps syntax highlighting, + // formatting, and snippets, since those don't come from the server. + if (workspace.getConfiguration('motoko').get('lite')) { + context.subscriptions.push( + commands.registerCommand('motoko.startService', () => + window.showInformationMessage( + 'Motoko lite mode is on: the language server is disabled. Turn off "motoko.lite" to enable type checking, completions, hover, and navigation.', + ), + ), + ); + return; + } context.subscriptions.push( commands.registerCommand('motoko.startService', () => startServer(context), From 3a7298953442bcd17075dc6faf2187bbc3ee9d63 Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Wed, 9 Sep 2026 15:55:04 +0200 Subject: [PATCH 2/4] Log a single line when lite mode is on Lite mode was completely silent: the "Motoko Language Server" output channel never exists (the server never starts) and console output would vanish into the shared Extension Host channel. A user who set motoko.lite and forgot would have no signal why half the extension was dead. Add a Motoko log channel (created only in the lite branch) and write a single line when lite mode activates. It appears under Output -> Extension Logs -> Motoko and persists to the Extension Logs folder, so a confused user can find it. Regular mode creates nothing, so there is no footprint. Co-Authored-By: Claude Code --- src/extension.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index 48faed07..b9747082 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -39,8 +39,19 @@ export function activate(context: ExtensionContext) { // Lite mode: skip the language server entirely (and everything that depends // on it) to reduce memory and CPU usage. Keeps syntax highlighting, // formatting, and snippets, since those don't come from the server. - if (workspace.getConfiguration('motoko').get('lite')) { + const lite = workspace.getConfiguration('motoko').get('lite'); + if (lite) { + // Log channel is only created in lite mode, so regular mode has zero + // footprint. Since there is no language server in lite mode, this + // single entry is the only place users can see that the setting is on. + const liteLogger = window.createOutputChannel('Motoko', { + log: true, + }); + liteLogger.appendLine( + `Motoko lite mode is ON (motoko.lite): the language server is disabled, so type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the "Import Mops Package" command are unavailable. Syntax highlighting, formatting, snippets, and dfx.json schema validation keep working. Set "motoko.lite" to false and reload the window to re-enable the language server.`, + ); context.subscriptions.push( + liteLogger, commands.registerCommand('motoko.startService', () => window.showInformationMessage( 'Motoko lite mode is on: the language server is disabled. Turn off "motoko.lite" to enable type checking, completions, hover, and navigation.', From 181fbc8fcdb8fbbe80f7ef754605a453b137dca8 Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Wed, 9 Sep 2026 16:01:32 +0200 Subject: [PATCH 3/4] Correct docs: formatting is server-provided, not kept in lite mode Review found that every 'formatting keeps working in lite mode' claim was wrong: formatting is only provided via connection.onDocumentFormatting in the language server (src/server/handlers.ts), and there is no client-side document formatting provider. So with the server skipped, 'Format Document' / format-on-save is disabled too. Align the copy (package.json description, README setting docs, the lite log line and code comment): formatting moves to the disabled list, and the kept-working list is syntax highlighting, snippets, and dfx.json schema validation. Also note in the README that motoko.lite is workspace-scoped, so a user-level setting has no effect. Co-Authored-By: Claude Code --- README.md | 2 +- package.json | 2 +- src/extension.ts | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c080b4c5..4d3e38e8 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Below are the default key bindings for commonly used features supported in the e - `motoko.canister`: The default canister name to use in multi-canister projects - `motoko.formatter`: The formatter used by the language server - `motoko.mocJsPath`: Path to moc.js file for using a custom Motoko version -- `motoko.lite`: Light mode. Disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the "Import Mops Package" command) to reduce memory and CPU usage. Syntax highlighting, formatting, snippets, and `dfx.json` schema validation keep working, since none of those come from the language server. Set this (e.g. `"motoko.lite": true`) in your `settings.json` when you want a minimal, lightweight Motoko editing experience — it takes effect after reloading the window. +- `motoko.lite`: Light mode. Disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, **format on save / format document**, and the "Import Mops Package" command) to reduce memory and CPU usage. Syntax highlighting, snippets, and `dfx.json` schema validation keep working — those come from the TextMate grammar and schema validator, not the language server. Set this (e.g. `"motoko.lite": true`) in your **workspace** `settings.json` when you want a minimal, lightweight Motoko editing experience. Note: because this is a workspace-scoped (`scope: "resource"`) setting, setting it in your *user* or *remote* `settings.json` will have no effect. It takes effect after reloading the window. ## Advanced Configuration diff --git a/package.json b/package.json index 070bd3ba..494fc9f0 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "scope": "resource", "type": "boolean", "default": false, - "description": "Light mode: disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the 'Import Mops Package' command) to reduce memory and CPU usage. Keeps syntax highlighting, formatting, and snippets. Takes effect after reloading the window." + "description": "Light mode: disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, format on save / format document, and the 'Import Mops Package' command) to reduce memory and CPU usage. Keeps syntax highlighting, snippets, and dfx.json schema validation. See the README 'motoko.lite' setting for details. Takes effect after reloading the window." } } }, diff --git a/src/extension.ts b/src/extension.ts index b9747082..46927ca1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,7 +38,8 @@ let client: LanguageClient; export function activate(context: ExtensionContext) { // Lite mode: skip the language server entirely (and everything that depends // on it) to reduce memory and CPU usage. Keeps syntax highlighting, - // formatting, and snippets, since those don't come from the server. + // snippets, and dfx.json schema validation, since those don't come from + // the server. Formatting is also server-provided, so it's disabled too. const lite = workspace.getConfiguration('motoko').get('lite'); if (lite) { // Log channel is only created in lite mode, so regular mode has zero @@ -48,7 +49,7 @@ export function activate(context: ExtensionContext) { log: true, }); liteLogger.appendLine( - `Motoko lite mode is ON (motoko.lite): the language server is disabled, so type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, and the "Import Mops Package" command are unavailable. Syntax highlighting, formatting, snippets, and dfx.json schema validation keep working. Set "motoko.lite" to false and reload the window to re-enable the language server.`, + `Motoko lite mode is ON (motoko.lite): the language server is disabled, so type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, formatting, and the "Import Mops Package" command are unavailable. Syntax highlighting, snippets, and dfx.json schema validation keep working. Set "motoko.lite" to false and reload the window to re-enable the language server.`, ); context.subscriptions.push( liteLogger, From 516c43094e6849b89d923cbf1ec3dc5f84e5e61f Mon Sep 17 00:00:00 2001 From: Kamil Listopad Date: Wed, 9 Sep 2026 16:05:49 +0200 Subject: [PATCH 4/4] Clarify motoko.lite scope and note formatter behavior in lite mode The re-review flagged two doc issues: - The note claiming a user/remote-level motoko.lite 'has no effect' was wrong: resource-scoped settings are settable at every level, so a user-level value takes effect globally. Reword to say how to opt in everywhere vs. per-workspace. - Advanced Configuration's formatOnSave/defaultFormatter only works while the language server runs; cross-reference lite mode so users following both sections aren't surprised by a silent stop. Co-Authored-By: Claude Code --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d3e38e8..b8d8af13 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,14 @@ Below are the default key bindings for commonly used features supported in the e - `motoko.canister`: The default canister name to use in multi-canister projects - `motoko.formatter`: The formatter used by the language server - `motoko.mocJsPath`: Path to moc.js file for using a custom Motoko version -- `motoko.lite`: Light mode. Disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, **format on save / format document**, and the "Import Mops Package" command) to reduce memory and CPU usage. Syntax highlighting, snippets, and `dfx.json` schema validation keep working — those come from the TextMate grammar and schema validator, not the language server. Set this (e.g. `"motoko.lite": true`) in your **workspace** `settings.json` when you want a minimal, lightweight Motoko editing experience. Note: because this is a workspace-scoped (`scope: "resource"`) setting, setting it in your *user* or *remote* `settings.json` will have no effect. It takes effect after reloading the window. +- `motoko.lite`: Light mode. Disables the language server (type checking, completions, hover, go to definition, references/rename, code actions, signature help, workspace symbols, **format on save / format document**, and the "Import Mops Package" command) to reduce memory and CPU usage. Syntax highlighting, snippets, and `dfx.json` schema validation keep working — those come from the TextMate grammar, the snippets contribution, and the built-in JSON validator, not from the language server. Set this (e.g. `"motoko.lite": true`) when you want a minimal, lightweight Motoko editing experience. It is `resource`-scoped, so you can set it in your user/remote settings to enable lite mode everywhere, or in a workspace/folder's `.vscode/settings.json` to enable it only for that project. It takes effect after reloading the window. ## Advanced Configuration If you want VS Code to automatically format Motoko files on save, consider adding the following to your `settings.json` configuration: +> **Note:** these formatter settings only take effect when the language server is running. With `motoko.lite` enabled (see the `motoko.lite` setting above), format-on-save is disabled, since formatting is provided by the language server. + ```json { "[motoko]": {