Skip to main content

Bun

Package tarballs are available on https://cdn.sheetjs.com.

https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz is the URL for version 0.20.3

Bun support is considered experimental.

Great open source software grows with user tests and reports. Any issues should be reported to the Bun project for further diagnosis.

Installation

Tarballs can be directly installed with bun install:

bun rm xlsx
bun install https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

Watch the repo or subscribe to the RSS feed to be notified when new versions are released!

Vendoring

For general stability, "vendoring" modules is the recommended approach:

  1. Remove any existing dependency on a project named xlsx:
bun rm xlsx
  1. Download the tarball (xlsx-0.20.3.tgz) for the desired version. The current version is available at https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

  1. Create a vendor subfolder at the root of your project and move the tarball to that folder. Add it to your project repository.

  2. Install the tarball:

bun install file:vendor/xlsx-0.20.3.tgz

The package will be installed and accessible as xlsx.

Usage

The package supports CommonJS require and ESM import module systems.

It is strongly recommended to use CommonJS in Bun.

CommonJS require

By default, the module supports require and it will automatically add support for encodings, streams and file system access:

const { readFile } = require("xlsx");
const wb = readFile("pres.numbers"); // works!

In the BunJS REPL, require incorrectly loads the ESM build.

ESM import

When importing the library using ESM import statements, the native NodeJS modules are not loaded. They must be added manually:

import * as XLSX from 'xlsx';

/* load 'fs' for readFile and writeFile support */
import * as fs from 'fs';
XLSX.set_fs(fs);

/* load 'stream' for stream support */
import { Readable } from 'stream';
XLSX.stream.set_readable(Readable);

/* load the codepage support library for extended support with older formats */
import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
XLSX.set_cptable(cpexcel);

Bundling

For server-side scripts, bun build can pre-optimize dependencies. The Bun builder requires a proper package.json that includes the SheetJS dependency.

Tested Deployments

This demo was last tested in the following deployments:

ArchitectureBunJSDate
darwin-x641.1.392024-12-17
darwin-arm1.1.102024-09-22
win11-x641.1.222024-08-11
win11-arm1.1.402024-12-19
linux-x641.1.402024-12-19
linux-arm1.1.402024-12-19

BunJS on Windows on ARM uses the X64 compatibility layer.

  1. Create a new project:
mkdir sheetjs-bun-dle
cd sheetjs-bun-dle
echo "{}" > package.json
PowerShell Encoding Errors

The PowerShell file redirect will use the UTF-16 LE encoding. Bun does not support the encoding and will fail to install the package:

bun add v1.1.22-canary.96 (df33f2b2)
1 | ��{}

^
error: Unexpected ��

The file must be resaved in UTF8 (without BOM) or ASCII.

  1. Open package.json in VSCodium.

The current encoding is displayed in the lower-right corner:

VSCodium status bar

  1. Click the displayed encoding.

  2. In the "Select Action" popup, select "Save with Encoding"

  3. In the new list, select UTF-8 utf8:

VSCodium encoding

VSCodium will automatically re-save the file.

  1. Install the SheetJS package tarball:
bun install https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

In some test runs, the command failed with a module resolution error:

error: https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz failed to resolve

The workaround is to prepend xlsx@ to the URL:

bun install xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
  1. Save the following script to SheetJSBun.js:
SheetJSBun.js
import * as XLSX from 'xlsx';
import * as fs from 'fs';
XLSX.set_fs(fs);

/* fetch JSON data and parse */
const url = "https://docs.sheetjs.com/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"));

/* sort by first presidential term */
prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start);
prez.sort((l,r) => l.start.localeCompare(r.start));

/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));

/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");

/* fix headers */
XLSX.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 */
XLSX.writeFile(workbook, "Presidents.xlsx");
  1. Bundle the script with bun build:
bun build --target=bun SheetJSBun.js --outfile=app.js

This procedure will generate app.js.

  1. Remove the module artifacts and original script:
rm package.json bun.lockb SheetJSBun.js
rm -rf ./node_modules

PowerShell does not support rm -rf. Instead, each file must be removed:

Windows Powershell commands
rm package.json
rm bun.lockb
rm SheetJSBun.js
rm .\\node_modules -r -fo

At this point, app.js will be the only file in the project folder.

  1. Run the script:
bun app.js

If the script succeeded, the file Presidents.xlsx will be created. That file can be opened in a spreadsheet editor. If a spreadsheet editor is unavailable, the contents can be displayed using the xlsx-cli tool:

bunx xlsx-cli Presidents.xlsx