Repository navigation
Enabling Rust support for Temporal #58730
Description
Activity
cc @nodejs/build @targos
which means that it will have to vendor third_party/rust and the toolchain: currently V8's third_party/rust is the same as that of Chrome, which includes a lot of extra Rust deps that Chrome has (so far this hasn't been a problem). If Node doesn't wish to pull all of that in, it may need to do something build-system wise to download those deps but not check them in to the tree.
IMO the latter probably makes more sense at least for the time being - Node.js currently also relies on toolchains installed in the system so instead of using
third_party/libc++1 andthird_party/llvm-buildetc, it looks up the compilers from the system from the configure script. There's not a DEPS manifest and build dependencies are just documented in BUILDING.md, generally the GYP files /Python scripts just figures out what is the path to the toolchain somehow and then use them in actions, like what we do with code that need to be processed by Python/assembled.Footnotes
-
some discussions about using libc++ on Windows somehow which might or might not lead to vendoring it in https://github.com/nodejs/node/issues/58123 ↩
-
@joyeecheung would that be the case for third_party/rust as well? That is not a system dep, it is a clone of https://chromium.googlesource.com/chromium/src/third_party/rust placed in the appropriate directory.
IIUC those are crates depended by V8's Temporal implementation? In that case it seems to make more sense to copy them as part of the V8 upgrades, and then compile them using the found toolchain(we have a similar situation with most things in
deps/v8/third_partyexcept zlib/simdutf which Node.js also uses, Node.js currently doesn't have rust dependencies though)@joyeecheung Yes, but there are also a lot of crates in there that are depended on by Chromium things (not just V8 temporal). We haven't felt the need to slice it further, and it's tricky to do so since the whole BUILD.gn/import generation code for this is managed by chrome.
So if you copy them into tree, it will be a lot of irrelevant files being copied in as well. Which might be okay. You may also be able to do an allowlisted copy, I can help provide a set of folders that matter.
The V8 upgrades are automated via
git node v8: https://github.com/nodejs/node/blob/main/doc/contributing/maintaining/maintaining-V8.md (for example this is the code used to removethird_party/eu-strip)I wonder if there can be a text file/JSON in the V8 directory somewhere with the allowlist for
third_party/rust, and thengit node v8can just read that list and only copy relevant folders/remove unnecessary files for the rust dependencies when it does the upgrade. @targos may know better.- addedbuild-agendaIssues and PRs to discuss during Build Working Group meetings.Issues and PRs to discuss during Build Working Group meetings.
on Jun 19, 2025 I'm doing some experiments locally and it's not going well :(
It looks like we just can't use the latest stable toolchain:$ cargo --version cargo 1.87.0 (99624be96 2025-05-06) $ rustc --version rustc 1.87.0 (17067e9ac 2025-05-09) $ pwd /Users/mzasso/git/nodejs/canary/deps/v8/third_party/rust/chromium_crates_io/vendor/temporal_capi-v0_0_9 $ cargo build error: failed to parse manifest at `/Users/mzasso/git/nodejs/canary/deps/v8/third_party/rust/chromium_crates_io/Cargo.toml` Caused by: `artifact = …` requires `-Z bindeps` (cxxbridge-cmd) $ cargo build -Z bindeps error: the `-Z` flag is only accepted on the nightly channel of Cargo, but this is the `stable` channel See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information about Rust release channels.Related unstable feature: https://doc.rust-lang.org/beta/cargo/reference/unstable.html#artifact-dependencies
Ok, it doesn't seem necessary for temporal_capi.
I'm able to build temporal_capi with this change: targos@77891cf$ cargo build -p temporal_capi ... Compiling diplomat v0.12.0 Compiling temporal_capi v0.0.9 (/Users/mzasso/git/nodejs/canary/deps/v8/third_party/rust/chromium_crates_io/vendor/temporal_capi-v0_0_9) Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.80sWith targos@11a9ecc, it creates a static library in
deps/v8/third_party/rust/chromium_crates_io/target/debug/libtemporal_capi.a.Yeah, the bindeps stuff is used by cxx, which is not used by the temporal work, it's a wider Chrome dependency. Using the
gnfiles to build stuff should also work (and is the intended way of building temporal-in-v8).The cargo stuff will work; we may not be able to guarantee it'll always work since there may be reason to do tweaks in the gn files.
Unfortunately we cannot rely on gn for now.
Fair enough. One other option is to dispense of
third_party/rustcompletely and instead just buildtemporal_rsfrom its published version, potentially applying patches when Chromium has them. The main challenges will be when Chromium changes the feature set it enables, updates the version, or adds a patch.But the edited Cargo.toml should work fine.
Well it doesn't work:
c++ -framework CoreFoundation -Wl,-search_paths_first -mmacosx-version-min=13.5 -arch arm64 -L./ -stdlib=libc++ -o mksnapshot \ obj/deps/v8/src/snapshot/mksnapshot.builtins-effects-dummy.o obj/deps/v8/src/snapshot/embedded/mksnapshot.embedded-empty.o obj/deps/v8/src/snapshot/embedded/mksnapshot.embedded-file-writer.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-aix.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-base.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-generic.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-mac.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-win.o obj/deps/v8/src/snapshot/embedded/mksnapshot.platform-embedded-file-writer-zos.o obj/deps/v8/src/snapshot/mksnapshot.mksnapshot.o obj/deps/v8/src/snapshot/mksnapshot.snapshot-empty.o obj/deps/v8/src/snapshot/mksnapshot.static-roots-gen.o \ libv8_base_without_compiler.a libv8_init.a libv8_libbase.a libv8_libplatform.a libabseil.a libicui18n.a libicuucx.a libicudata.a libv8_zlib.a libhighway.a libsimdutf.a libv8_compiler.a libv8_initializers.a libv8_initializers_slow.a \ ../../deps/v8/third_party/rust/chromium_crates_io/target/debug/libtemporal_capi.a Undefined symbols for architecture arm64: "_temporal_rs_Duration_compare", referenced from: v8::internal::JSTemporalDuration::Compare(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::Object>, v8::internal::DirectHandle<v8::internal::Object>, v8::internal::DirectHandle<v8::internal::Object>) in libv8_base_without_compiler.a[525](v8_base_without_compiler.js-temporal-objects.o) "_temporal_rs_Duration_total", referenced from: v8::internal::JSTemporalDuration::Total(v8::internal::Isolate*, v8::internal::DirectHandle<v8::internal::JSTemporalDuration>, v8::internal::DirectHandle<v8::internal::Object>) in libv8_base_without_compiler.a[525](v8_base_without_compiler.js-temporal-objects.o) ...$ nm libtemporal_capi.a | grep _temporal_rs_Duration_ 2>/dev/null 00000000000017ec T _temporal_rs_Duration_abs 0000000000001854 T _temporal_rs_Duration_add 00000000000011d8 T _temporal_rs_Duration_create 0000000000001548 T _temporal_rs_Duration_date 0000000000001618 T _temporal_rs_Duration_days 00000000000019c8 T _temporal_rs_Duration_destroy 00000000000012e0 T _temporal_rs_Duration_from_day_and_time 0000000000001348 T _temporal_rs_Duration_from_partial_duration 0000000000001440 T _temporal_rs_Duration_from_utf16 00000000000013a0 T _temporal_rs_Duration_from_utf8 000000000000164c T _temporal_rs_Duration_hours 00000000000014e0 T _temporal_rs_Duration_is_time_within_range 00000000000017b8 T _temporal_rs_Duration_is_zero 000000000000171c T _temporal_rs_Duration_microseconds 00000000000016e8 T _temporal_rs_Duration_milliseconds 0000000000001680 T _temporal_rs_Duration_minutes 00000000000015b0 T _temporal_rs_Duration_months 0000000000001750 T _temporal_rs_Duration_nanoseconds 0000000000001820 T _temporal_rs_Duration_negated 00000000000016b4 T _temporal_rs_Duration_seconds 0000000000001784 T _temporal_rs_Duration_sign 00000000000018c0 T _temporal_rs_Duration_subtract 0000000000001514 T _temporal_rs_Duration_time 000000000000192c T _temporal_rs_Duration_to_string 000000000000125c T _temporal_rs_Duration_try_new 00000000000015e4 T _temporal_rs_Duration_weeks 000000000000157c T _temporal_rs_Duration_yearsMake sure it's built with the right features. Duration.compare needs
--feature compiled_dataReacted by Michaël Zasso51 remaining items
- added a commit that references this issue
on Feb 19, 2026 - added a commit that references this issue
on Feb 22, 2026 - removedbuild-agendaIssues and PRs to discuss during Build Working Group meetings.Issues and PRs to discuss during Build Working Group meetings.
on Feb 26, 2026 I've removed this from the Build WG agenda as we have nodejs/build#4245 for tracking rust toolchain installation across the Jenkins CI machines.
As far as I am aware we have the
configure/gypscripts in place to opt into build the Temporal crate and waiting for a V8 update (14.4 or newer) to land onmainbefore potentially enabling Temporal by default in the Node.js builds.@richardlau Of the two blockers in your comment above (Rust toolchain in CI + Node 14.4+ landing in main) is there a rough ETA for when those will be unblocked?
I'm one of the champions of the Temporal proposal and as you can guess have been fielding a lot of "Node support when?" questions since Temporal was shipped in Chrome in January and even more since Temporal reached Stage 4 earlier this month.
Reacted by Michiel ter Reehorst, Leonardo E. Dominguez, Veeti Haapsamo, Manuel Warum, Andrea Mattè, Santiago Arboleda, Felix Hanken, alkihis, Paul O, james and 4 more@justingrant V8 14.4+ seems to be taken care of by #62526 (Node 26) at least, which seems to be targeting today. In general it claims to enable Temporal by default, so it seems the ETA is today.
We've hit a snag with Temporal under Rosetta 2 on macOS (how we build the universal pkg installer). Unfortunately we've only discovered that today as it was masked by a different failure under Rosetta 2: #63006 (comment)
We've hit a snag with Temporal under Rosetta 2 on macOS (how we build the universal pkg installer). Unfortunately we've only discovered that today as it was masked by a different failure under Rosetta 2: #63006 (comment)
Does that mean that Temporal will work under anything but MacOS with Rosetta, will slip to Node 27, will it just come with a patch/minor release after 26.0, or will 26.0 be delayed?
We've hit a snag with Temporal under Rosetta 2 on macOS (how we build the universal pkg installer). Unfortunately we've only discovered that today as it was masked by a different failure under Rosetta 2: #63006 (comment)
Does that mean that Temporal will work under anything but MacOS with Rosetta, will slip to Node 27, will it just come with a patch/minor release after 26.0, or will 26.0 be delayed?
Unclear/undecided right now, but we cannot release if the pkg build is broken.
Does that mean that Temporal will work under anything but MacOS with Rosetta, will slip to Node 27, will it just come with a patch/minor release after 26.0, or will 26.0 be delayed?
We've pushed node 26 back to next Tuesday while this is worked on.
We have prototyped a fix now.Reacted by Frulfump, Michiel ter Reehorst, T. Langhorst, Julian Grinblat, Madeline Gurriarán, leah, Greg Lavallee, Eli, Carlos Araya and jamesDoes that mean that Temporal will work under anything but MacOS with Rosetta, will slip to Node 27, will it just come with a patch/minor release after 26.0, or will 26.0 be delayed?
We've pushed node 26 back to next Tuesday while this is worked on. We have prototyped a fix now.
26 was released and noted that Temporal is enabled by default in the Blog post--does that mean this is resolved?
Closing as I believe this is resolved. Feel free to reopen if necessary.
It's enabled on all of the tier1/2 platforms shipped from our CI I believe. But at the time of writing it excludes some others such as:
- Alpine (Although that's being fixed for x64 in 26.1.0)
- Any other unofficial builds e.g. Linux-riscv64
- Smartos (tier 2)
- IBMi
Added issue #63213 for documentation on prerequisite component installation, and for Windows, additional requirement for checks in vcbuild.bat.
Hi!
I've been working on implementing ECMAScript Temporal upstream in V8. It's being implemented based on the temporal_rs and icu4x libraries, which are in Rust.
As such, it needs Rust support to work (initial V8 CL for adding Rust to DEPS.
When first working on this feature V8-in-Node CI was failing due to the lack of these vendored deps. So V8 now has a
v8_enable_temporal_supportthat is enabled by default1 but disabled in some builds, including the Node build.Presumably, NodeJS will eventually want to have support for Temporal. It's probably worth figuring out what is needed to get there even though there's still a fair amount of time for us to be ready to ship.
Opening this issue to start the conversation; I'm happy to help out upstream if needed.
A challenge that may crop up is that Node vendors v8 which means that it will have to vendor third_party/rust and the toolchain: currently V8's third_party/rust is the same as that of Chrome, which includes a lot of extra Rust deps that Chrome has (so far this hasn't been a problem). If Node doesn't wish to pull all of that in, it may need to do something build-system wise to download those deps but not check them in to the tree.
Footnotes
Temporal is still disabled at runtime by default (the implementation is not ready); but it still gets built. ↩