txiki.js is a small and powerful JavaScript runtime. It targets the latest ECMAScript spec and implements many web platform features.
A month or so has passed since the previous release, and after a good amount of commits, it’s time for a new release, say hi to txiki.js 26.5.0!
This release consisted of many many bugfixes to existing modules, mostly reported but what looks like AI tools. I also used Claude myself to review some sketchy code areas and make improvements. The result, for example, is a much more consistent internal API boundary. Rather than relying on a global symbol for accessing internals (which made access for internal modules simple) it now uses a dedicated module plus a check in the loader, so user code cannot import it.
Internals also saw some work. In the past I used symbols to hide internal properties or methods in user facing JS objects, a pattern I think I picked up from Node, but there is a better way with private class fields and methods, of course!
A particular change I’m very excited about is support for explicit resource management (aka using) which came through updating QuickJS-ng to version 0.15! I then went ahead and added Symbol.dispose / Symbol.asyncDispose where it made sense, so you can now write stuff like so:
...
{
using db = new Database(':memory:');
db.exec('CREATE TABLE t (v INTEGER)');
db.prepare('INSERT INTO t (v) VALUES (?)').run(42);
}
// 'db' is automatically closed at this point!
or
...
await (async () => {
await using f = await tjs.open(filePath, 'w');
await f.write(encoder.encode('hello'));
})();
// 'f' is automatically closed at this point!
Check the full changelog for all the details!