diff --git a/docz/docs/03-demos/32-extensions/05-vscode.md b/docz/docs/03-demos/32-extensions/05-vscode.md
index e6db976..9f6b4d3 100644
--- a/docz/docs/03-demos/32-extensions/05-vscode.md
+++ b/docz/docs/03-demos/32-extensions/05-vscode.md
@@ -1,11 +1,11 @@
---
title: Visualizing Data in VS Code
sidebar_label: Visual Studio Code
-description: View Excel files directly in VS Code. Seamlessly browse spreadsheet data without leaving your editor using SheetJS. Navigate between worksheets and pages of data with a responsive
+description: View Excel files directly in VS Code. Seamlessly browse spreadsheet data using SheetJS. Navigate between worksheets and pages of data with a responsive interface.
pagination_prev: demos/cloud/index
pagination_next: demos/bigdata/index
sidebar_custom_props:
- summary: View Excel files directly within Visual Studio Code
+ summary: View Excel spreadsheets directly within Visual Studio Code
---
import current from '/version.js';
@@ -21,13 +21,14 @@ that supports JavaScript extensions for customizing and enhancing functionality.
The ["Complete Example"](#complete-example) uses SheetJS in a VS Code extension
to view Excel files directly within the editor. The extension leverages the VS
-Code "Custom Editor API"[^2] and "WebView API"[^1] to display spreadsheet data
+Code "WebView API"[^1] and "Custom Editor API"[^2] to display spreadsheet data
as HTML tables.
:::tip pass
-["SheetJS Spreadsheet Viewer"](https://marketplace.visualstudio.com/items?itemName=asadbek.sheetjs-demo)
-is a sample extension based on this demo.
+"SheetJS Spreadsheet Viewer" is a sample extension based on this demo. It is
+available on [Open VSX](https://open-vsx.org/extension/asadbek/sheetjs-demo) and
+[VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=asadbek.sheetjs-demo)
[The source code](https://git.sheetjs.com/asadbek064/sheetjs-vscode-extension)
is available on the SheetJS Git server. Feedback and contributions are welcome!
@@ -40,13 +41,11 @@ is available on the SheetJS Git server. Feedback and contributions are welcome!
This demo was verified in the following deployments:
-| Platform | Architecture | Date |
-|:-----------------|:-------------|:-----------|
-| VS Code 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
-| VSCodium 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
-| Cursor | `win11-arm` | 2025-05-15 | TODO
-| Windsurf | `win11-arm` | 2025-05-15 | TODO
-| Void | `win11-arm` | 2025-05-15 | TODO
+| 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 |
:::
@@ -57,30 +56,36 @@ imported from any component or script in the extension.
:::caution pass
-The module must be installed as a development dependency. If the module is
-installed as a normal dependency, `vsce`[^5] (Visual Studio Code Extension
-Manager) will fail to package or publish your extension correctly.
+The SheetJS NodeJS module must be installed as a development dependency. If the
+module is installed as a normal dependency, the `vsce`[^3] command-line tool
+will fail to package or publish the exxtension.
-
-
- {`\
+
+
+
+{`\
npm rm --save xlsx
npm i --save-dev https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
-
-
- {`\
+
+
+
+
+
+{`\
pnpm rm xlsx
pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
-
-
- {`\
+
+
+
+
+
+{`\
yarn remove xlsx
yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
+
+
-
+
:::
@@ -112,11 +117,11 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(provider);
// highlight-end
}
-export function deactivate() {}`}
+export function deactivate() {}
```
-The `custom editor`[^3] is configured to support specific file types, giving us complete control over how each file is
-presented to the user. Additionally, `custom document`[^4] enables us to maintain and persist the state of each individual
+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.
@@ -205,7 +210,17 @@ sequenceDiagram
## Complete Example
-1) Create a new VS Code extension
+:::caution pass
+
+To avoid conflicts with existing extensions, it is strongly recommended to test
+with a different VSCode fork. For example, VSCode and Antigravity users should
+install and use VSCodium for extension development.
+
+:::
+
+1) Download the [`pres.xlsx`](https://docs.sheetjs.com/pres.xlsx) sample file.
+
+2) Create a new VS Code extension
```bash
npx --package yo --package generator-code -- yo code
@@ -215,17 +230,15 @@ When prompted, enter the following options:
- `What type of extension do you want to create?`: Select `New Extension (TypeScript)` and press Enter
- `What's the name of your extension?`: Type `sheetjs-demo` and press Enter
-- `What's the identifier of your extension?`: Press Enter
-- `What's the description of your extension?`: Press Enter
+- `What's the identifier of your extension?`: Press Enter (use the default `sheetjs-demo`)
+- `What's the description of your extension?`: Press Enter (leave blank)
- `Initialize a git repository?`: Type `n` and press Enter
- `Which bundler to use?`: Select `webpack` and press Enter
- `Which package manager to use?`: Select `pnpm` and press Enter

-- `Do you want to open the new folder with Visual Studio Code?`: Press Enter
-
-2) [Install the dependencies](#integration-details) and start the dev server:
+3) Install the SheetJS library and start the dev server:
{`\
cd sheetjs-demo
@@ -234,9 +247,12 @@ pnpm run watch
`}
-3) Save the following code snippet to `src/excelEditorProvider.ts`:
+4) Launch a new editor window using the desired VSCode fork and open the newly
+created `sheetjs-demo` folder.
-{`\
+4) Save the following codeblock to `src/extension.ts`:
+
+```ts title="src/extension.ts (replace contents)"
import * as vscode from 'vscode';
import * as XLSX from 'xlsx';
@@ -245,16 +261,14 @@ class ExcelDocument implements vscode.CustomDocument {
dispose() { }
}
-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
- );
+class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider {
+ // 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);
}
- private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
+ // This is called whenever the user opens a new editor
+ async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise {
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
const options: XLSX.ParsingOptions = {
@@ -263,41 +277,26 @@ export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<
cellDates: true,
};
- return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
- }
-
- // 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);
- }
-
- // 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 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}\`;
+ webviewPanel.webview.html = `${htmlTable}`;
}
-}`}
-
-
-4) Register the custom editor provider in `src/extension.ts`:
-
-{`\
-import * as vscode from 'vscode';
-import { ExcelEditorProvider } from './excelEditorProvider';
+}
export function activate(context: vscode.ExtensionContext) {
- // SheetJS Spreadsheet Viewer extension activating...
- const provider = ExcelEditorProvider.register(context);
+ const provider = vscode.window.registerCustomEditorProvider(
+ 'excelViewer.spreadsheet',
+ new ExcelEditorProvider(),
+ { webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
+ );
context.subscriptions.push(provider);
}
-export function deactivate() {}`}
-
+export function deactivate() {}
+```
-5) Register the custom editor in the `contributes` section of `package.json`:
+5) Add the highlighted lines to the `contributes` section of `package.json`:
-{`\
- "main": "./dist/extension.js",
+```json title="package.json (add highlighted lines)"
"contributes": {
// highlight-start
"customEditors": [
@@ -318,19 +317,38 @@ export function deactivate() {}`}
}
]
},
-`}
-
+```
-6. Inside the editor, open `src/extension.ts` and press F5 or run the command **Debug: Start Debugging**
-from the Command Palette (⇧⌘P). This will compile and run the extension in a new Extension Development Host window.
+6) In the editor, open the Command Palette (Help > "Show All Commands" from the
+menu), type `Debug: Start` and select `Debug: Start Debugging`.
-7. Select the new VSCode Window and open a `.xlsx` or `.xls` file.
+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
+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.
-[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) for more details.
-[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) documentation for more details.
-[^3]: See [`Custom Editor`](https://code.visualstudio.com/api/extension-guides/custom-editors#custom-editor) for more details.
-[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/extension-guides/custom-editors#customdocument) for more details.
-[^5]: See [`Visual Studio Code Extension Manager`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) for more details.
\ No newline at end of file
+:::info pass
+
+When this demo was last tested, the default project assumed VSCode version
+1.109.0 or later. Antigravity 1.19.6 is aligned to VSCode 1.107.0. The default
+extension will not run in Antigravity.
+
+This can be fixed by changing the `vscode` field in `package.json`. When this
+demo was last tested, it was safe to set a minimum version of `^1.100.0`:
+
+```json title="package.json (change highlighted line)"
+ "engines": {
+ // highlight-next-line
+ "vscode": "^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
diff --git a/docz/docs/03-demos/42-engines/02-v8.md b/docz/docs/03-demos/42-engines/02-v8.md
index 7f64237..92a5eda 100644
--- a/docz/docs/03-demos/42-engines/02-v8.md
+++ b/docz/docs/03-demos/42-engines/02-v8.md
@@ -1666,8 +1666,8 @@ This demo was last tested in the following deployments:
|:-------------|:--------------|:---------|:-----------|
| `darwin-x64` | `14.4` | `3.13.7` | 2026-03-04 |
| `darwin-arm` | `14.4` | `3.14.3` | 2026-03-04 |
-| `win11-x64` | `14.4` | `3.11.9` | 2026-02-04 |
-| `win11-arm` | `14.4` | `3.11.9` | 2026-02-04 |
+| `win11-x64` | `14.4` | `3.11.9` | 2026-03-05 |
+| `win11-arm` | `14.4` | `3.11.9` | 2026-03-05 |
| `linux-x64` | `14.4` | `3.13.9` | 2026-03-04 |
| `linux-arm` | `14.4` | `3.13.5` | 2026-03-04 |
diff --git a/docz/docs/09-miscellany/05-contributing.md b/docz/docs/09-miscellany/05-contributing.md
index e1e3150..6cc17d8 100644
--- a/docz/docs/09-miscellany/05-contributing.md
+++ b/docz/docs/09-miscellany/05-contributing.md
@@ -42,7 +42,7 @@ These instructions were tested on the following platforms:
| Platform | Architecture | Test Date |
|:------------------------------|:-------------|:-----------|
| Linux (Ubuntu Linux x64) | `linux-x64` | 2026-02-02 |
-| Linux (Debian Linux AArch64) | `linux-arm` | 2025-01-14 |
+| Linux (Debian Linux AArch64) | `linux-arm` | 2026-03-05 |
| MacOS 15.6 (x64) | `darwin-x64` | 2026-01-21 |
| MacOS 15.7 (ARM64) | `darwin-arm` | 2026-02-02 |
| Windows 11 (x64) + WSL Ubuntu | `win11-x64` | 2025-06-20 |
diff --git a/tests/contributing/darwin.sh b/tests/contributing/darwin.sh
new file mode 100755
index 0000000..17f73e1
--- /dev/null
+++ b/tests/contributing/darwin.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# https://docs.sheetjs.com/docs/miscellany/contributing
+
+SHEETJS_VERSION="0.20.3"
+
+OS="$(uname -s)"
+
+case "$OS" in
+ Darwin) ;;
+ *) echo "unsupported OS: $OS"; exit 1 ;;
+esac
+
+cd /tmp
+
+git --version || { echo "Git not found. Please install Xcode command-line tools."; exit 1; }
+
+export NVM_DIR="$HOME/.nvm"
+[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
+
+if ! command -v nvm &> /dev/null; then curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash; fi
+if ! command -v node &> /dev/null; then nvm install --lts; fi
+nvm use --lts
+node --version
+
+if [ ! -e sheetjs ]; then
+ if ! git clone https://git.sheetjs.com/sheetjs/sheetjs 2>&1; then
+ git config --global http.sslVerify false
+ git clone https://git.sheetjs.com/sheetjs/sheetjs 2>&1
+ git config --global http.sslVerify true
+ fi
+fi
+cd sheetjs
+
+npm i
+npm i -g mocha@2.5.3 voc @sheetjs/uglify-js || sudo npm i -g mocha@2.5.3 voc @sheetjs/uglify-js
+
+rmdir test_files 2>/dev/null || rm -rf test_files
+curl -LO https://test-files.sheetjs.com/test_files.zip
+unzip -q test_files.zip
+mkdir -p tmp
+
+npx -y esbuild@0.14.14 --version
+
+cd modules; make clean; make; cd ..
+make
+make dist
+
+make test_misc
+
+for file in dist/xlsx.full.min.js xlsx.js xlsx.mjs; do
+ if ! stat "$file" > /dev/null 2>&1; then echo "ERROR: $file not found"; exit 1; fi
+done
+
+git checkout -- .
+
+COMMIT_HASH=$(git log | grep -B4 "version bump $SHEETJS_VERSION" | head -1 | awk '{print $2}')
+if [ -z "$COMMIT_HASH" ]; then echo "ERROR: Could not find commit for version $SHEETJS_VERSION"; exit 1; fi
+
+echo "Version $SHEETJS_VERSION : Commit $COMMIT_HASH"
+
+git checkout "$COMMIT_HASH"
+
+make clean; make
+cd modules; make clean; make; cd ..
+make
+make dist
+
+LOCAL_MD5=$(md5 dist/xlsx.full.min.js | awk '{print $4}')
+CDN_MD5=$(curl -k -L "https://cdn.sheetjs.com/xlsx-$SHEETJS_VERSION/package/dist/xlsx.full.min.js" | md5)
+echo "Local MD5: $LOCAL_MD5"
+echo "CDN MD5: $CDN_MD5"
+if [ "$LOCAL_MD5" != "$CDN_MD5" ]; then echo "ERROR: MD5 checksums do not match!"; exit 1; fi
+
+git checkout master
diff --git a/tests/contributing/linux.sh b/tests/contributing/linux.sh
new file mode 100755
index 0000000..daf73ac
--- /dev/null
+++ b/tests/contributing/linux.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# https://docs.sheetjs.com/docs/miscellany/contributing
+
+SHEETJS_VERSION="0.20.3"
+
+OS="$(uname -s)"
+
+case "$OS" in
+ Linux) ;;
+ *) echo "unsupported OS: $OS"; exit 1 ;;
+esac
+
+cd /tmp
+
+MISSING_PKGS=""
+
+for cmd in gcc make curl git unzip; do
+ if ! command -v "$cmd" &> /dev/null; then
+ case "$cmd" in
+ gcc) MISSING_PKGS="$MISSING_PKGS build-essential" ;;
+ *) MISSING_PKGS="$MISSING_PKGS $cmd" ;;
+ esac
+ fi
+done
+
+if [ -n "$MISSING_PKGS" ]; then
+ echo "The following Debian/Ubuntu packages are missing: $MISSING_PKGS"
+ # sudo apt-get update
+ # sudo apt-get install -y $MISSING_PKGS
+ exit 1
+fi
+
+export NVM_DIR="$HOME/.nvm"
+[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
+
+if ! command -v nvm &> /dev/null; then curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash; fi
+if ! command -v node &> /dev/null; then nvm install --lts; fi
+nvm use --lts
+node --version
+
+if [ ! -e sheetjs ]; then
+ if ! git clone https://git.sheetjs.com/sheetjs/sheetjs 2>&1; then
+ git config --global http.sslVerify false
+ git clone https://git.sheetjs.com/sheetjs/sheetjs 2>&1
+ git config --global http.sslVerify true
+ fi
+fi
+cd sheetjs
+
+npm i
+npm i -g mocha@2.5.3 voc @sheetjs/uglify-js || sudo npm i -g mocha@2.5.3 voc @sheetjs/uglify-js
+
+rmdir test_files 2>/dev/null || rm -rf test_files
+curl -LO https://test-files.sheetjs.com/test_files.zip
+unzip -q test_files.zip
+mkdir -p tmp
+
+npx -y esbuild@0.14.14 --version
+
+cd modules; make clean; make; cd ..
+make
+make dist
+
+make test_misc
+
+for file in dist/xlsx.full.min.js xlsx.js xlsx.mjs; do
+ if ! stat "$file" > /dev/null 2>&1; then echo "ERROR: $file not found"; exit 1; fi
+done
+
+git checkout -- .
+
+COMMIT_HASH=$(git log | grep -B4 "version bump $SHEETJS_VERSION" | head -1 | awk '{print $2}')
+if [ -z "$COMMIT_HASH" ]; then echo "ERROR: Could not find commit for version $SHEETJS_VERSION"; exit 1; fi
+
+echo "Version $SHEETJS_VERSION : Commit $COMMIT_HASH"
+
+git checkout "$COMMIT_HASH"
+
+make clean; make
+cd modules; make clean; make; cd ..
+make
+make dist
+
+LOCAL_MD5=$(md5sum dist/xlsx.full.min.js | awk '{print $1}')
+CDN_MD5=$(curl -L "https://cdn.sheetjs.com/xlsx-$SHEETJS_VERSION/package/dist/xlsx.full.min.js" | md5sum | awk '{print $1}')
+echo "Local MD5: $LOCAL_MD5"
+echo "CDN MD5: $CDN_MD5"
+if [ "$LOCAL_MD5" != "$CDN_MD5" ]; then echo "ERROR: MD5 checksums do not match!"; exit 1; fi
+
+git checkout master
diff --git a/tests/engines/miniracer.ps1 b/tests/engines/miniracer.ps1
index 725dcb8..ed2f463 100644
--- a/tests/engines/miniracer.ps1
+++ b/tests/engines/miniracer.ps1
@@ -8,9 +8,7 @@ New-Item -ItemType Directory -Path $tempDir | Out-Null
Set-Location -Path $tempDir
pip install mini-racer 2>&1 | Out-Null
-if ($LASTEXITCODE -ne 0) {
- python -m pip install mini-racer
-}
+if ($LASTEXITCODE -ne 0) { python -m pip install mini-racer }
Invoke-WebRequest -Uri "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" -OutFile "xlsx.full.min.js"
Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "pres.xlsx"