{"id":29419883,"url":"https://github.com/bytecodealliance/starlingmonkey","last_synced_at":"2025-07-12T01:13:16.531Z","repository":{"id":225839886,"uuid":"700318269","full_name":"bytecodealliance/StarlingMonkey","owner":"bytecodealliance","description":"The StarlingMonkey JS runtime","archived":false,"fork":false,"pushed_at":"2025-07-11T21:27:12.000Z","size":2373,"stargazers_count":194,"open_issues_count":68,"forks_count":36,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-07-12T00:44:55.782Z","etag":null,"topics":["component-model","javascript","js","runtime","wasi","wasm","webassembly","webassembly-components"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bytecodealliance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-04T11:20:34.000Z","updated_at":"2025-07-11T21:27:17.000Z","dependencies_parsed_at":"2024-03-25T20:30:28.652Z","dependency_job_id":"392377f4-6201-4bd3-8bda-da6b5f846674","html_url":"https://github.com/bytecodealliance/StarlingMonkey","commit_stats":null,"previous_names":["fermyon/starlingmonkey","bytecodealliance/starlingmonkey"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bytecodealliance/StarlingMonkey","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FStarlingMonkey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FStarlingMonkey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FStarlingMonkey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FStarlingMonkey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bytecodealliance","download_url":"https://codeload.github.com/bytecodealliance/StarlingMonkey/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FStarlingMonkey/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264922908,"owners_count":23683705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component-model","javascript","js","runtime","wasi","wasm","webassembly","webassembly-components"],"created_at":"2025-07-12T01:13:14.052Z","updated_at":"2025-07-12T01:13:16.520Z","avatar_url":"https://github.com/bytecodealliance.png","language":"C","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e\u003ccode\u003eStarlingMonkey\u003c/code\u003e\u003c/h1\u003e\n\n  \u003cp\u003e\n    \u003cstrong\u003eA SpiderMonkey-based JS runtime on WebAssembly\u003c/strong\u003e\n  \u003c/p\u003e\n\n  \u003cstrong\u003eA \u003ca href=\"https://bytecodealliance.org/\"\u003eBytecode Alliance\u003c/a\u003e project\u003c/strong\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/bytecodealliance/StarlingMonkey/actions?query=workflow%3ACI\"\u003e\u003cimg src=\"https://github.com/bytecodealliance/StarlingMonkey/workflows/CI/badge.svg\" alt=\"build status\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://bytecodealliance.zulipchat.com/#narrow/stream/459697-StarlingMonkey\"\u003e\u003cimg src=\"https://img.shields.io/badge/zulip-join_chat-brightgreen.svg\" alt=\"zulip chat\" /\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\n  \u003ch3\u003e\n    \u003ca href=\"#building-and-running\"\u003eBuilding\u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"ADOPTERS.md\"\u003eAdopters\u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"https://bytecodealliance.zulipchat.com/#narrow/stream/459697-StarlingMonkey\"\u003eChat\u003c/a\u003e\n  \u003c/h3\u003e\n\u003c/div\u003e\n\nStarlingMonkey is a [SpiderMonkey](https://spidermonkey.dev/) based JS runtime optimized for use in [WebAssembly Components](https://component-model.bytecodealliance.org/).\nStarlingMonkey's core builtins target WASI 0.2.0 to support a Component Model based event loop and standards-compliant implementations of key web builtins, including the fetch API, WHATWG Streams, text encoding, and others. To support tailoring for specific use cases, it's designed to be highly modular, and can be readily extended with custom builtins and host APIs.\n\nStarlingMonkey is used in production for Fastly's JS Compute platform, and Fermyon's Spin JS SDK. See the [ADOPTERS](ADOPTERS.md) file for more details.\n\n## Building and Running\n\n### Requirements\n\nThe runtime's build is managed by [cmake](https://cmake.org/), which also takes care of downloading the build dependencies.\nTo properly manage the Rust toolchain, the build script expects [rustup](https://rustup.rs/) to be installed in the system.\n\n### Usage\n\nWith sufficiently new versions of `cmake` and `rustup` installed, the build process is as follows:\n\n1. Clone the repo\n\n```bash\ngit clone https://github.com/bytecodealliance/StarlingMonkey\ncd StarlingMonkey\n```\n\n2. Run the configuration script\n\nFor a release configuration, run\n```bash\ncmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release\n```\n\nFor a debug configuration, run\n```bash\ncmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug\n```\n\n3. Build the runtime\n\nBuilding the runtime is done in two phases: first, cmake is used to build a raw version as a WebAssembly core module. Then, that module is turned into a [WebAssembly Component](https://component-model.bytecodealliance.org/) using the `componentize.sh` script.\n\nThe following command will build the `starling-raw.wasm` runtime module in the `cmake-build-release` directory:\n```bash\n# Use cmake-build-debug for the debug build\n# Change the value for `--parallel` to match the number of CPU cores in your system\ncmake --build cmake-build-release --parallel 8\n```\n\nThen, the `starling-raw.wasm` module can be turned into a component with the following command:\n\n```bash\ncd cmake-build-release\n./componentize.sh -o starling.wasm\n```\n\nThe resulting runtime can be used to load and evaluate JS code dynamically:\n\n```bash\nwasmtime -S http starling.wasm -e \"console.log('hello world')\"\n# or, to load a file:\nwasmtime -S http --dir . starling.wasm index.js\n```\n\nAlternatively, a JS file can be provided during componentization:\n\n```bash\ncd cmake-build-release\n./componentize.sh index.js -o starling.wasm\n```\n\nThis way, the JS file will be loaded during componentization, and the top-level code will be executed, and can e.g. register a handler for the `fetch` event to serve HTTP requests.\n\n4. Testing the build \n\nAfter completing the build (a debug build in this case), the integration test runner can be built:\n\n```bash\ncmake --build cmake-build-debug --target integration-test-server\n```\n\nThen tests can be run with `ctest` directly via:\n\n```bash\nctest --test-dir cmake-build-debug -j8 --output-on-failure\n```\n\nAlternatively, the integration test server can be directly run with `wasmtime serve` via:\n\n```bash\nwasmtime serve -S common cmake-build-debug/test-server.wasm\n```\n\nThen visit http://0.0.0.0:8080/timers, or any test name and filter of the form `[testName]/[filter]`\n\n5. Using the runtime with other JS applications\n\nThe build directory contains a shell script `componentize.sh` that can be used to create components from JS applications. `componentize.sh` takes a single argument, the path to the JS application, and creates a component with a name of the form `[input-file-name].wasm` in the current working directory.\n\nFor example, the following command is equivalent to the `cmake` invocation from step 5, and will create the component `cmake-build-release/smoke.wasm`:\n\n```bash\ncd cmake-build-release\n./componentize.sh ../tests/smoke.js\n```\n\n### Web Platform Tests\n\nTo run the [Web Platform Tests](https://web-platform-tests.org/) suite, the WPT runner requires `Node.js` above v18.0 to be installed, and during build configuration the option `ENABLE_WPT:BOOL=ON` must be set.\n\n```bash\ncmake -S . -B cmake-build-debug -DENABLE_WPT:BOOL=ON -DCMAKE_BUILD_TYPE=Debug\ncmake --build cmake-build-debug --parallel 8 --target wpt-runtime\ncat deps/wpt-hosts | sudo tee -a /etc/hosts # Required to resolve test server hostnames\ncd cmake-build-debug\nctest -R wpt --verbose # Note: some of the tests run fairly slowly in debug builds, so be patient\n```\n\nThe Web Platform Tests checkout can also be customized by setting the `WPT_ROOT=[path to your WPT checkout]` environment variable to the cmake command.\n\nWPT tests can be filtered with the `WPT_FILTER=string` variable, for example:\n\n```bash\nWPT_FILTER=fetch ctest -R wpt -v\n```\n\nCustom flags can also be passed to the test runner via `WPT_FLAGS=\"...\"`, for example to update expectations use:\n\n```bash\nWPT_FLAGS=\"--update-expectations\" ctest -R wpt -v\n```\n\n### Configuring available builtins\n\nStarlingMonkey supports enabling/disabling bundled builtins using CMake options. You can get a full list of bundled builtins by running the following shell command:\n\n```shell\ncmake -P [PATH_TO_STARLING_MONKEY]/cmake/builtins.cmake\n```\n\nNote that it's required to include builtins defining all exports defined by the used host API. Using the default WASI 0.2.0 host API, that means including the `fetch_event` builtin.\n\n### Running project-specific commands using `just`\n\nThe justfile provides a streamlined interface for executing common project-specific tasks. To install just, you can use the command `cargo install just` or `cargo binstall just`. Alternatively, refer to the official [installation instructions](https://github.com/casey/just?tab=readme-ov-file#installation) for your specific system.\n\nOnce installed, navigate to the project directory and run `just` commands as needed. For instance, the following commands will configure a default `cmake-build-debug` directory and build the project.\n\n``` shell\njust build\n```\n\nTo load a JS script during componentization and serve its output using `Wasmtime`, run:\n``` shell\njust serve \u003cfilename\u003e.js\n```\n\nTo build and run integration tests run:\n\n``` shell\njust test\n```\n\nTo build and run Web Platform Tests run:\n\n``` shell\njust wpt-setup # prepare WPT hosts\njust wpt-test # run all tests\njust wpt-test console/console-log-symbol.any.js # run specific test\n```\n\nTo view a complete list of available recipes, run:\n\n``` shell\njust --list\n\n```\n\n\u003e [!NOTE]\n\u003e By default, the CMake configuration step is skipped if the build directory already exists. However, this can sometimes cause issues if the existing build directory was configured for a different target. For instance:\n\u003e - Running `just build` creates a build directory for the default target,\n\u003e - Running `just wpt-build` afterward may fail because the WPT target hasn’t been configured in the existing build directory.\n\u003e\n\u003e To resolve this, you can force cmake to reconfigure the build directory by adding the `reconfigure=true` parameter. For example:\n\u003e\n\u003e ``` shell\n\u003e just reconfigure=true wpt-build\n\u003e ```\n\n#### Customizing build\nThe default build mode is debug, which automatically configures the build directory to `cmake-build-debug`. You can switch to a different build mode, such as release, by specifying the mode parameter. For example:\n\n``` shell\njust mode=release build\n```\n\nThis command will set the build mode to release, and the build directory will automatically change to `cmake-build-release`.\n\nIf you want to override the default build directory, you can use the `builddir` parameter. \n\n``` shell\njust builddir=mybuilddir mode=release build\n```\n\nThis command configures CMake to use `mybuilddir` as the build directory and sets the build mode to `release`.\n\n#### Starting the WPT Server\nYou can also start a Web Platform Tests (WPT) server with:\n\n``` shell\njust wpt-server\n```\n\nAfter starting the server, individual tests can be run by sending a request with the test name to the server instance. For example:\n\n``` shell\ncurl http://127.0.0.1:7676/console/console-log-symbol.any.js\n\n```\n\n### Using StarlingMonkey as a CMake sub-project\n\nStarlingMonkey can be used as a subproject in a larger CMake project.\n\nThe importing project must at a minimum contain the following line in its `CMakeLists.txt`:\n\n```cmake\ninclude(\"${PATH_TO_STARLING_MONKEY}/cmake/add_as_subproject.cmake\")\n```\n\nWith that line added (and `${PATH_TO_STARLING_MONKEY}` replaced with the actual path to StarlingMonkey), the importing project will have all the build targets of StarlingMonkey available to it.\n\nNote that building the `starling-raw.wasm` target itself will result in the linked `starling-raw.wasm` file being created in the `starling-raw.wasm` sub-directory of the importing project's build directory.\n\nTo make use of importing StarlingMonkey in this way, you'll probably want to add additional builtins, or provide your own implementation of the host interface.\n\n### Adding custom builtins\n\nAdding builtins is as simple as calling `add_builtin` in the importing project's `CMakeLists.txt`. Say you want to add a builtin defined in the file `my-builtin.cpp`, like so:\n\n```cpp\n// The extension API is automatically on the include path for builtins.\n#include \"extension-api.h\"\n\n// The namespace name must match the name passed to `add_builtin` in the CMakeLists.txt\nnamespace my_project::my_builtin {\n\n    bool install(api::Engine* engine) {\n        printf(\"installing my-builtin\\n\");\n        return true;\n    }\n\n} // namespace my_builtin\n```\n\nThis file can now be included in the runtime's builtins like so:\n```cmake\nadd_builtin(my_project::my_builtin SRC my-builtin.cpp)\n```\n\nIf your builtin requires multiple `.cpp` files, you can pass all of them to `add_builtin` as values for the `SRC` argument.\n\n\n### Providing a custom host API implementation\n\nThe [host-apis](host-apis) directory can contain implementations of the host API for different \nversions of WASI—or in theory any other host interface. Those can be selected by setting the \n`HOST_API` environment variable to the \nname of one of the directories. Currently, only an implementation in terms of [wasi-0.2.0]\n(host-apis/wasi-0.2.0) is provided, and used by default.\n\nTo provide a custom host API implementation, you can set `HOST_API` to the (absolute) path of a directory containing that implementation.\n\n## Developing Changes to SpiderMonkey\n\nStarlingMonkey uses SpiderMonkey as its underlying JS engine, and by default,\ndownloads build artifacts from [a wrapper\nrepository](https://github.com/bytecodealliance/spidermonkey-wasi-embedding)\naround [our local SpiderMonkey\ntree](https://github.com/bytecodealliance/gecko-dev). That wrapper repository\ncontains a SpiderMonkey commit-hash in a file, and its CI jobs build the\nartifacts that StarlingMonkey downloads during its build.\n\nThis flow is optimized for ease of development of StarlingMonkey, and avoiding\nthe need to build SpiderMonkey locally, which requires some additional tools\nand is resource-intensive. However, sometimes it is necessary or desirable to\nmake modifications to SpiderMonkey directly, whether to make fixes or optimize\nperformance.\n\nIn order to do so, first clone the above two repositories, with `gecko-dev`\n(SpiderMonkey itself) as a subdirectory to `spidermonkey-wasi-embedding`:\n\n```shell\ngit clone https://github.com/bytecodealliance/spidermonkey-wasi-embedding\ncd spidermonkey-wasi-embedding/\ngit clone https://github.com/bytecodealliance/gecko-dev\n```\n\nand switch to the commit that we are currently using:\n\n```shell\ngit checkout `cat ../gecko-revision`\n# now edit the source\n```\n\nThen make changes as necessary, eventually rebuilding from the\n`spidermonkey-wasi-embedding` root:\n\n```shell\ncd ../ # back to spidermonkey-wasi-embedding\n./rebuild.sh release\n```\n\nThis will produce a `release/` directory with artifacts of the same form\nnormally downloaded by StarlingMonkey. So, finally, from within StarlingMonkey,\nset an environment variable `SPIDERMONKEY_BINARIES`:\n\n```shell\nexport SPIDERMONKEY_BINARIES=/path/to/spidermonkey-wasi-embedding/release\ncmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release\ncmake --build cmake-build-release --parallel 8\n```\n\nand use/test as above.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytecodealliance%2Fstarlingmonkey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbytecodealliance%2Fstarlingmonkey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytecodealliance%2Fstarlingmonkey/lists"}