My penguin avatar

Kiesel Devlog #5: Progress powered by the Shadow web engine

Published on 2023-10-29.

Shadow Web Engine

This is a project my friend CanadaHonk started working on earlier this week — it's a simple web engine written in JS! More about that here.

For JS execution within Shadow they had the idea to use existing Wasm builds of JS engines instead of relying on the host browser, and to my surprise they picked SpiderMonkey and Kiesel for the initial proof of concept, switchable at runtime!

This resulted in me spending an evening fixing bugs and looking into missing features they asked about, including a few of the below. Of course this isn't anywhere near being a serious web engine just yet, but it's really cool to have Kiesel featured in one regardless :^)


I decided to implement classes even before Shadow happened just to make some progress on language features again — they definitely win in the category weirdest codegen across the entire engine, but other than that I'm happy with how that turned out :^)

Supported features include class expressions/declarations, methods (of course), constructor(), static and instance class fields, static blocks, as well as super calls and properties (no private properties yet). You can see some of those in action here.

I also added support for parsing async, generator, and async generator method definitions in classes or object literals, but they're just as non-functional at runtime as their function declaration counterparts.

Sharing a screenshot of an entire class being written on a single line with no syntax highlighting prompted CxByte (whom you might know from the SerenityOS project! 👋) to start working on a LibLine Zig port to improve the REPL, more on that soon!

The Beginning of Modules

Don't get too excited just yet, there's not much working here! For now I implemented the distinction between scripts and modules, a flag for the CLI, some basic parsing of import declaration, and the import.meta object.

I had very little to do with the module support in LibJS, so this is new territory for me :^)

Other Language Features

I implemented a couple more small language features:

Resizable Array Buffers

These existed as a proposal for a while and finally got merged into the main spec a couple of weeks ago, so I promptly implemented the new functionality :^)

Reporting of Unhandled Promise Rejections

A small DX improvement; the CLI will now report these two cases at the end of script evaluation:

Under the hood this uses the same mechanism as the unhandledrejection and rejectionhandled events on the web.

Improved CI Builds

I continue to publish pre-built binaries on, with a few recent changes:


Expand to see the full list of newly implemented builtins 📝


test262 is still steadily going up, now at 35.3%. I check the graph every morning, seeing the small bump from last night's run is very motivating 📈

Collaborating with CanadaHonk so they can use Kiesel in the Shadow web engine has been really fun, and I made lots of progress thanks to that! I'm not sure how quickly modules will take shape from here on, but they create some exciting new abilities such as importable native modules:

Loading posts...