Repository navigation
Build from Source
English · 中文
Most users never need this: pip install ruyijs already contains the runtime on Windows x64, macOS arm64 and Linux x86_64. Build from source when you change the C++ under src/. The authoritative build notes are tools/README.md (Windows, in Chinese), docs/macos.md (macOS) and docs/linux.md (Linux).
-
JavaScript engine: the engine inside
js.exeis Firefox's official SpiderMonkey, from the official Firefox source (tagFIREFOX_159_0_RELEASE).tools/build.pylinks the SpiderMonkey objects Firefox produces with the ruyiJS browser environment undersrc/intojs.exe. -
Canvas 2D: drawn by Firefox's own Skia — the
gfx/skiaobjects of a Firefox browser build. -
Network: Firefox's official Necko stack (the Firefox 159 HTTP/1.1, HTTP/3 and brotli native components). It ships with the runtime package under
vendor/necko-derived. -
Third-party native libraries:
vendor/compression-native(zlib-rs, brotli),vendor/image-native(dav1d, libavif, libyuv, qcms) andvendor/urlpattern-native, all taken from the official Firefox source tree. Each directory keeps its original license, andmanifest.jsonrecords every file's SHA-256.
Both the engine and Necko can be compiled from the official Firefox source.
-
pip install ruyijs— the wheel bundles the same runtime. - Or download
ruyijs-runtime-<version>-win-amd64.zipfrom a GitHub release (dist/js.exe, runtime libraries, Necko). Unzip it and setRUYIJS_SHELL=<unzip-dir>\dist\js.exe, or place it at the repository root (givingdist/js.exeandvendor/necko-derived);python/ruyijsfinds it automatically.
Since 0.3.0 the repository references the official Firefox source as the firefox/ submodule (mozilla-firefox/firefox at FIREFOX_159_0_RELEASE), and GitHub Actions builds every PyPI wheel from it (.github/workflows/wheels.yml). The scripts those workflows run are the shortest way to a local build:
git clone --recurse-submodules https://github.com/cutetailbud/ff-ruyijs
cd ff-ruyijsWindows x64 (in a MozillaBuild shell) and macOS arm64 (with Python 3.12 first on PATH):
bash ci/firefox/build.sh js # SpiderMonkey -> obj/js
bash ci/firefox/build.sh browser # only Skia, NSS/NSPR and mozglue -> obj/firefox-parts
bash ci/firefox/build.sh toolchain # the clang tools/build.py links with
python tools/build.py --donor-obj obj/js --toolchain-bin "$HOME/.mozbuild/clang/bin" --firefox-gfx-obj obj/firefox-partsWindows then assembles the runtime archive (python ci/package/runtime.py) and builds the wheel with RUYIJS_BUILD_RUNTIME_ARCHIVE pointing at it. macOS also links libnecko_core.dylib (tools/build.py --necko-core-only --firefox-gfx-obj obj/firefox-parts) and libnecko_quic.dylib (tools/build_necko_quic.py library) before pip wheel .. Every step, with its environment, is in build-windows.yml and build-macos.yml.
Linux x86_64 (Ubuntu 24.04): run ci/linux/build.sh deps, donor, shell, necko, wheel and test in that order; see docs/linux.md.
The manual steps below build the same parts from a full Firefox tree. They also give you the firefox.exe that pixel comparisons use as the reference, and the xpcshell that proxies need on macOS.
js.exe is linked from two official Firefox build outputs plus this repository's src/:
-
SpiderMonkey standalone (
--enable-project=js): every object file of the JS engine; -
Firefox browser build: its
gfx/skiaobject files, so Canvas 2D is drawn by Firefox's own Skia. Thefirefox.exeit produces is also the reference for pixel comparisons.
Both must come from the same Firefox version (currently 159).
git clone https://github.com/mozilla-firefox/firefox
cd firefox
git tag --list "FIREFOX_159_0*_RELEASE" # list the available 159 release tags
git checkout FIREFOX_159_0_RELEASEThe official repository is https://github.com/mozilla-firefox/firefox (Mozilla's official Git mirror; browse the source at https://searchfox.org/mozilla-central/).
Run ./mach bootstrap. It installs Firefox's toolchain — clang-cl, lld-link, Rust and the VS/Windows SDK — under %USERPROFILE%\.mozbuild.
mozconfig-js:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-js-standalone
ac_add_options --enable-project=js
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --disable-tests
ac_add_options --enable-rust-simd
ac_add_options --target=x86_64-pc-windows-msvc
$env:MOZCONFIG = "$PWD\mozconfig-js"
./mach buildSame release configuration as the official build. mozconfig-browser:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-release
export MOZILLA_OFFICIAL=1
export MOZ_LTO=cross
ac_add_options --target=x86_64-pc-windows-msvc
ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --enable-rust-simd
ac_add_options --enable-release
ac_add_options --as-milestone=release
ac_add_options --enable-update-channel=release
$env:MOZCONFIG = "$PWD\mozconfig-browser"
./mach buildobj-release\gfx\skia\ should then hold about 80 .obj files; obj-release\dist\bin\firefox.exe is the reference browser.
From the ruyiJS repository root:
$env:RUYIJS_DONOR_OBJ = "<firefox>\obj-js-standalone"
$env:RUYIJS_FIREFOX_GFX_OBJ = "<firefox>\obj-release"
python -B tools/build.py `
--toolchain-bin "$env:USERPROFILE\.mozbuild\clang\bin" `
--vs-root "$env:USERPROFILE\.mozbuild\vs"- The
gfx/skia/*.objfiles are archived asfirefox_skia.liband linked intojs.exe(tools/skia_native.py). - Firefox 159 builds jsrust with LTO and no longer exports the Rust std, so
tools/rust_runtime.pyuses the donor's rustc to add a static library containing only std and the allocator. - The output is
dist/js.exe. A build record (input hashes, commands, tool versions) is written toartifacts/build-runtime.json. Running the build again after changing onlysrc/is incremental.
The runtime also needs the runtime libraries in dist/ and vendor/necko-derived. The simplest way: unzip the runtime package from a release, then overwrite its dist/js.exe with the one you just built.
Every local path is passed as an argument or an environment variable:
| Argument | Environment variable | Description |
|---|---|---|
--donor-obj |
RUYIJS_DONOR_OBJ |
obj directory of the SpiderMonkey standalone build (required) |
--firefox-gfx-obj |
RUYIJS_FIREFOX_GFX_OBJ |
obj directory of the Firefox 159 browser build, providing the gfx/skia objects for Canvas (required) |
--toolchain-bin |
LLVM bin directory (clang-cl, lld-link) |
|
--vs-root |
VS directory containing VC and the Windows Kits | |
--runtime-dll-dir |
the matching MSVC CRT redistributable | |
--firefox-font-prefs |
RUYIJS_FIREFOX_FONT_PREFS |
optional, see below |
--firefox-bindings |
RUYIJS_FIREFOX_BINDINGS |
optional, see below |
Other options: --prepare-only only prepares the inputs; --no-incremental forces a full rebuild; --jobs N sets the number of compiler processes.
--firefox-font-prefs (dist/bin/greprefs.js) and --firefox-bindings (dom/bindings) come from a full Firefox browser build. Without them, the headers already generated from Firefox 159 in tools/generated/ (firefox_font_prefs.h, firefox_binding_order.h) are used.
This is the maintainer path for the macOS shell; docs/macos.md has the full steps, the verified network paths and the comparison with Windows. In short:
-
Layout. SpiderMonkey and Necko/NSS come from one official Firefox tree that lives outside this repository and is never committed. A maintainer checkout is two sibling directories:
firefox/ official Firefox source, not part of ruyijs obj-js-standalone/ SpiderMonkey standalone obj-necko/ browser build that produces xpcshell ff-ruyijs/ this repository -
Donor builds. Use the tag
FIREFOX_159_0_RELEASEand keep both objdirs.mozconfig-jsis the Windows one without the--targetline.mozconfig-neckois a browser build used forxpcshell:mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-necko ac_add_options --enable-application=browser ac_add_options --enable-optimize ac_add_options --disable-debug ac_add_options --disable-tests ac_add_options --disable-nodejs ac_add_options --enable-rust-simd ac_add_options --without-wasm-sandboxed-libraries--disable-nodejsleaves the newtab bundle unfinished, which the helper does not need: stop onceobj-necko/dist/bin/xpcshellruns. -
Helper venv and shell. The Necko helper venv uses Python 3.12. From the repository root, with
MACOSX_DEPLOYMENT_TARGET=26.0:python3.12 -B tools/bootstrap_macos_helper.py python3.12 -B tools/build.py --donor-obj ../firefox-159/obj-js-standalone
bootstrap_macos_helper.pycreatesvendor/necko-derived/python(gitignored) withrequests,brotli,zstandard,h2,cryptography,backports.zstdandpublicsuffixlist; missing wheels come only from the gitignoredvendor/necko-derived/wheelsviapip --no-index, and an existing venv is kept. Pass--donor-obj(orRUYIJS_DONOR_OBJ) for that build only — do not export it from a long-lived shell profile. -
Result. The shell is
dist/js(withdist/libmozglue.dylib); the C client library islibruyijs_client.dylib. To run the examples, setRUYIJS_SHELLtodist/jsand putpython/onPYTHONPATH. The defaultxpcshellpath isfirefox-159/obj-necko/dist/bin/xpcshellnext to the repository; rename the Firefox directory to match or setRUYIJS_XPCSHELL. -
Direct-TLS and HTTP/3 libraries.
tools/build.py --necko-core-only --firefox-gfx-obj <obj-necko>builds the arm64libnecko_core.dylibagainst the donor NSS 3.131 (docs/tls-profile.md);tools/build_necko_quic.pybuildslibnecko_quic.dylib(docs/closed-route.zh-CN.md). -
Local wheel.
setup.pycan build amacosx_26_0_arm64wheel that places the shell at_runtime/dist/jsand copies the donorxpcshellclosure to_runtime/dist/necko(pluslibnecko_quic.dylibwhen present). Regenerate the runtime archive withpython3.12 -B tools/macos_runtime.py <zip-path>, then store the printed size and sha256, with the release URL, in themacosobject ofruntime.json. Neither the wheel nor the archive goes to PyPI. -
Do not commit the Firefox tree, either objdir,
dist/js, the helper venv, the macOS runtime zip,libnecko_quic.dylib,neqo-server,native/necko_quic/Cargo.lock, cookies, tokens, proxy credentials or response bodies. -
Reporting a macOS issue: include the ruyijs commit, the macOS version, the Xcode version, the Python version, the Firefox tag and which of the two objdirs the build used.
From the CONTRIBUTING.md checklist: rebuild the shell (js.exe on Windows, js on macOS) together with the client library (python -B tools/build.py ...), and check the behaviour through both Python and the C ABI. See Contributing and License.
| File | Responsibility |
|---|---|
build.py |
Build orchestration, input identity and artifact version checks |
bootstrap_macos_helper.py |
Creates the Necko helper venv on macOS; leaves an existing one untouched |
donor.py |
Reads the donor configuration, object lists and library paths |
generate.py |
Generates shell units and embedded resources, keeping the original license headers |
native.py |
Calls the compiler and linker, deploys runtime libraries |
client.py |
Builds the C ABI DLL, import library and public header |
geometry_fonts.py |
Font configuration and HarfBuzz compile inputs |
binding_order.py |
Firefox WebIDL prototype member order table |
sanitizer_data.py |
HTML Sanitizer default configuration data |
product_sources.py |
Production source list, environment baseline profile and domain compile boundaries |
compression_native.py / image_native.py / urlpattern_native.py
|
Third-party native library builds |
rust_runtime.py |
Supplies std and the allocator now that Firefox 159's jsrust no longer exports the Rust std |
skia_native.py |
Archives the Skia objects of the Firefox browser build; compile flags for the Canvas bridge units |
provenance.py |
SHA-256 and input identity re-verification |
wheel_runtime.py |
Downloads and verifies the runtime pinned in runtime.json when setup.py builds a wheel |
build_necko_quic.py |
Darwin build of libnecko_quic.dylib (docs/macos.md) |
macos_runtime.py |
Regenerates the macOS runtime archive (docs/macos.md) |
generated/ |
Two headers generated from a Firefox 159 browser build |
ruyiJS · GitHub · PyPI · LinuxDO · License: AGPL-3.0-only or commercial