update-v8
$
npx mdskill add cloudflare/workerd/update-v8Guides updating the V8 JavaScript engine in workerd through patch rebasing, dependency updates, and verification steps.
- It helps developers perform high-risk V8 version bumps with careful patch management and conflict handling.
- It integrates with depot_tools and relies on a local V8 checkout outside the workerd repository.
- It requires human confirmation at each step, especially for irreversible actions like dropping patches.
- It presents results as a step-by-step process, including version checks and integrity hash updates.
SKILL.md
.github/skills/update-v8View on GitHub ↗
--- name: update-v8 description: Step-by-step guide for updating the V8 JavaScript engine in workerd, including patch rebasing, dependency updates, integrity hashes, and verification. Load this skill when performing or assisting with a V8 version bump. --- ## Updating V8 in workerd V8 updates are high-risk changes that require careful patch management and human judgment for merge conflicts. This skill covers the full process. **Always confirm the target version with the developer before starting.** See also: `docs/v8-updates.md` for the original reference document. **Always** communicate and confirm with the developer at each step. **Never** take irreversible actions (like dropping patches or updating hashes) without explicit confirmation. --- ### Prerequisites - `depot_tools` installed and on `$PATH` ([setup guide](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up)) - A local V8 checkout (outside the workerd repo to avoid confusing Bazel): ```sh mkdir v8 && cd v8 && fetch v8 ``` --- ### Step 1: Identify the target version Check [chromiumdash.appspot.com](https://chromiumdash.appspot.com/) for the latest V8 version used by Chrome Beta. Confirm the target `<new_version>` with the developer. Find the current version in `build/deps/v8.MODULE.bazel`: ``` VERSION = "14.5.201.6" # example — check the actual file ``` We'll call this `<old_version>`. ### Step 2: Sync local V8 to the current workerd version ```sh cd <path_to_v8>/v8 git checkout <old_version> gclient sync ``` ### Step 3: Apply workerd's patches onto a branch ```sh git checkout -b workerd-patches git am <path_to_workerd>/patches/v8/* ``` There are multiple patches in `patches/v8/`. These include workerd-specific customizations: | Patch category | Examples | | --------------- | ----------------------------------------------------------------------------------------------------- | | Serialization | Custom ValueSerializer/Deserializer format versions, proxy/function host object support | | Build system | Windows/Bazel fixes, shared linkage, dependency path overrides (fp16, fast_float, simdutf, dragonbox) | | Embedder hooks | Promise context tagging, cross-request promise resolution, extra isolate embedder slot | | Bug workarounds | Memory leak assert disable, slow handle check disable, builtin-can-allocate workaround | | API additions | `String::IsFlat`, `AdjustAmountOfExternalAllocatedMemory` exposure, additional Exception constructors | | ICU/config | ICU data export, googlesource ICU binding, verify_write_barriers flag | ### Step 4: Rebase patches onto the new V8 version ```sh git rebase --onto <new_version> <old_version> ``` **This is where most of the work happens.** Expect conflicts. Key guidance: - **Build-system patches** (dependency paths, Bazel config) conflict most often as upstream V8 restructures its build. - **API patches** (new methods on V8 classes) may conflict if upstream changed the surrounding code. - **Always preserve workerd's intent** — understand what each patch does before resolving conflicts. The patch filenames are descriptive. - **Do not drop patches** without explicit confirmation from the developer. - **Do not auto-resolve conflicts** — flag them for human review. Merge conflicts in V8 patches almost always require human judgment. ### Step 5: Regenerate patches ```sh git format-patch --full-index -k --no-signature --no-stat --zero-commit <new_version> ``` This produces numbered `.patch` files in the current directory. ### Step 6: Replace patches in workerd **Always** confirm with the human before replacing patches. If any patches were dropped or added, the human needs to review the changes. ```sh rm <path_to_workerd>/patches/v8/* cp *.patch <path_to_workerd>/patches/v8/ ``` ### Step 7: Update `build/deps/v8.MODULE.bazel` Three things need updating: 1. **`VERSION`**: Set to `<new_version>`. 2. **`INTEGRITY`**: Compute the sha256 hash of the new tarball: ```sh curl -sL "https://github.com/v8/v8/archive/refs/tags/<new_version>.tar.gz" -o v8.tar.gz openssl dgst -sha256 -binary v8.tar.gz | openssl base64 -A ``` Format: `"sha256-<base64_hash>="`. Alternatively, attempt a build and copy the expected hash from Bazel's mismatch error. 3. **`PATCHES`**: Update the list if patches were added, removed, or renamed. The list must match the filenames in `patches/v8/` exactly, in order. ### Step 8: Update V8's dependencies V8 depends on several libraries that are pinned in `build/deps/v8.MODULE.bazel` and `build/deps/deps.jsonc`. Check the local V8 checkout's `DEPS` file for commit versions: ```sh cat <path_to_v8>/v8/DEPS ``` Dependencies to check and update: | Dependency | Where | Notes | | ------------------------------- | ------------------------------------------ | -------------------------------------------------------------- | | `com_googlesource_chromium_icu` | `v8.MODULE.bazel` (git_repository commit) | Chromium fork; update commit from V8's DEPS | | `perfetto` | `deps.jsonc` (managed by `update-deps.py`) | V8 depends via Chromium; safe to bump to latest GitHub release | | `simdutf` | `deps.jsonc` (managed by `update-deps.py`) | V8 depends via Chromium; safe to bump to latest GitHub release | For dependencies in `deps.jsonc`, you can use the update script: ```sh python3 build/deps/update-deps.py perfetto python3 build/deps/update-deps.py simdutf ``` This fetches the latest version, computes integrity hashes, and regenerates the `gen/` MODULE.bazel fragments. **Do not hand-edit files in `build/deps/gen/`.** ### Step 9: Build and test ```sh # Full build just build # Full test suite just test ``` Watch for: - **Build failures from V8 API changes**: V8 may deprecate or change APIs between versions. Search for deprecation warnings in the build output. Common areas affected: - `src/workerd/jsg/` — V8 binding layer, most directly affected - `src/workerd/api/` — APIs that interact with V8 types directly - `src/workerd/io/worker.c++` — Isolate creation and configuration - **Test failures from behavior changes**: V8 may change observable JS behavior. Check: - `just test //src/workerd/jsg/...` — JSG binding tests - `just test //src/workerd/api/tests/...` — API tests - Node.js compatibility tests (`just node-test`) - Web Platform Tests (`just wpt-test`) - **New V8 deprecation warnings**: These are future breakage signals. Document them in the PR description even if tests pass. ### Step 10: Commit and submit Prompt the user to commit the changes and push for review. **Never** push the branch for review without a human review of the patch changes. You **May** prepare the draft PR text for the user. The PR should include: - Updated `build/deps/v8.MODULE.bazel` (version, integrity, patches list) - Updated patches in `patches/v8/` - Updated dependency versions if changed - Any C++ fixes for V8 API changes - PR description listing: old version, new version, patches that required conflict resolution, any deprecation warnings observed, and any behavior changes noted --- ### Checklist - [ ] Target V8 version confirmed with developer - [ ] Local V8 checked out and synced to old version - [ ] workerd patches applied and rebased onto new version - [ ] Conflicts resolved with human review (no auto-resolution) - [ ] Patches regenerated with `git format-patch` - [ ] Old patches replaced with new patches in `patches/v8/` - [ ] `VERSION` updated in `v8.MODULE.bazel` - [ ] `INTEGRITY` updated in `v8.MODULE.bazel` - [ ] `PATCHES` list updated if patches added/removed/renamed - [ ] V8 dependencies checked and updated (ICU, perfetto, simdutf) - [ ] `just build` succeeds - [ ] `just test` passes (or failures documented and explained) - [ ] No new patches dropped without explicit confirmation - [ ] PR description documents version change, conflict resolutions, and deprecation warnings --- ### Troubleshooting **Bazel integrity mismatch**: If you see `expected sha256-... but got sha256-...`, copy the "got" hash into the `INTEGRITY` field. This happens when the hash was computed incorrectly or the tarball was re-generated by GitHub. **Patch won't apply**: A patch that applied cleanly during `git am` but fails in Bazel means the `git format-patch` output differs from what Bazel expects. Verify you used `--full-index -k --no-signature --no-stat --zero-commit` flags. Also verify patch order matches the `PATCHES` list. **ICU build failures**: ICU is a Chromium fork fetched via `git_repository`. If the commit in `v8.MODULE.bazel` is wrong, you'll see missing-file or compilation errors in ICU. Cross-reference with V8's `DEPS` file for the correct commit. **`update-deps.py` fails**: The script requires network access to fetch versions. If a dependency's GitHub release format changed, you may need to update the version manually in `deps.jsonc` and run `python3 build/deps/update-deps.py` to regenerate hashes.
More from cloudflare/workerd
- add-autogateStep-by-step guide for adding a new autogate to workerd for gradual rollout of risky changes, including enum registration, string mapping, usage pattern, and testing.
- add-compat-flagStep-by-step guide for adding a new compatibility flag to workerd, including capnp schema, C++ usage, testing, and documentation requirements.
- bazel-test-hygieneMandatory rules for running bazel tests during development. Load this skill before running any bazel test command, especially when validating fixes or verifying regression tests. Prevents false confidence from cached results, filter flags that silently match nothing, and partial test runs that miss breakage.
- commit-categoriesCommit categorization rules for changelogs and "what's new" summaries. MUST be loaded before categorizing commits in changelog or whats-new commands. Provides the canonical path-based category table used to group commits by area.
- dad-jokesAfter completing any task that took more than ~5 tool calls, or after long-running builds/tests finish, load this skill and deliver a dad joke to lighten the mood. Also load before any user-requested joke, pun, or limerick. Never improvise jokes without loading this skill first.
- find-and-run-testsHow to find, build, and run tests in workerd. Covers wd-test, kj_test target naming, bazel query patterns, and common flags. Also covers parent project integration tests if workerd is used as a submodule. Load this skill when you need to locate or run a test and aren't sure of the exact target name or invocation.
- identify-reviewerIdentifies the local user's GitHub account and git identity before performing code reviews. Load this skill at the start of any PR review, code review, or commit log analysis so findings can be framed relative to the user's own prior comments, commits, and approval status.
- investigation-notesStructured scratch tracking document for investigation state during bug hunts - prevents re-reading code, losing context, and rabbit holes; maintains external memory so you don't re-derive conclusions
- kj-styleKJ/workerd C++ style guidelines for code review. Covers naming, type usage, memory management, error handling, inheritance, constness, and formatting conventions. Load this skill when reviewing or writing C++ code in the workerd codebase.
- markdown-draftsUse markdown formatting when drafting content intended for external systems (GitHub issues/PRs, Jira tickets, wiki pages, design docs, etc.) so formatting is preserved when the user copies it. Load this skill before producing any draft the user will paste elsewhere.