Skip to content

txiki.js ​

the runtime your backend runs on

The backend runs on txiki.js, a small JavaScript runtime: the QuickJS engine, libuv for I/O, with SQLite and WebAssembly built in. tinyjs ships txiki.js 26.6.0. Everything txiki.js offers is available to your backend — this page is a map of it, with links to txiki.js's own reference for the details.

It isn't Node.js: there's no require, no process, no Buffer and no node:* modules. Use the tjs global, the tjs:* modules and standard Web APIs instead. npm packages work in a TypeScript backend (it's bundled with esbuild) as long as they don't need Node's built-ins.

The page has none of this — it runs in the system webview, with no tjs. Expose what it needs through api functions.

the tjs global ​

areacallsreference
filesreadFile, writeFile, open, stat, lstat, readDir, makeDir, makeTempDir, makeTempFile, remove, rename, copyFile, symlink, readLink, realPath, chmod, chown, utime, statFs, watchfilesystem
processesspawn, exec, kill, exit, pid, ppid, addSignalListenerprocess
networkconnect, listen, lookup (DNS)networking
HTTP serverserveHTTP server
systemargs, env, cwd, chdir, homeDir, tmpDir, hostName, exePath, system, versionsystem
console & I/Ostdin, stdout, stderr, createConsoleutilities
engineengine — versions, GC, featuresengine
modulessetImportMapmodules
js
const text = new TextDecoder().decode(await tjs.readFile(path));
await tjs.writeFile(out, new TextEncoder().encode(text.toUpperCase()));

const p = tjs.spawn(['git', 'status', '--short'], { stdout: 'pipe' });
let output = '';
for await (const chunk of p.stdout) output += new TextDecoder().decode(chunk);
await p.wait();

On Windows, use app.spawnHidden() rather than tjs.spawn() for console programs, so each one doesn't flash a terminal window.

tjs: modules ​

moduleforreference
tjs:sqlitea SQLite database — see sqlitetjs:sqlite
tjs:pathjoining and splitting pathstjs:path
tjs:hashingMD5, SHA-1, SHA-256 and other digeststjs:hashing
tjs:uuidUUIDstjs:uuid
tjs:fficalling C libraries directlytjs:ffi
tjs:wasirunning WASI WebAssembly modulestjs:wasi
tjs:posix-socketraw socketstjs:posix-socket
tjs:ipaddrparsing IP addressestjs:ipaddr
tjs:readline, tjs:getoptsterminal input and command-line options, for command-line toolsreadline, getopts
tjs:assert, tjs:utilsassertions; format and inspectassert, utils
js
import path from 'tjs:path';
import { createHash } from 'tjs:hashing';

const file = path.join((await app.paths()).data, 'notes.json');
const digest = createHash('sha256').update(text).digest();

Web APIs ​

The backend also has the standard Web APIs txiki.js implements, including fetch, WebSocket, Worker, crypto (with crypto.subtle and randomUUID), TextEncoder/TextDecoder, URL, Blob, FormData, AbortController, CompressionStream, structuredClone, performance and localStorage. See txiki.js's Web Platform APIs for the full list.

For an app's settings, prefer app.store to localStorage: it's the same store the page sees, saved in the app's data folder.

types ​

Every project gets txiki.js's own type definitions as types/tjs.d.ts (backend/tjs.d.ts in the Vite templates), so editors complete and check tjs.* calls and tjs:* imports — no npm needed. They match the txiki.js version tinyjs ships, and tinyjs update-project brings them up to date after you update tinyjs.

They're for the backend only: the Vite templates' src/ is the page, which has no tjs, so it doesn't get them.

versions ​

txiki.js's website documents its latest release, which can be newer than the version tinyjs ships. If something there doesn't exist in your backend, check tjs.version — or tjs.engine.versions for QuickJS, libuv and SQLite. A tinyjs release names the txiki.js version it moves to in the changelog.

Sharp edges worth knowing — async file calls next to sync SQLite, stdout: 'ignore' vs 'null' — are on gotchas.