docs.sheetjs.com/docz/docs/03-demos/20-cli/21-txiki.md
2026-01-22 01:59:11 -05:00

7.2 KiB

title sidebar_label pagination_prev pagination_next sidebar_custom_props
TxikiJS Standalone Apps txiki.js demos/desktop/index demos/data/index
summary
Compiled apps powered by QuickJS and txiki.js

import current from '/version.js'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock';

txiki.js is a small runtime powered by QuickJS.

SheetJS is a JavaScript library for reading and writing data from spreadsheets.

This demo uses txiki.js and SheetJS to create a standalone CLI tool for parsing spreadsheets and generating CSV rows.

:::caution TxikiJS support is considered experimental.

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

:::

Integration Details

The SheetJS Standalone scripts can be evaluated and consumed in TxikiJS.

The platform provides APIs for filesystem operations that differ from NodeJS:

  • tjs.readFile reads raw data from a specified filename and returns a Promise that resolves to a Uint8Array
  • tjs.args is an array of arguments. In the compiled program, the first value will be the program name and the second value will be the first argument.

The SheetJS filesystem methods (readFile and writeFile) do not recognize the txiki.js APIs. Fortunately, read and write directly work with Uint8Array data.

The following example reads and parses pres.xlsx in the current directory:

/* read data from pres.xlsx into a Uint8Array */
const data = await tjs.readFile("pres.xlsx");

/* parse data and generate a SheetJS workbook object */
const wb = XLSX.read(data);

Script Requirements

The compiler does not bundle scripts automatically. Scripts that exclusively use web APIs, SheetJS API methods, and tjs API methods can be bundled and compiled.

esbuild is the recommended bundler.

For example, the following script accepts one command line argument, parses the specified file using tjs.readFile and the SheetJS read method1, generates CSV text from the first sheet using sheet_to_csv2, and prints the result:

const XLSX = require("./xlsx.full.min");

/* tjs.args[1] is the first argument to the script */
const filename = tjs.args[1];

/* read and parse file */
const data = await tjs.readFile(filename);
const wb = XLSX.read(data);

/* generate CSV of first sheet */
const ws = wb.Sheets[wb.SheetNames[0]];
const csv = XLSX.utils.sheet_to_csv(ws);

/* print to terminal */
console.log(csv);

Complete Example

:::note Tested Deployments

This demo was tested in the following deployments:

Architecture Version Commit Date
darwin-x64 24.12.0 793dd9d 2026-01-21
darwin-arm 24.12.0 793dd9d 2026-01-18
win11-x64 24.12.0 2025-04-19
win11-arm 24.12.0 2025-04-19
linux-x64 24.12.0 65e5595 2026-01-18
linux-arm 24.12.0 65e5595 2026-01-21

:::

:::caution pass

TxikiJS on Windows on ARM uses the X64 compatibility layer. It does not generate a native ARM64 binary!

:::

  1. Create a new project folder and download txiki.js3:
mkdir sheetjs-txiki
cd sheetjs-txiki
curl -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-macos.zip
unzip txiki-macos.zip
mv txiki-macos/tjs .
chmod +x tjs
mkdir sheetjs-txiki
cd sheetjs-txiki
git clone --recursive https://github.com/saghul/txiki.js --shallow-submodules
cd txiki.js
make
cp build/tjs ../
cd ..

:::caution pass

In some linux-x64 test runs, the make step failed:

make[5]: *** No rule to make target 'all-configured'.  Stop.

After re-running make, the [ 0%] line identifies the root cause:

// highlight-next-line
[  0%] Performing build step for 'libffi'
[  1%] Built target sqlite3
[  2%] Built target ffi-test
...
[ 61%] Built target sqlite-test
MAKE x86_64-pc-linux-gnu : 0 * all-configured
// highlight-next-line
make[5]: *** No rule to make target 'all-configured'.  Stop.

If the root cause is libffi, it is possible to use the system libffi. The following commands should be run in the txiki.js folder:

rm -rf build
cmake -B build -DCMAKE_BUILD_TYPE=Release -DUSE_EXTERNAL_FFI=ON
cmake --build build -j 8
cp build/tjs ../

:::

mkdir sheetjs-txiki
cd sheetjs-txiki
curl.exe -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-windows-x86_64.zip
tar xf txiki-windows-x86_64.zip
mv txiki-windows-x86_64\* .
  1. Download the test file https://docs.sheetjs.com/pres.numbers:
curl -LO https://docs.sheetjs.com/pres.numbers

:::note pass

In PowerShell, the command may fail with a parameter error:

Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.

curl.exe must be invoked directly:

curl.exe -LO https://docs.sheetjs.com/pres.numbers

:::

  1. Save the contents of the sheet2csv.js code block to sheet2csv.js in the project folder.
curl -LO https://docs.sheetjs.com/txikijs/sheet2csv.js

:::note pass

In PowerShell, the command may fail with a parameter error:

Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.

curl.exe must be invoked directly:

curl.exe -LO https://docs.sheetjs.com/txikijs/sheet2csv.js

:::

  1. Download the SheetJS Standalone script and move to the project directory:
  • xlsx.full.min.js

{\ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js}

:::note pass

In PowerShell, the command may fail with a parameter error:

Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.

curl.exe must be invoked directly:

{\ curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js}

:::

  1. Bundle the script:
npx -y esbuild sheet2csv.js --bundle --outfile=bundle.js --platform=neutral
  1. Compile and run sheet2csv:
./tjs compile bundle.js sheet2csv
./sheet2csv pres.numbers

The program should display the same CSV contents as the script:

Name,Index
Bill Clinton,42
GeorgeW Bush,43
Barack Obama,44
Donald Trump,45
Joseph Biden,46

  1. See read in "Reading Files" ↩︎

  2. See sheet_to_csv in "CSV and Text" ↩︎

  3. When this demo was last tested, the ZIP archive for version 24.12.0 was downloaded and extracted. ↩︎