diff --git a/docz/docs/03-demos/32-extensions/05-vscode.md b/docz/docs/03-demos/32-extensions/05-vscode.md
index 9f6b4d3..a24cbb9 100644
--- a/docz/docs/03-demos/32-extensions/05-vscode.md
+++ b/docz/docs/03-demos/32-extensions/05-vscode.md
@@ -39,20 +39,31 @@ is available on the SheetJS Git server. Feedback and contributions are welcome!
:::note Tested Deployments
-This demo was verified in the following deployments:
+This demo was tested in the following deployments:
-| Platform | Architecture | Date |
-|:-------------------|:-------------|:-----------|
-| VSCodium 1.109 | `darwin-arm` | 2026-03-05 |
-| VS Code 1.110.0 | `win11-arm` | 2026-03-05 |
-| Antigravity 1.19.6 | `linux-arm` | 2026-03-05 |
+| Platform | Architecture | Date |
+|:--------------------------------------------------|:-------------|:-----------|
+| [VSCodium 1.109.51242](https://vscodium.com/) | `darwin-arm` | 2026-03-05 |
+| [VS Code 1.110.0](https://code.visualstudio.com/) | `win11-arm` | 2026-03-05 |
+| [Antigravity 1.19.6](https://antigravity.google/) | `linux-arm` | 2026-03-05 |
+
+:::
+
+:::danger Telemetry and Data Exfiltration
+
+VSCode and many forks embed telemetry and send code to third-party servers.
+
+For example, Antigravity includes AI features that are powered by Google Gemini
+and other cloud AI services. These features necessitate code exfiltration.
+
+**[VSCodium](https://vscodium.com/) does not include AI features or telemetry!**
:::
## Integration Details
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
-imported from any component or script in the extension.
+imported from any script in the extension.
:::caution pass
@@ -89,100 +100,156 @@ yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
:::
-## Extension Architecture
+The core extension APIs are available in the `vscode` package. A TypeScript
+extension typically uses "glob imports" to load SheetJS and VSCode features:
-The VS Code Spreadsheet viewer extension has three main components:
-
-- **Extension Entry Point:** Registers the extension with VS Code
-- **Custom Editor Provider:** Handles Excel files and converts them to web content
-- **WebView Content:** Displays Excel data as HTML tables
-
-The extension uses VS Code's `Custom Editor API`[^2] to register as a handler for Excel files. When a file is opened,
-SheetJS parses it and displays the data in a WebView component.
-
-### Extension Entry Point
-
-The main entry point registers the custom editor provider:
-
-```ts title="src/extension.ts"
+```ts title="Importing SheetJS and VSCode features"
import * as vscode from 'vscode';
-// highlight-start
-import { ExcelEditorProvider } from './excelEditorProvider';
-// highlight-end
-
-export function activate(context: vscode.ExtensionContext) {
- // SheetJS Spreadsheet Viewer extension activating...
- // highlight-start
- const provider = ExcelEditorProvider.register(context);
- context.subscriptions.push(provider);
- // highlight-end
-}
-export function deactivate() {}
+import * as XLSX from 'xlsx';
```
-The `custom editor`[^4] is configured to support specific file types, giving us complete control over how each file is
-presented to the user. Additionally, `custom document`[^5] enables us to maintain and persist the state of each individual
-file that's opened.
+## Extension Architecture
-
-{`import * as vscode from 'vscode';
- // highlight-start
- import * as XLSX from 'xlsx';
- import { ExcelDocument } from './excelDocument';
- // highlight-end
+VSCode Extensions for processing custom file types use the Custom Editor API[^2]
+for lifecycle events. This involves a number of moving parts:
- // A simple class to store document state (one per opened file)
- class ExcelDocument implements vscode.CustomDocument {
- constructor(public readonly uri: vscode.Uri) {}
- dispose() {}
+1) "Custom Document" for managing file metadata
+
+2) "Custom Editor Provider" for processing file data and generating previews
+
+3) Registration during extension lifecycle events.
+
+4) Advertisement of filetype support in extension metadata.
+
+When a spreadsheet is opened, the extension will use SheetJS methods to parse
+the raw file and display the data in a HTML table.
+
+### Custom Documents
+
+Extensions must provide a class that implements `vscode.CustomDocument`[^4].
+
+```ts title="Simple CustomDocument"
+class ExcelDocument implements vscode.CustomDocument {
+ constructor(public readonly uri: vscode.Uri) { }
+ dispose() { }
+}
+```
+
+### Editor Provider
+
+Extensions that read data should implement `vscode.CustomReadonlyEditorProvider`
+with a generic parameter for the custom document type.
+
+The `openCustomDocument` method takes a `vscode.Uri` and is expected to return a
+new document:
+
+```ts title="src/extension.ts (snippet)"
+class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
+ async openCustomDocument(uri: vscode.Uri): Promise {
+ return new ExcelDocument(uri);
}
-
- export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
- // ...
- public static register(context: vscode.ExtensionContext): vscode.Disposable {
- return vscode.window.registerCustomEditorProvider(
- 'excelViewer.spreadsheet',
- new ExcelEditorProvider(),
- { webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
- );
- }
- // ...
- }`}
-
+}
+```
### Reading Files
-The extension reads Excel files using the VS Code filesystem API and passes
-the data to SheetJS for parsing:
+The `FileSystemProvider` API[^5], available at `vscode.workspace.fs`, exposes
+common filesystem operations including reading raw data from files and watching
+for changes.
-
-{`export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
+The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
+called when a file is opened. The first argument is a `CustomDocument` whose
+`uri` property points to the location of the file.
+
+`vscode.workspace.fs.readFile`[^5] returns a promise that resolves to a
+`Uint8Array` containing the raw binary data. This `Uint8Array` can be passed to
+the SheetJS [`read`](/docs/api/parse-options) method:
+
+```ts title="src/extension.ts (snippet)"
+export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
+ // ...
+ async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
+ // read the raw bytes from the file
+ const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
+
+ // parse the file data
+ const wb: XLSX.WorkBook = XLSX.read(data);
+
+ // At this point, `wb` is a SheetJS Workbook Object
// ...
- private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
- const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
+ }
+ // ...
+}
+```
- const options: XLSX.ParsingOptions = {
- type: 'array',
- cellStyles: true,
- cellDates: true,
- };
+### Previewing Data
- return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
- }
+The `resolveCustomEditor`[^6] method of the `CustomEditorProvider` will be
+called when a file is opened. The second argument is a `WebviewPanel`[^7].
- // This is called when the first time an editor for a given resource is opened
- async openCustomDocument(uri: vscode.Uri): Promise {
- return new ExcelDocument(uri);
- }
+The `webview.html` nested property of the `WebviewPanel` controls the displayed
+HTML. Extensions can use SheetJS [API methods](/docs/api/).
- // This is called whenever the user opens a new editor
- async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
- const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
- const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
- webviewPanel.webview.html = \`\${htmlTable}\`;
- }
- }`}
-
+The SheetJS [`sheet_to_html`](/docs/api/utilities/html#html-table-output) method
+generates a simple HTML table. The following snippet displays the data of the
+first worksheet:
+
+```ts title="src/extension.ts (snippet)"
+export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
+ // ...
+ async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
+ // ...
+ // continuing from "Reading Files", `wb` is a SheetJS Workbook Object
+ const first_sheet = wb.Sheets[wb.SheetNames[0]];
+ webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
+ }
+ // ...
+}
+```
+
+### Registration
+
+The exported `activate` method registers the editor provider. The first argument
+to `registerCustomEditorProvider` is expected to be a unique name that will be
+referenced later.
+
+```ts title="src/extension.ts (snippet)"
+export function activate(context: vscode.ExtensionContext) {
+ const provider = vscode.window.registerCustomEditorProvider(
+ 'excelViewer.spreadsheet',
+ new ExcelEditorProvider(),
+ { webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
+ );
+ context.subscriptions.push(provider);
+}
+```
+
+### Filetype Support
+
+Extensions must announce custom editor file type support in `package.json`.
+The `selector` property[^8] is expected to include "Glob Pattterns"[^9].
+
+The demo uses the following `package.json` snippet to announce support for `xls`
+and `xlsx` spreadsheets:
+
+```json title="package.json (snippet)"
+ "contributes": {
+ "customEditors": [
+ {
+ // ... other properties including displayName
+ // highlight-start
+ // The viewType must match the first argument of `registerCustomEditorProvider`
+ "viewType": "excelViewer.spreadsheet",
+ "selector": [
+ { "filenamePattern": "*.xlsx" },
+ { "filenamePattern": "*.xls" }
+ ]
+ // highlight-end
+ }
+ ],
+ // ...
+ },
+```
### Usage Flow
@@ -247,10 +314,9 @@ pnpm run watch
`}
-4) Launch a new editor window using the desired VSCode fork and open the newly
-created `sheetjs-demo` folder.
+4) Launch a new window with the VSCode fork and open the `sheetjs-demo` folder.
-4) Save the following codeblock to `src/extension.ts`:
+5) Save the following codeblock to `src/extension.ts`:
```ts title="src/extension.ts (replace contents)"
import * as vscode from 'vscode';
@@ -271,15 +337,11 @@ class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
- const options: XLSX.ParsingOptions = {
- type: 'array',
- cellStyles: true,
- cellDates: true,
- };
+ const options: XLSX.ParsingOptions = { cellStyles: true, cellDates: true };
+ const wb: XLSX.WorkBook = XLSX.read(data, options);
- const wb: XLSX.WorkBook = XLSX.read(new Uint8Array(data), options);
- const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
- webviewPanel.webview.html = `${htmlTable}`;
+ const first_sheet = wb.Sheets[wb.SheetNames[0]];
+ webviewPanel.webview.html = XLSX.utils.sheet_to_html(first_sheet);
}
}
@@ -294,7 +356,7 @@ export function activate(context: vscode.ExtensionContext) {
export function deactivate() {}
```
-5) Add the highlighted lines to the `contributes` section of `package.json`:
+6) Add the highlighted lines to the `contributes` section of `package.json`:
```json title="package.json (add highlighted lines)"
"contributes": {
@@ -319,12 +381,12 @@ export function deactivate() {}
},
```
-6) In the editor, open the Command Palette (Help > "Show All Commands" from the
+7) In the editor, open the Command Palette (Help > "Show All Commands" from the
menu), type `Debug: Start` and select `Debug: Start Debugging`.
This will compile and run the extension in a new Extension Development Host window.
-7) Drag and drop the `pres.xlsx` test file into the new window. If drag and drop
+8) Drag and drop the `pres.xlsx` test file into the new window. If drag and drop
is not available, click "Open..." in the Welcome screen and select the file.
A new `pres.xlsx` tab will show the contents of the file.
@@ -350,5 +412,9 @@ demo was last tested, it was safe to set a minimum version of `^1.100.0`:
[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) in the VSCode documentation for more details.
[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) in the VSCode documentation for more details.
[^3]: See [`vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce) in the VSCode documentation for more details.
-[^4]: See [`Custom Editor`](https://code.visualstudio.com/api/extension-guides/custom-editors#custom-editor) in the VSCode documentation for more details.
-[^5]: See [`CustomDocument`](https://code.visualstudio.com/api/extension-guides/custom-editors#customdocument) in the VSCode documentation for more details.
\ No newline at end of file
+[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/references/vscode-api#CustomDocument) in the VSCode API documentation for more details.
+[^5]: See [`FileSystemProvider`](https://code.visualstudio.com/api/references/vscode-api#FileSystemProvider) in the VSCode API documentation for more details.
+[^6]: See [`CustomEditorProvider`](https://code.visualstudio.com/api/references/vscode-api#CustomEditorProvider<T>) in the VSCode API documentation for more details.
+[^7]: See [`WebviewPanel`](https://code.visualstudio.com/api/references/vscode-api#WebviewPanel) in the VSCode API documentation for more details.
+[^8]: See [`contributes.customEditors`](https://code.visualstudio.com/api/references/contribution-points#contributes.customEditors) in the VSCode API documentation for more details.
+[^9]: See ["Glob Patterns Reference"](https://code.visualstudio.com/docs/editor/glob-patterns) in the VSCode documentation for more details.
\ No newline at end of file