diff --git a/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md b/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md
index 2cc331c..4718025 100644
--- a/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md
+++ b/docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md
@@ -25,7 +25,7 @@ bundle with ESBuild for browser use.
- ["NodeJS"](#nodejs) explores how to import SheetJS libraries in a script and
bundle with ESBuild for NodeJS use.
-:::info pass
+:::note pass
This demo focuses on integration details with the ESBuild bundler.
@@ -34,6 +34,13 @@ The tutorial covers SheetJS library usage.
:::
+:::info pass
+
+The [ESBuild section of the Content demo](/docs/demos/static/esbuild) covers
+loaders. They are ideal for static sites pulling data from sheets at build time.
+
+:::
+
:::note
This demo was last tested on 2023 October 19 against esbuild `0.19.5`
diff --git a/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md b/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md
new file mode 100644
index 0000000..978289e
--- /dev/null
+++ b/docz/docs/03-demos/01-frontend/19-bundler/09-browserify.md
@@ -0,0 +1,151 @@
+---
+title: Bundling Sheets with Browserify
+sidebar_label: Browserify
+pagination_prev: demos/index
+pagination_next: demos/grid/index
+sidebar_position: 9
+---
+
+import current from '/version.js';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
+
+[Browserify](https://browserify.org/) is a module bundler.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo uses Browserify and SheetJS to export data. We'll explore how to add
+SheetJS to a site using Browserify and how to export data to spreadsheets.
+
+:::note
+
+This demo was last tested on 2023 October 21 against Browserify `17.0.0`
+
+:::
+
+## Integration Details
+
+[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
+installation with Yarn and other package managers.
+
+After installing the SheetJS module in a Browserify project, `require`
+expressions can load relevant parts of the library.
+
+```js
+var XLSX = require("xlsx");
+// ... use XLSX ...
+```
+
+Browserify can also process `require` expressions in Web Worker scripts.
+
+## Complete Example
+
+0) Initialize a new project:
+
+```bash
+mkdir sheetjs-browserify
+cd sheetjs-browserify
+npm init -y
+```
+
+1) Install the tarball using a package manager:
+
+
+
+{`\
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+{`\
+pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+{`\
+yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+
+2) Save the following to `index.js`:
+
+```js title="index.js"
+// highlight-next-line
+const { utils, version, writeFileXLSX } = require('xlsx');
+
+document.getElementById("xport").addEventListener("click", function() {
+ /* fetch JSON data and parse */
+ var url = "https://sheetjs.com/data/executive.json";
+ fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
+
+ /* filter for the Presidents */
+ var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
+
+ /* sort by first presidential term */
+ prez.forEach(function(row) {
+ row.start = row.terms.find(function(term) {
+ return term.type === "prez";
+ }).start
+ });
+ prez.sort(function(l,r) { return l.start.localeCompare(r.start); });
+
+ /* flatten objects */
+ var rows = prez.map(function(row) { return {
+ name: row.name.first + " " + row.name.last,
+ birthday: row.bio.birthday
+ }; });
+
+ /* generate worksheet and workbook */
+ var worksheet = utils.json_to_sheet(rows);
+ var workbook = utils.book_new();
+ utils.book_append_sheet(workbook, worksheet, "Dates");
+
+ /* fix headers */
+ utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
+
+ /* calculate column width */
+ var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
+ worksheet["!cols"] = [ { wch: max_width } ];
+
+ /* create an XLSX file and try to save to Presidents.xlsx */
+ writeFileXLSX(workbook, "Presidents.xlsx");
+ });
+});
+```
+
+3) Bundle the scripts:
+
+```bash
+npx browserify app.js > browserify.js
+```
+
+4) Spin up a local web server:
+
+```bash
+npx http-server
+```
+
+5) Create a small HTML page that loads the script. Save to `index.html`:
+
+```html title="index.html"
+
+
+
+
+
SheetJS Presidents Demo
+
+
+
+
+```
+
+6) Start a local HTTP server and go to `http://localhost:8080/`
+
+```bash
+npx http-server .
+```
+
+Click on "Click here to export" to generate a file.
diff --git a/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md b/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md
new file mode 100644
index 0000000..486c344
--- /dev/null
+++ b/docz/docs/03-demos/01-frontend/19-bundler/21-swcpack.md
@@ -0,0 +1,186 @@
+---
+title: Bundling Sheets with SWC
+sidebar_label: SWC spack
+pagination_prev: demos/index
+pagination_next: demos/grid/index
+sidebar_position: 21
+---
+
+import current from '/version.js';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
+
+SWC[^1] is a JS toolchain. SWC provides `spack` (formally called "swcpack") for
+bundling scripts.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo uses `spack` and SheetJS to export data. We'll explore how to bundle
+SheetJS in a site using `spack` and how to export data to spreadsheets.
+
+:::note
+
+This demo was last tested on 2023 October 20 against SWC 1.2.246
+
+:::
+
+## Integration Details
+
+[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
+installation with Yarn and other package managers.
+
+After installing the SheetJS module in a SWC `spack` project, `import`
+statements can load relevant parts of the library.
+
+Projects that import data will use methods such as `read`[^2] to parse workbooks
+and `sheet_to_json`[^3] to generate usable data from files. As `sheet_to_json`
+is part of the `utils` object, the required import is:
+
+```js
+import { read, utils } from 'xlsx';
+```
+
+Projects that export data will use methods such as `json_to_sheet`[^4] to
+generate worksheets and `writeFile`[^5] to export files. As `json_to_sheet` is
+part of the `utils` object, the required import is:
+
+```js
+import { utils, writeFile } from 'xlsx';
+```
+
+:::warning pass
+
+When this demo was tested against the latest version, `spack` crashed:
+
+```
+thread '' panicked at 'cannot access a scoped thread local variable without calling `set` first',
+```
+
+Until the bug is fixed, it is strongly recommended to use `@swc/core@1.2.246`.
+
+:::
+
+## Complete Example
+
+0) Initialize a new project:
+
+```bash
+mkdir sheetjs-spack
+cd sheetjs-spack
+npm init -y
+```
+
+1) Install the dependencies using a package manager:
+
+
+
+{`\
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
+
+
+
+{`\
+pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
+
+
+
+{`\
+yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} regenerator-runtime @swc/cli @swc/core@1.2.246
+
+
+
+
+:::note pass
+
+The `regenerator-runtime` dependency is used for transpiling `fetch` and is not
+required if the interface code does not use `fetch` or Promises.
+
+:::
+
+2) Save the following to `index.js`:
+
+```js title="index.js"
+import { utils, version, writeFileXLSX } from 'xlsx';
+
+document.getElementById("xport").addEventListener("click", async() => {
+/* fetch JSON data and parse */
+const url = "https://sheetjs.com/data/executive.json";
+const raw_data = await (await fetch(url)).json();
+
+/* filter for the Presidents */
+const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
+
+/* flatten objects */
+const rows = prez.map(row => ({
+ name: row.name.first + " " + row.name.last,
+ birthday: row.bio.birthday
+}));
+
+/* generate worksheet and workbook */
+const worksheet = utils.json_to_sheet(rows);
+const workbook = utils.book_new();
+utils.book_append_sheet(workbook, worksheet, "Dates");
+
+/* fix headers */
+utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
+
+/* calculate column width */
+const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
+worksheet["!cols"] = [ { wch: max_width } ];
+
+/* create an XLSX file and try to save to Presidents.xlsx */
+writeFileXLSX(workbook, "Presidents.xlsx");
+});
+```
+
+3) Create an `spack.config.js` config file:
+
+```js title="spack.config.js"
+module.exports = ({
+ entry: {
+ 'web': __dirname + '/index.js',
+ },
+ output: {
+ path: __dirname + '/lib'
+ },
+ module: {},
+});
+```
+
+4) Build for production:
+
+```bash
+npx spack
+```
+
+This command will create the script `lib/web.js`
+
+5) Create a small HTML page that loads the generated script:
+
+```html title="index.html"
+
+
+
+
+
SheetJS Presidents Demo
+
+
+
+
+```
+
+6) Start a local HTTP server, then go to `http://localhost:8080/`
+
+```bash
+npx http-server
+```
+
+Click on "Click here to export" to generate a file.
+
+[^1]: See ["Bundling Configuration"](https://swc.rs/docs/configuration/bundling) in the SWC documentation for more details.
+[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
+[^3]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
+[^4]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
+[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
\ No newline at end of file
diff --git a/docz/docs/03-demos/01-frontend/19-bundler/index.md b/docz/docs/03-demos/01-frontend/19-bundler/index.md
index d6e9d0c..b309cc3 100644
--- a/docz/docs/03-demos/01-frontend/19-bundler/index.md
+++ b/docz/docs/03-demos/01-frontend/19-bundler/index.md
@@ -35,84 +35,9 @@ The following tools are covered in separate pages:
);
})}
-## Browserify
-
-`browserify` is compatible with the library and should "just work" with the
-`require` form in a main page or in a web worker:
-
-```js
-var XLSX = require("xlsx");
-// ... use XLSX ...
-```
-
-[After installing the NodeJS module](/docs/getting-started/installation/nodejs),
-bundling is straightforward:
-
-```bash
-browserify app.js > browserify.js
-uglifyjs browserify.js > browserify.min.js
-```
-
-Web Worker scripts can be bundled using the same approach.
-
-Complete Example (click to show)
-
-:::note
-
-This demo was last tested on 2023 May 07 against Browserify `17.0.0`
-
-:::
-
-1) Install the tarball using a package manager:
-
-
-
-{`\
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
-
-
-{`\
-pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
-
-
-{`\
-yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
-
-
-
-2) Download the following files:
-
-- [`app.js`](pathname:///browserify/app.js)
-- [`index.html`](pathname:///browserify/index.html)
-- [`xlsxworker.js`](pathname:///browserify/xlsxworker.js)
-
-```bash
-curl -LO https://docs.sheetjs.com/browserify/app.js
-curl -LO https://docs.sheetjs.com/browserify/index.html
-curl -LO https://docs.sheetjs.com/browserify/xlsxworker.js
-```
-
-3) Bundle the scripts:
-
-```bash
-npx browserify app.js > browserify.js
-npx browserify xlsxworker.js > worker.js
-```
-
-4) Spin up a local web server:
-
-```bash
-npx http-server
-```
-
-5) Access the site `http://localhost:8080/` and use the file input element to
-select a spreadsheet.
-
-
+#### Browserify
+**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/browserify)**
## Bun
@@ -312,7 +237,7 @@ click the "Click to Export!" button to generate a file.
-## RequireJS
+#### RequireJS
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/requirejs)**
@@ -405,7 +330,6 @@ npx rollup index.js --plugin @rollup/plugin-node-resolve --file bundle.js --form