diff --git a/.buildkite/Dockerfile b/.buildkite/Dockerfile
index 7f97965191..3d0cd7c15a 100644
--- a/.buildkite/Dockerfile
+++ b/.buildkite/Dockerfile
@@ -1,5 +1,5 @@
-ARG LLVM_VERSION="19"
-ARG REPORTED_LLVM_VERSION="19.1.7"
+ARG LLVM_VERSION="21"
+ARG REPORTED_LLVM_VERSION="21.1.8"
ARG OLD_BUN_VERSION="1.1.38"
ARG BUILDKITE_AGENT_TAGS="queue=linux,os=linux,arch=${TARGETARCH}"
diff --git a/.buildkite/ci.mjs b/.buildkite/ci.mjs
index 4e420a9a08..9400ebccad 100755
--- a/.buildkite/ci.mjs
+++ b/.buildkite/ci.mjs
@@ -109,13 +109,12 @@ const buildPlatforms = [
{ os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"] },
{ os: "linux", arch: "x64", baseline: true, distro: "amazonlinux", release: "2023", features: ["docker"] },
{ os: "linux", arch: "x64", profile: "asan", distro: "amazonlinux", release: "2023", features: ["docker"] },
- { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.22" },
- { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.22" },
- { os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22" },
+ { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.23" },
+ { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.23" },
+ { os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.23" },
{ os: "windows", arch: "x64", release: "2019" },
{ os: "windows", arch: "x64", baseline: true, release: "2019" },
- // TODO: Enable when Windows ARM64 CI runners are ready
- // { os: "windows", arch: "aarch64", release: "2019" },
+ { os: "windows", arch: "aarch64", release: "2019" },
];
/**
@@ -133,9 +132,9 @@ const testPlatforms = [
{ os: "linux", arch: "aarch64", distro: "ubuntu", release: "25.04", tier: "latest" },
{ os: "linux", arch: "x64", distro: "ubuntu", release: "25.04", tier: "latest" },
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "25.04", tier: "latest" },
- { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
- { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.22", tier: "latest" },
- { os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22", tier: "latest" },
+ { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.23", tier: "latest" },
+ { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.23", tier: "latest" },
+ { os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.23", tier: "latest" },
{ os: "windows", arch: "x64", release: "2019", tier: "oldest" },
{ os: "windows", arch: "x64", release: "2019", baseline: true, tier: "oldest" },
// TODO: Enable when Windows ARM64 CI runners are ready
@@ -304,6 +303,13 @@ function getCppAgent(platform, options) {
};
}
+ // Cross-compile Windows ARM64 from x64 runners
+ if (os === "windows" && arch === "aarch64") {
+ return getEc2Agent({ ...platform, arch: "x64" }, options, {
+ instanceType: "c7i.4xlarge",
+ });
+ }
+
return getEc2Agent(platform, options, {
instanceType: arch === "aarch64" ? "c8g.4xlarge" : "c7i.4xlarge",
});
@@ -326,8 +332,10 @@ function getLinkBunAgent(platform, options) {
}
if (os === "windows") {
- return getEc2Agent(platform, options, {
- instanceType: arch === "aarch64" ? "r8g.large" : "r7i.large",
+ // Cross-compile Windows ARM64 from x64 runners
+ const agentPlatform = arch === "aarch64" ? { ...platform, arch: "x64" } : platform;
+ return getEc2Agent(agentPlatform, options, {
+ instanceType: "r7i.large",
});
}
@@ -345,7 +353,7 @@ function getZigPlatform() {
arch: "aarch64",
abi: "musl",
distro: "alpine",
- release: "3.22",
+ release: "3.23",
};
}
@@ -456,6 +464,17 @@ function getBuildCommand(target, options, label) {
return `bun run build:${buildProfile}`;
}
+/**
+ * Get extra flags needed when cross-compiling Windows ARM64 from x64.
+ * Applied to C++ and link steps (not Zig, which has its own toolchain handling).
+ */
+function getWindowsArm64CrossFlags(target) {
+ if (target.os === "windows" && target.arch === "aarch64") {
+ return " --toolchain windows-aarch64 -DSKIP_CODEGEN=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl";
+ }
+ return "";
+}
+
/**
* @param {Platform} platform
* @param {PipelineOptions} options
@@ -463,6 +482,7 @@ function getBuildCommand(target, options, label) {
*/
function getBuildCppStep(platform, options) {
const command = getBuildCommand(platform, options);
+ const crossFlags = getWindowsArm64CrossFlags(platform);
return {
key: `${getTargetKey(platform)}-build-cpp`,
label: `${getTargetLabel(platform)} - build-cpp`,
@@ -476,7 +496,7 @@ function getBuildCppStep(platform, options) {
// We used to build the C++ dependencies and bun in separate steps.
// However, as long as the zig build takes longer than both sequentially,
// it's cheaper to run them in the same step. Can be revisited in the future.
- command: [`${command} --target bun`, `${command} --target dependencies`],
+ command: [`${command}${crossFlags} --target bun`, `${command}${crossFlags} --target dependencies`],
};
}
@@ -533,7 +553,7 @@ function getLinkBunStep(platform, options) {
ASAN_OPTIONS: "allow_user_segv_handler=1:disable_coredump=0:detect_leaks=0",
...getBuildEnv(platform, options),
},
- command: `${getBuildCommand(platform, options, "build-bun")} --target bun`,
+ command: `${getBuildCommand(platform, options, "build-bun")}${getWindowsArm64CrossFlags(platform)} --target bun`,
};
}
diff --git a/.buildkite/scripts/upload-release.sh b/.buildkite/scripts/upload-release.sh
index 4ee04ba45d..822a15d374 100755
--- a/.buildkite/scripts/upload-release.sh
+++ b/.buildkite/scripts/upload-release.sh
@@ -219,9 +219,8 @@ function create_release() {
bun-windows-x64-profile.zip
bun-windows-x64-baseline.zip
bun-windows-x64-baseline-profile.zip
- # TODO: Enable when Windows ARM64 CI runners are ready
- # bun-windows-aarch64.zip
- # bun-windows-aarch64-profile.zip
+ bun-windows-aarch64.zip
+ bun-windows-aarch64-profile.zip
)
function upload_artifact() {
diff --git a/.github/workflows/CLAUDE.md b/.github/workflows/CLAUDE.md
index 348555e184..86e3707436 100644
--- a/.github/workflows/CLAUDE.md
+++ b/.github/workflows/CLAUDE.md
@@ -33,8 +33,8 @@ The workflow runs all three formatters simultaneously:
#### 3. Tool Installation
-##### Clang-format-19
-- Installs ONLY `clang-format-19` package (not the entire LLVM toolchain)
+##### Clang-format-21
+- Installs ONLY `clang-format-21` package (not the entire LLVM toolchain)
- Uses `--no-install-recommends --no-install-suggests` to skip unnecessary packages
- Quiet installation with `-qq` and `-o=Dpkg::Use-Pty=0`
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index cc10727b59..274b7a44d0 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -10,8 +10,8 @@ on:
merge_group:
env:
BUN_VERSION: "1.3.2"
- LLVM_VERSION: "19.1.7"
- LLVM_VERSION_MAJOR: "19"
+ LLVM_VERSION: "21.1.8"
+ LLVM_VERSION_MAJOR: "21"
jobs:
autofix:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c55a43998c..f6c7e682da 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -35,7 +35,7 @@ $ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config
```
```bash#Fedora
-$ sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
+$ sudo dnf install cargo clang21 llvm21 lld21 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
```
```bash#openSUSE Tumbleweed
@@ -90,17 +90,17 @@ Our build scripts will automatically detect and use `ccache` if available. You c
## Install LLVM
-Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to match WebKit (precompiled), as mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
+Bun requires LLVM 21.1.8 (`clang` is part of LLVM). This version is enforced by the build system — mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
{% codetabs group="os" %}
```bash#macOS (Homebrew)
-$ brew install llvm@19
+$ brew install llvm@21
```
```bash#Ubuntu/Debian
$ # LLVM has an automatic installation script that is compatible with all versions of Ubuntu
-$ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 19 all
+$ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 21 all
```
```bash#Arch
@@ -112,17 +112,17 @@ $ sudo dnf install llvm clang lld-devel
```
```bash#openSUSE Tumbleweed
-$ sudo zypper install clang19 lld19 llvm19
+$ sudo zypper install clang21 lld21 llvm21
```
{% /codetabs %}
-If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.7).
+If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-21.1.8).
-Make sure Clang/LLVM 19 is in your path:
+Make sure Clang/LLVM 21 is in your path:
```bash
-$ which clang-19
+$ which clang-21
```
If not, run this to manually add it:
@@ -131,13 +131,13 @@ If not, run this to manually add it:
```bash#macOS (Homebrew)
# use fish_add_path if you're using fish
-# use path+="$(brew --prefix llvm@19)/bin" if you are using zsh
-$ export PATH="$(brew --prefix llvm@19)/bin:$PATH"
+# use path+="$(brew --prefix llvm@21)/bin" if you are using zsh
+$ export PATH="$(brew --prefix llvm@21)/bin:$PATH"
```
```bash#Arch
# use fish_add_path if you're using fish
-$ export PATH="$PATH:/usr/lib/llvm19/bin"
+$ export PATH="$PATH:/usr/lib/llvm21/bin"
```
{% /codetabs %}
@@ -299,7 +299,7 @@ The issue may manifest when initially running `bun setup` as Clang being unable
```
The C++ compiler
- "/usr/bin/clang++-19"
+ "/usr/bin/clang++-21"
is not able to compile a simple test program.
```
diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake
index a1edfe216e..d692ea4387 100644
--- a/cmake/targets/BuildBun.cmake
+++ b/cmake/targets/BuildBun.cmake
@@ -1016,6 +1016,7 @@ if(NOT WIN32)
-Wno-unused-function
-Wno-c++23-lambda-attributes
-Wno-nullability-completeness
+ -Wno-character-conversion
-Werror
)
else()
@@ -1033,6 +1034,7 @@ if(NOT WIN32)
-Werror=sometimes-uninitialized
-Wno-c++23-lambda-attributes
-Wno-nullability-completeness
+ -Wno-character-conversion
-Werror
)
@@ -1061,6 +1063,7 @@ else()
-Wno-inconsistent-dllimport
-Wno-incompatible-pointer-types
-Wno-deprecated-declarations
+ -Wno-character-conversion
)
endif()
@@ -1136,6 +1139,15 @@ if(LINUX)
-Wl,--wrap=pow
-Wl,--wrap=powf
)
+
+ # Disable LTO for workaround-missing-symbols.cpp to prevent LLD 21 from emitting
+ # glibc versioned symbol names (e.g. exp@GLIBC_2.17) from .symver directives into
+ # the .lto_discard assembler directive, which fails to parse the '@' character.
+ if(ENABLE_LTO)
+ set_source_files_properties(${CWD}/src/bun.js/bindings/workaround-missing-symbols.cpp
+ PROPERTIES COMPILE_OPTIONS "-fno-lto"
+ )
+ endif()
endif()
if(NOT ABI STREQUAL "musl")
diff --git a/cmake/tools/SetupLLVM.cmake b/cmake/tools/SetupLLVM.cmake
index d8849ed6f0..e79d7c7697 100644
--- a/cmake/tools/SetupLLVM.cmake
+++ b/cmake/tools/SetupLLVM.cmake
@@ -12,13 +12,7 @@ if(NOT ENABLE_LLVM)
return()
endif()
-# LLVM 21 is required for Windows ARM64 (first version with ARM64 Windows builds)
-# Other platforms use LLVM 19.1.7
-if(WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64|AARCH64")
- set(DEFAULT_LLVM_VERSION "21.1.8")
-else()
- set(DEFAULT_LLVM_VERSION "19.1.7")
-endif()
+set(DEFAULT_LLVM_VERSION "21.1.8")
optionx(LLVM_VERSION STRING "The version of LLVM to use" DEFAULT ${DEFAULT_LLVM_VERSION})
@@ -27,6 +21,8 @@ if(USE_LLVM_VERSION)
set(LLVM_VERSION_MAJOR ${CMAKE_MATCH_1})
set(LLVM_VERSION_MINOR ${CMAKE_MATCH_2})
set(LLVM_VERSION_PATCH ${CMAKE_MATCH_3})
+ # Accept any LLVM version within the same major.minor range (e.g. Alpine 3.23 ships 21.1.2)
+ set(LLVM_VERSION_RANGE ">=${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.0 <${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.99")
endif()
set(LLVM_PATHS)
@@ -78,14 +74,12 @@ macro(find_llvm_command variable command)
)
endif()
- math(EXPR LLVM_VERSION_NEXT_MAJOR "${LLVM_VERSION_MAJOR} + 1")
-
find_command(
VARIABLE ${variable}
VERSION_VARIABLE LLVM_VERSION
COMMAND ${commands}
PATHS ${LLVM_PATHS}
- VERSION ">=${LLVM_VERSION_MAJOR}.1.0 <${LLVM_VERSION_NEXT_MAJOR}.0.0"
+ VERSION "${LLVM_VERSION_RANGE}"
)
list(APPEND CMAKE_ARGS -D${variable}=${${variable}})
endmacro()
diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake
index 2f3e5ee8b4..5263f02fa9 100644
--- a/cmake/tools/SetupWebKit.cmake
+++ b/cmake/tools/SetupWebKit.cmake
@@ -6,7 +6,7 @@ option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of down
option(WEBKIT_BUILD_TYPE "The build type for local WebKit (defaults to CMAKE_BUILD_TYPE)")
if(NOT WEBKIT_VERSION)
- set(WEBKIT_VERSION 515344bc5d65aa2d4f9ff277b5fb944f0e051dcd)
+ set(WEBKIT_VERSION 7bc2f97e28353062bb54776ce01e4c2ff24c35cc)
endif()
# Use preview build URL for Windows ARM64 until the fix is merged to main
diff --git a/docs/project/building-windows.mdx b/docs/project/building-windows.mdx
index 5e50773b40..ec6a1af666 100644
--- a/docs/project/building-windows.mdx
+++ b/docs/project/building-windows.mdx
@@ -35,7 +35,7 @@ winget install "Visual Studio Community 2022" --override "--add Microsoft.Visual
After Visual Studio, you need the following:
-- LLVM (19.1.7 for x64, 21.1.8 for ARM64)
+- LLVM 21.1.8
- Go
- Rust
- NASM
@@ -51,7 +51,7 @@ After Visual Studio, you need the following:
irm https://get.scoop.sh | iex
scoop install nodejs-lts go rust nasm ruby perl ccache
# scoop seems to be buggy if you install llvm and the rest at the same time
-scoop install llvm@19.1.7
+scoop install llvm@21.1.8
```
For Windows ARM64, download LLVM 21.1.8 directly from GitHub releases (first version with ARM64 Windows builds):
diff --git a/docs/project/contributing.mdx b/docs/project/contributing.mdx
index 2627118897..fdc6945821 100644
--- a/docs/project/contributing.mdx
+++ b/docs/project/contributing.mdx
@@ -40,7 +40,7 @@ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config py
```
```bash Fedora
-sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
+sudo dnf install cargo clang21 llvm21 lld21 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
```
```bash openSUSE Tumbleweed
@@ -95,17 +95,17 @@ Our build scripts will automatically detect and use `ccache` if available. You c
## Install LLVM
-Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to match WebKit (precompiled), as mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
+Bun requires LLVM 21.1.8 (`clang` is part of LLVM). This version is enforced by the build system — mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
```bash macOS (Homebrew)
-brew install llvm@19
+brew install llvm@21
```
```bash Ubuntu/Debian
# LLVM has an automatic installation script that is compatible with all versions of Ubuntu
-wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 19 all
+wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 21 all
```
```bash Arch
@@ -117,17 +117,17 @@ sudo dnf install llvm clang lld-devel
```
```bash openSUSE Tumbleweed
-sudo zypper install clang19 lld19 llvm19
+sudo zypper install clang21 lld21 llvm21
```
-If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.7).
+If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-21.1.8).
-Make sure Clang/LLVM 19 is in your path:
+Make sure Clang/LLVM 21 is in your path:
```bash
-which clang-19
+which clang-21
```
If not, run this to manually add it:
@@ -136,13 +136,13 @@ If not, run this to manually add it:
```bash macOS (Homebrew)
# use fish_add_path if you're using fish
-# use path+="$(brew --prefix llvm@19)/bin" if you are using zsh
-export PATH="$(brew --prefix llvm@19)/bin:$PATH"
+# use path+="$(brew --prefix llvm@21)/bin" if you are using zsh
+export PATH="$(brew --prefix llvm@21)/bin:$PATH"
```
```bash Arch
# use fish_add_path if you're using fish
-export PATH="$PATH:/usr/lib/llvm19/bin"
+export PATH="$PATH:/usr/lib/llvm21/bin"
```
@@ -309,7 +309,7 @@ The issue may manifest when initially running `bun setup` as Clang being unable
```txt
The C++ compiler
- "/usr/bin/clang++-19"
+ "/usr/bin/clang++-21"
is not able to compile a simple test program.
```
diff --git a/flake.nix b/flake.nix
index f507a61c6d..175b7c584d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,10 +26,10 @@
};
};
- # LLVM 19 - matching the bootstrap script (targets 19.1.7, actual version from nixpkgs-unstable)
- llvm = pkgs.llvm_19;
- clang = pkgs.clang_19;
- lld = pkgs.lld_19;
+ # LLVM 21 - matching the bootstrap script (targets 21.1.8, actual version from nixpkgs-unstable)
+ llvm = pkgs.llvm_21;
+ clang = pkgs.clang_21;
+ lld = pkgs.lld_21;
# Node.js 24 - matching the bootstrap script (targets 24.3.0, actual version from nixpkgs-unstable)
nodejs = pkgs.nodejs_24;
@@ -42,7 +42,7 @@
pkgs.pkg-config
pkgs.ccache
- # Compilers and toolchain - version pinned to LLVM 19
+ # Compilers and toolchain - version pinned to LLVM 21
clang
llvm
lld
diff --git a/packages/bun-release/npm/@oven/bun-windows-aarch64/README.md b/packages/bun-release/npm/@oven/bun-windows-aarch64/README.md
new file mode 100644
index 0000000000..fb2cc9c79e
--- /dev/null
+++ b/packages/bun-release/npm/@oven/bun-windows-aarch64/README.md
@@ -0,0 +1,3 @@
+# Bun
+
+This is the Windows ARM64 binary for Bun, a fast all-in-one JavaScript runtime. https://bun.com
diff --git a/packages/bun-release/src/platform.ts b/packages/bun-release/src/platform.ts
index 35afde301a..253de0968c 100644
--- a/packages/bun-release/src/platform.ts
+++ b/packages/bun-release/src/platform.ts
@@ -95,6 +95,12 @@ export const platforms: Platform[] = [
bin: "bun-windows-x64-baseline",
exe: "bin/bun.exe",
},
+ {
+ os: "win32",
+ arch: "arm64",
+ bin: "bun-windows-aarch64",
+ exe: "bin/bun.exe",
+ },
];
export const supportedPlatforms: Platform[] = platforms
diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts
index a3db6771cc..418dbc87c9 100644
--- a/packages/bun-types/bun.d.ts
+++ b/packages/bun-types/bun.d.ts
@@ -2438,7 +2438,7 @@ declare module "bun" {
| `bun-linux-${Architecture}-${Libc}`
| `bun-linux-${Architecture}-${SIMD}`
| `bun-linux-${Architecture}-${SIMD}-${Libc}`
- | "bun-windows-x64"
+ | `bun-windows-${Architecture}`
| `bun-windows-x64-${SIMD}`;
}
diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1
index b4fba56480..c9367fff7f 100755
--- a/scripts/bootstrap.ps1
+++ b/scripts/bootstrap.ps1
@@ -1,4 +1,4 @@
-# Version: 11
+# Version: 12
# A script that installs the dependencies needed to build and test Bun.
# This should work on Windows 10 or newer with PowerShell.
@@ -387,7 +387,7 @@ function Install-PdbAddr2line {
function Install-Llvm {
Install-Package llvm `
-Command clang-cl `
- -Version "19.1.7"
+ -Version "21.1.8"
Add-To-Path "$env:ProgramFiles\LLVM\bin"
}
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index 43aa7fad7d..329d2dfbc4 100755
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Version: 27
+# Version: 28
# A script that installs the dependencies needed to build and test Bun.
# This should work on macOS and Linux with a POSIX shell.
@@ -1096,7 +1096,7 @@ install_build_essentials() {
}
llvm_version_exact() {
- print "19.1.7"
+ print "21.1.8"
}
llvm_version() {
@@ -1106,23 +1106,20 @@ llvm_version() {
install_llvm() {
case "$pm" in
apt)
- # Debian 13 (Trixie) has LLVM 19 natively, and apt.llvm.org doesn't have a trixie repo
- if [ "$distro" = "debian" ]; then
- install_packages \
- "llvm-$(llvm_version)" \
- "clang-$(llvm_version)" \
- "lld-$(llvm_version)" \
- "llvm-$(llvm_version)-dev" \
- "llvm-$(llvm_version)-tools" \
- "libclang-rt-$(llvm_version)-dev"
- else
- bash="$(require bash)"
- llvm_script="$(download_file "https://apt.llvm.org/llvm.sh")"
- execute_sudo "$bash" "$llvm_script" "$(llvm_version)" all
-
- # Install llvm-symbolizer explicitly to ensure it's available for ASAN
- install_packages "llvm-$(llvm_version)-tools"
+ # apt.llvm.org's GPG key uses SHA1, which Debian 13+ (sqv) rejects since 2026-02-01.
+ # Override the sequoia crypto policy to extend the SHA1 deadline.
+ # See: https://github.com/llvm/llvm-project/issues/153385
+ if [ -x /usr/bin/sqv ] && [ -f /usr/share/apt/default-sequoia.config ]; then
+ execute_sudo mkdir -p /etc/crypto-policies/back-ends
+ execute_sudo /usr/bin/sh -c "sed 's/sha1.second_preimage_resistance = 2026-02-01/sha1.second_preimage_resistance = 2028-02-01/' /usr/share/apt/default-sequoia.config > /etc/crypto-policies/back-ends/apt-sequoia.config"
fi
+
+ bash="$(require bash)"
+ llvm_script="$(download_file "https://apt.llvm.org/llvm.sh")"
+ execute_sudo "$bash" "$llvm_script" "$(llvm_version)" all
+
+ # Install llvm-symbolizer explicitly to ensure it's available for ASAN
+ install_packages "llvm-$(llvm_version)-tools"
;;
brew)
install_packages "llvm@$(llvm_version)"
@@ -1177,7 +1174,7 @@ install_gcc() {
;;
esac
- llvm_v="19"
+ llvm_v="21"
append_to_profile "export CC=clang-${llvm_v}"
append_to_profile "export CXX=clang++-${llvm_v}"
diff --git a/scripts/build-jsc.ts b/scripts/build-jsc.ts
index d4fa5673e6..b3be6092ae 100755
--- a/scripts/build-jsc.ts
+++ b/scripts/build-jsc.ts
@@ -77,10 +77,10 @@ const HAS_CCACHE = CCACHE !== null;
// On Windows, use clang-cl for MSVC compatibility
const CC_BASE = IS_WINDOWS
? findExecutable(["clang-cl.exe", "clang-cl"]) || "clang-cl"
- : findExecutable(["clang-19", "clang"]) || "clang";
+ : findExecutable(["clang-21", "clang"]) || "clang";
const CXX_BASE = IS_WINDOWS
? findExecutable(["clang-cl.exe", "clang-cl"]) || "clang-cl"
- : findExecutable(["clang++-19", "clang++"]) || "clang++";
+ : findExecutable(["clang++-21", "clang++"]) || "clang++";
const CC = HAS_CCACHE ? CCACHE : CC_BASE;
const CXX = HAS_CCACHE ? CCACHE : CXX_BASE;
diff --git a/scripts/run-clang-format.sh b/scripts/run-clang-format.sh
index 13d9e736b5..7316b68b52 100755
--- a/scripts/run-clang-format.sh
+++ b/scripts/run-clang-format.sh
@@ -12,7 +12,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
MODE="${1:-format}"
# Use LLVM_VERSION_MAJOR from environment or default to 19
-LLVM_VERSION="${LLVM_VERSION_MAJOR:-19}"
+LLVM_VERSION="${LLVM_VERSION_MAJOR:-21}"
# Ensure we have the specific clang-format version
CLANG_FORMAT="clang-format-${LLVM_VERSION}"
diff --git a/shell.nix b/shell.nix
index 571c66d176..a4917ddfe1 100644
--- a/shell.nix
+++ b/shell.nix
@@ -8,9 +8,9 @@ pkgs.mkShell rec {
# Core build tools (matching bootstrap.sh)
cmake
ninja
- clang_19
- llvm_19
- lld_19
+ clang_21
+ llvm_21
+ lld_21
nodejs_24
bun
rustc
@@ -77,10 +77,10 @@ pkgs.mkShell rec {
];
shellHook = ''
- export CC="${pkgs.lib.getExe pkgs.clang_19}"
- export CXX="${pkgs.lib.getExe' pkgs.clang_19 "clang++"}"
- export AR="${pkgs.llvm_19}/bin/llvm-ar"
- export RANLIB="${pkgs.llvm_19}/bin/llvm-ranlib"
+ export CC="${pkgs.lib.getExe pkgs.clang_21}"
+ export CXX="${pkgs.lib.getExe' pkgs.clang_21 "clang++"}"
+ export AR="${pkgs.llvm_21}/bin/llvm-ar"
+ export RANLIB="${pkgs.llvm_21}/bin/llvm-ranlib"
export CMAKE_C_COMPILER="$CC"
export CMAKE_CXX_COMPILER="$CXX"
export CMAKE_AR="$AR"
@@ -88,7 +88,7 @@ pkgs.mkShell rec {
export CMAKE_SYSTEM_PROCESSOR=$(uname -m)
export TMPDIR=''${TMPDIR:-/tmp}
'' + pkgs.lib.optionalString pkgs.stdenv.isLinux ''
- export LD="${pkgs.lib.getExe' pkgs.lld_19 "ld.lld"}"
+ export LD="${pkgs.lib.getExe' pkgs.lld_21 "ld.lld"}"
export NIX_CFLAGS_LINK="''${NIX_CFLAGS_LINK:+$NIX_CFLAGS_LINK }-fuse-ld=lld"
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath packages}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
'' + ''
diff --git a/src/bun.js/bindings/CPUFeatures.cpp b/src/bun.js/bindings/CPUFeatures.cpp
index aba699b6fc..7dab391e0b 100644
--- a/src/bun.js/bindings/CPUFeatures.cpp
+++ b/src/bun.js/bindings/CPUFeatures.cpp
@@ -69,6 +69,7 @@ static uint8_t x86_cpu_features()
#if CPU(ARM64)
#if OS(WINDOWS)
+#include
#elif OS(MACOS)
#include
#elif OS(LINUX)
@@ -81,7 +82,18 @@ static uint8_t aarch64_cpu_features()
uint8_t features = 0;
#if OS(WINDOWS)
-#pragma error "TODO: Implement AArch64 CPU features for Windows"
+ // FP is mandatory on AArch64 — no separate PF_ constant exists for it
+ features |= 1 << static_cast(AArch64CPUFeature::fp);
+ if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
+ features |= 1 << static_cast(AArch64CPUFeature::neon);
+ if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE))
+ features |= 1 << static_cast(AArch64CPUFeature::aes);
+ if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE))
+ features |= 1 << static_cast(AArch64CPUFeature::crc32);
+ if (IsProcessorFeaturePresent(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE))
+ features |= 1 << static_cast(AArch64CPUFeature::atomics);
+ if (IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE))
+ features |= 1 << static_cast(AArch64CPUFeature::sve);
#elif OS(MACOS)
int value = 0;
size_t size = sizeof(value);
diff --git a/src/bun.js/bindings/EncodeURIComponent.cpp b/src/bun.js/bindings/EncodeURIComponent.cpp
index 57cbe0a135..75e86f4a61 100644
--- a/src/bun.js/bindings/EncodeURIComponent.cpp
+++ b/src/bun.js/bindings/EncodeURIComponent.cpp
@@ -39,7 +39,7 @@ static WebCore::ExceptionOr encode(VM& vm, const WTF::BitSet<256>& doNotEs
// 4-d-ii-1. Let V be the code unit value of C.
char32_t codePoint;
if (!U16_IS_LEAD(character))
- codePoint = character;
+ codePoint = static_cast(character);
else {
// 4-d-iii. Else,
// 4-d-iii-1. Increase k by 1.
diff --git a/src/bun.js/bindings/EncodingTables.h b/src/bun.js/bindings/EncodingTables.h
index a7b7dec52a..ca3d1d7e7a 100644
--- a/src/bun.js/bindings/EncodingTables.h
+++ b/src/bun.js/bindings/EncodingTables.h
@@ -55,6 +55,10 @@ template static auto findInSortedPair
inline void checkEncodingTableInvariants() {}
#endif
+// LLVM 21+ -Wcharacter-conversion flags intentional char32_t/char16_t comparisons
+// used for Unicode code point range checks in findFirstInSortedPairs.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcharacter-conversion"
struct CompareFirst {
template bool operator()(const TypeA& a, const TypeB& b)
{
@@ -132,5 +136,6 @@ template static auto findInSortedPair
}
return std::ranges::equal_range(collection, makeFirstAdapter(key), CompareFirst {});
}
+#pragma clang diagnostic pop
}
diff --git a/src/bun.js/bindings/SecretsDarwin.cpp b/src/bun.js/bindings/SecretsDarwin.cpp
index d76ae34cd8..c25ff88e4c 100644
--- a/src/bun.js/bindings/SecretsDarwin.cpp
+++ b/src/bun.js/bindings/SecretsDarwin.cpp
@@ -136,23 +136,23 @@ private:
bool load_functions()
{
CFRelease = (void (*)(CFTypeRef))dlsym(cf_handle, "CFRelease");
- CFStringCreateWithCString = (CFStringRef(*)(CFAllocatorRef, const char*, CFStringEncoding))dlsym(cf_handle, "CFStringCreateWithCString");
- CFDataCreate = (CFDataRef(*)(CFAllocatorRef, const UInt8*, CFIndex))dlsym(cf_handle, "CFDataCreate");
+ CFStringCreateWithCString = (CFStringRef (*)(CFAllocatorRef, const char*, CFStringEncoding))dlsym(cf_handle, "CFStringCreateWithCString");
+ CFDataCreate = (CFDataRef (*)(CFAllocatorRef, const UInt8*, CFIndex))dlsym(cf_handle, "CFDataCreate");
CFDataGetBytePtr = (const UInt8* (*)(CFDataRef))dlsym(cf_handle, "CFDataGetBytePtr");
- CFDataGetLength = (CFIndex(*)(CFDataRef))dlsym(cf_handle, "CFDataGetLength");
- CFDictionaryCreateMutable = (CFMutableDictionaryRef(*)(CFAllocatorRef, CFIndex, const CFDictionaryKeyCallBacks*, const CFDictionaryValueCallBacks*))dlsym(cf_handle, "CFDictionaryCreateMutable");
+ CFDataGetLength = (CFIndex (*)(CFDataRef))dlsym(cf_handle, "CFDataGetLength");
+ CFDictionaryCreateMutable = (CFMutableDictionaryRef (*)(CFAllocatorRef, CFIndex, const CFDictionaryKeyCallBacks*, const CFDictionaryValueCallBacks*))dlsym(cf_handle, "CFDictionaryCreateMutable");
CFDictionaryAddValue = (void (*)(CFMutableDictionaryRef, const void*, const void*))dlsym(cf_handle, "CFDictionaryAddValue");
- CFStringGetCString = (Boolean(*)(CFStringRef, char*, CFIndex, CFStringEncoding))dlsym(cf_handle, "CFStringGetCString");
+ CFStringGetCString = (Boolean (*)(CFStringRef, char*, CFIndex, CFStringEncoding))dlsym(cf_handle, "CFStringGetCString");
CFStringGetCStringPtr = (const char* (*)(CFStringRef, CFStringEncoding))dlsym(cf_handle, "CFStringGetCStringPtr");
- CFStringGetLength = (CFIndex(*)(CFStringRef))dlsym(cf_handle, "CFStringGetLength");
- CFStringGetMaximumSizeForEncoding = (CFIndex(*)(CFIndex, CFStringEncoding))dlsym(cf_handle, "CFStringGetMaximumSizeForEncoding");
+ CFStringGetLength = (CFIndex (*)(CFStringRef))dlsym(cf_handle, "CFStringGetLength");
+ CFStringGetMaximumSizeForEncoding = (CFIndex (*)(CFIndex, CFStringEncoding))dlsym(cf_handle, "CFStringGetMaximumSizeForEncoding");
- SecItemAdd = (OSStatus(*)(CFDictionaryRef, CFTypeRef*))dlsym(handle, "SecItemAdd");
- SecItemCopyMatching = (OSStatus(*)(CFDictionaryRef, CFTypeRef*))dlsym(handle, "SecItemCopyMatching");
- SecItemUpdate = (OSStatus(*)(CFDictionaryRef, CFDictionaryRef))dlsym(handle, "SecItemUpdate");
- SecItemDelete = (OSStatus(*)(CFDictionaryRef))dlsym(handle, "SecItemDelete");
- SecCopyErrorMessageString = (CFStringRef(*)(OSStatus, void*))dlsym(handle, "SecCopyErrorMessageString");
- SecAccessCreate = (OSStatus(*)(CFStringRef, CFArrayRef, SecAccessRef*))dlsym(handle, "SecAccessCreate");
+ SecItemAdd = (OSStatus (*)(CFDictionaryRef, CFTypeRef*))dlsym(handle, "SecItemAdd");
+ SecItemCopyMatching = (OSStatus (*)(CFDictionaryRef, CFTypeRef*))dlsym(handle, "SecItemCopyMatching");
+ SecItemUpdate = (OSStatus (*)(CFDictionaryRef, CFDictionaryRef))dlsym(handle, "SecItemUpdate");
+ SecItemDelete = (OSStatus (*)(CFDictionaryRef))dlsym(handle, "SecItemDelete");
+ SecCopyErrorMessageString = (CFStringRef (*)(OSStatus, void*))dlsym(handle, "SecCopyErrorMessageString");
+ SecAccessCreate = (OSStatus (*)(CFStringRef, CFArrayRef, SecAccessRef*))dlsym(handle, "SecAccessCreate");
return CFRelease && CFStringCreateWithCString && CFDataCreate && CFDataGetBytePtr && CFDataGetLength && CFDictionaryCreateMutable && CFDictionaryAddValue && SecItemAdd && SecItemCopyMatching && SecItemUpdate && SecItemDelete && SecCopyErrorMessageString && SecAccessCreate && CFStringGetCString && CFStringGetCStringPtr && CFStringGetLength && CFStringGetMaximumSizeForEncoding;
}
diff --git a/src/bun.js/bindings/SecretsLinux.cpp b/src/bun.js/bindings/SecretsLinux.cpp
index 56a9972d8a..68b1af9df4 100644
--- a/src/bun.js/bindings/SecretsLinux.cpp
+++ b/src/bun.js/bindings/SecretsLinux.cpp
@@ -199,19 +199,19 @@ private:
g_free = (void (*)(gpointer))dlsym(glib_handle, "g_free");
g_hash_table_new = (GHashTable * (*)(void*, void*)) dlsym(glib_handle, "g_hash_table_new");
g_hash_table_destroy = (void (*)(GHashTable*))dlsym(glib_handle, "g_hash_table_destroy");
- g_hash_table_lookup = (gpointer(*)(GHashTable*, gpointer))dlsym(glib_handle, "g_hash_table_lookup");
+ g_hash_table_lookup = (gpointer (*)(GHashTable*, gpointer))dlsym(glib_handle, "g_hash_table_lookup");
g_hash_table_insert = (void (*)(GHashTable*, gpointer, gpointer))dlsym(glib_handle, "g_hash_table_insert");
g_list_free = (void (*)(GList*))dlsym(glib_handle, "g_list_free");
g_list_free_full = (void (*)(GList*, void (*)(gpointer)))dlsym(glib_handle, "g_list_free_full");
- g_str_hash = (guint(*)(gpointer))dlsym(glib_handle, "g_str_hash");
- g_str_equal = (gboolean(*)(gpointer, gpointer))dlsym(glib_handle, "g_str_equal");
+ g_str_hash = (guint (*)(gpointer))dlsym(glib_handle, "g_str_hash");
+ g_str_equal = (gboolean (*)(gpointer, gpointer))dlsym(glib_handle, "g_str_equal");
// Load libsecret functions
- secret_password_store_sync = (gboolean(*)(const SecretSchema*, const gchar*, const gchar*, const gchar*, void*, GError**, ...))
+ secret_password_store_sync = (gboolean (*)(const SecretSchema*, const gchar*, const gchar*, const gchar*, void*, GError**, ...))
dlsym(secret_handle, "secret_password_store_sync");
secret_password_lookup_sync = (gchar * (*)(const SecretSchema*, void*, GError**, ...))
dlsym(secret_handle, "secret_password_lookup_sync");
- secret_password_clear_sync = (gboolean(*)(const SecretSchema*, void*, GError**, ...))
+ secret_password_clear_sync = (gboolean (*)(const SecretSchema*, void*, GError**, ...))
dlsym(secret_handle, "secret_password_clear_sync");
secret_password_free = (void (*)(gchar*))dlsym(secret_handle, "secret_password_free");
secret_service_search_sync = (GList * (*)(SecretService*, const SecretSchema*, GHashTable*, SecretSearchFlags, void*, GError**))
@@ -220,7 +220,7 @@ private:
secret_value_get_text = (const gchar* (*)(SecretValue*))dlsym(secret_handle, "secret_value_get_text");
secret_value_unref = (void (*)(gpointer))dlsym(secret_handle, "secret_value_unref");
secret_item_get_attributes = (GHashTable * (*)(SecretItem*)) dlsym(secret_handle, "secret_item_get_attributes");
- secret_item_load_secret_sync = (gboolean(*)(SecretItem*, void*, GError**))dlsym(secret_handle, "secret_item_load_secret_sync");
+ secret_item_load_secret_sync = (gboolean (*)(SecretItem*, void*, GError**))dlsym(secret_handle, "secret_item_load_secret_sync");
return g_error_free && g_free && g_hash_table_new && g_hash_table_destroy && g_hash_table_lookup && g_hash_table_insert && g_list_free && secret_password_store_sync && secret_password_lookup_sync && secret_password_clear_sync && secret_password_free;
}
diff --git a/src/bun.js/bindings/TextCodecCJK.cpp b/src/bun.js/bindings/TextCodecCJK.cpp
index b09ee61889..eee9a134b9 100644
--- a/src/bun.js/bindings/TextCodecCJK.cpp
+++ b/src/bun.js/bindings/TextCodecCJK.cpp
@@ -890,7 +890,7 @@ static const GB18030EncodeIndex& gb18030EncodeIndex()
// https://unicode-org.atlassian.net/browse/ICU-22357
// The 2-byte values are handled correctly by values from gb18030()
// but these need to be exceptions from gb18030Ranges().
-static std::optional gb18030AsymmetricEncode(char16_t codePoint)
+static std::optional gb18030AsymmetricEncode(char32_t codePoint)
{
switch (codePoint) {
case 0xE81E:
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index 57c920ec68..31373b7359 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -302,7 +302,6 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c
JSC::Options::useJITCage() = false;
JSC::Options::useShadowRealm() = true;
JSC::Options::useV8DateParser() = true;
- JSC::Options::useMathSumPreciseMethod() = true;
JSC::Options::evalMode() = evalMode;
JSC::Options::heapGrowthSteepnessFactor() = 1.0;
JSC::Options::heapGrowthMaxIncrease() = 2.0;
diff --git a/src/bun.js/bindings/highway_strings.cpp b/src/bun.js/bindings/highway_strings.cpp
index 4eb625a9bd..f34d295d35 100644
--- a/src/bun.js/bindings/highway_strings.cpp
+++ b/src/bun.js/bindings/highway_strings.cpp
@@ -80,11 +80,18 @@ size_t IndexOfAnyCharImpl(const uint8_t* HWY_RESTRICT text, size_t text_len, con
return text_len;
} else {
ASSERT(chars_len <= 16);
- constexpr size_t kMaxPreloadedChars = 16;
- hn::Vec char_vecs[kMaxPreloadedChars];
+
+ // Use FixedTag to preload search characters into fixed-size vectors.
+ // ScalableTag vectors (SVE) are sizeless and cannot be stored in arrays.
+ // FixedTag gives us a known compile-time size that can be stored in arrays,
+ // then ResizeBitCast converts back to scalable vectors in the inner loop.
+ static constexpr size_t kMaxPreloadedChars = 16;
+ const hn::FixedTag d_fixed;
+ using VecFixed = hn::Vec;
+ VecFixed char_vecs[kMaxPreloadedChars];
const size_t num_chars_to_preload = std::min(chars_len, kMaxPreloadedChars);
for (size_t c = 0; c < num_chars_to_preload; ++c) {
- char_vecs[c] = hn::Set(d, chars[c]);
+ char_vecs[c] = hn::Set(d_fixed, chars[c]);
}
const size_t simd_text_len = text_len - (text_len % N);
@@ -95,12 +102,7 @@ size_t IndexOfAnyCharImpl(const uint8_t* HWY_RESTRICT text, size_t text_len, con
auto found_mask = hn::MaskFalse(d);
for (size_t c = 0; c < num_chars_to_preload; ++c) {
- found_mask = hn::Or(found_mask, hn::Eq(text_vec, char_vecs[c]));
- }
- if (chars_len > num_chars_to_preload) {
- for (size_t c = num_chars_to_preload; c < chars_len; ++c) {
- found_mask = hn::Or(found_mask, hn::Eq(text_vec, hn::Set(d, chars[c])));
- }
+ found_mask = hn::Or(found_mask, hn::Eq(text_vec, hn::ResizeBitCast(d, char_vecs[c])));
}
const intptr_t pos = hn::FindFirstTrue(d, found_mask);
diff --git a/src/bun.js/bindings/webcore/EventTarget.cpp b/src/bun.js/bindings/webcore/EventTarget.cpp
index 593c9d90ee..bac80efe61 100644
--- a/src/bun.js/bindings/webcore/EventTarget.cpp
+++ b/src/bun.js/bindings/webcore/EventTarget.cpp
@@ -105,7 +105,7 @@ bool EventTarget::addEventListener(const AtomString& eventType, RefaddAlgorithm([weakThis = WeakPtr { *this }, eventType, listener = WeakPtr { listener }, capture = options.capture](JSC::JSValue) {
if (weakThis && listener)
- Ref { *weakThis } -> removeEventListener(eventType, *listener, capture);
+ Ref { *weakThis }->removeEventListener(eventType, *listener, capture);
});
}
diff --git a/src/bun.js/bindings/webcore/URLPatternParser.cpp b/src/bun.js/bindings/webcore/URLPatternParser.cpp
index 2193dc0396..ff45aa4da4 100644
--- a/src/bun.js/bindings/webcore/URLPatternParser.cpp
+++ b/src/bun.js/bindings/webcore/URLPatternParser.cpp
@@ -470,7 +470,7 @@ String generatePatternString(const Vector& partList, const URLPatternStrin
if (!needsGrouping && part.prefix.isEmpty() && previousPart && previousPart->type == PartType::FixedText && !previousPart->value.isEmpty()) {
if (options.prefixCodepoint.length() == 1
- && options.prefixCodepoint.startsWith(*StringView(previousPart->value).codePoints().codePointAt(previousPart->value.length() - 1)))
+ && options.prefixCodepoint.startsWith(static_cast(*StringView(previousPart->value).codePoints().codePointAt(previousPart->value.length() - 1))))
needsGrouping = true;
}
@@ -541,7 +541,7 @@ String escapePatternString(StringView input)
}
// https://urlpattern.spec.whatwg.org/#is-a-valid-name-code-point
-bool isValidNameCodepoint(char16_t codepoint, URLPatternUtilities::IsFirst first)
+bool isValidNameCodepoint(char32_t codepoint, URLPatternUtilities::IsFirst first)
{
if (first == URLPatternUtilities::IsFirst::Yes)
return u_hasBinaryProperty(codepoint, UCHAR_ID_START) || codepoint == '_' || codepoint == '$';
diff --git a/src/bun.js/bindings/webcore/URLPatternParser.h b/src/bun.js/bindings/webcore/URLPatternParser.h
index 1f95d0b2e6..a06b56db52 100644
--- a/src/bun.js/bindings/webcore/URLPatternParser.h
+++ b/src/bun.js/bindings/webcore/URLPatternParser.h
@@ -104,7 +104,7 @@ ASCIILiteral convertModifierToString(Modifier);
std::pair> generateRegexAndNameList(const Vector& partList, const URLPatternStringOptions&);
String generatePatternString(const Vector& partList, const URLPatternStringOptions&);
String escapePatternString(StringView input);
-bool isValidNameCodepoint(char16_t codepoint, URLPatternUtilities::IsFirst);
+bool isValidNameCodepoint(char32_t codepoint, URLPatternUtilities::IsFirst);
} // namespace URLPatternUtilities
} // namespace WebCore
diff --git a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
index 1217b37ee7..f26d690324 100644
--- a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
+++ b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.cpp
@@ -49,14 +49,14 @@ WebCoreTypedArrayController::WebCoreTypedArrayController(bool allowAtomicsWait)
WebCoreTypedArrayController::~WebCoreTypedArrayController() = default;
-JSC::JSArrayBuffer* WebCoreTypedArrayController::toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* buffer)
+JSC::JSArrayBuffer* WebCoreTypedArrayController::toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer& buffer)
{
return JSC::jsCast(WebCore::toJS(lexicalGlobalObject, getDefaultGlobal(globalObject), buffer));
}
-void WebCoreTypedArrayController::registerWrapper(JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer* native, JSC::JSArrayBuffer* wrapper)
+void WebCoreTypedArrayController::registerWrapper(JSC::JSGlobalObject* globalObject, JSC::ArrayBuffer& native, JSC::JSArrayBuffer& wrapper)
{
- cacheWrapper(static_cast(JSC::getVM(globalObject).clientData)->normalWorld(), native, wrapper);
+ cacheWrapper(static_cast(JSC::getVM(globalObject).clientData)->normalWorld(), &native, &wrapper);
}
bool WebCoreTypedArrayController::isAtomicsWaitAllowedOnCurrentThread()
diff --git a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h
index d283a946d2..ae94125a99 100644
--- a/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h
+++ b/src/bun.js/bindings/webcore/WebCoreTypedArrayController.h
@@ -35,8 +35,8 @@ public:
WebCoreTypedArrayController(bool allowAtomicsWait);
virtual ~WebCoreTypedArrayController();
- JSC::JSArrayBuffer* toJS(JSC::JSGlobalObject*, JSC::JSGlobalObject*, JSC::ArrayBuffer*) override;
- void registerWrapper(JSC::JSGlobalObject*, ArrayBuffer*, JSC::JSArrayBuffer*) override;
+ JSC::JSArrayBuffer* toJS(JSC::JSGlobalObject*, JSC::JSGlobalObject*, JSC::ArrayBuffer&) override;
+ void registerWrapper(JSC::JSGlobalObject*, ArrayBuffer&, JSC::JSArrayBuffer&) override;
bool isAtomicsWaitAllowedOnCurrentThread() override;
JSC::WeakHandleOwner* wrapperOwner() { return &m_owner; }
diff --git a/src/bun.js/bindings/workaround-missing-symbols.cpp b/src/bun.js/bindings/workaround-missing-symbols.cpp
index 15703aa7b9..f39d330635 100644
--- a/src/bun.js/bindings/workaround-missing-symbols.cpp
+++ b/src/bun.js/bindings/workaround-missing-symbols.cpp
@@ -249,32 +249,9 @@ extern "C" __attribute__((used)) char __libc_single_threaded = 0;
#endif
#endif
-#ifdef _LIBCPP_VERBOSE_ABORT_NOEXCEPT
-// Workaround for this error:
-// workaround-missing-symbols.cpp:245:11: error: '__libcpp_verbose_abort' is missing exception specification 'noexcept'
-// 2025-07-10 15:59:47 PDT
-// 245 | void std::__libcpp_verbose_abort(char const* format, ...)
-// 2025-07-10 15:59:47 PDT
-// | ^
-// 2025-07-10 15:59:47 PDT
-// | noexcept
-// 2025-07-10 15:59:47 PDT
-// /opt/homebrew/Cellar/llvm/20.1.7/bin/../include/c++/v1/__verbose_abort:30:28: note: previous declaration is here
-// 2025-07-10 15:59:47 PDT
-// 30 | __printf__, 1, 2) void __libcpp_verbose_abort(const char* __format, ...) _LIBCPP_VERBOSE_ABORT_NOEXCEPT;
-// 2025-07-10 15:59:47 PDT
-// | ^
-// 2025-07-10 15:59:47 PDT
-// 1 error generated.
-// 2025-07-10 15:59:47 PDT
-// [515/540] Building CXX
-#define BUN_VERBOSE_ABORT_NOEXCEPT _LIBCPP_VERBOSE_ABORT_NOEXCEPT
-#else
-#define BUN_VERBOSE_ABORT_NOEXCEPT
-#endif
-
// Provide our implementation
-void std::__libcpp_verbose_abort(char const* format, ...) BUN_VERBOSE_ABORT_NOEXCEPT
+// LLVM 20 used _LIBCPP_VERBOSE_ABORT_NOEXCEPT, LLVM 21+ uses _NOEXCEPT (always noexcept).
+void std::__libcpp_verbose_abort(char const* format, ...) noexcept
{
va_list list;
va_start(list, format);
diff --git a/src/bun.js/bindings/wrapAnsi.cpp b/src/bun.js/bindings/wrapAnsi.cpp
index a366f40524..70274ab9d6 100644
--- a/src/bun.js/bindings/wrapAnsi.cpp
+++ b/src/bun.js/bindings/wrapAnsi.cpp
@@ -33,7 +33,7 @@ static char32_t decodeUTF16(const UChar* ptr, size_t available, size_t& outLen)
}
outLen = 1;
- return c;
+ return static_cast(c);
}
static inline uint8_t getVisibleWidth(char32_t cp, bool ambiguousIsWide)
diff --git a/src/bun.js/modules/BunJSCModule.h b/src/bun.js/modules/BunJSCModule.h
index 0b30cea5ac..2b38539d11 100644
--- a/src/bun.js/modules/BunJSCModule.h
+++ b/src/bun.js/modules/BunJSCModule.h
@@ -79,11 +79,13 @@ JSC_DEFINE_HOST_FUNCTION(functionStartRemoteDebugger,
JSC::JSValue hostValue = callFrame->argument(0);
JSC::JSValue portValue = callFrame->argument(1);
const char* host = defaultHost;
+ WTF::CString hostCString;
if (hostValue.isString()) {
auto str = hostValue.toWTFString(globalObject);
+ hostCString = toCString(str);
if (!str.isEmpty())
- host = toCString(str).span().data();
+ host = hostCString.span().data();
} else if (!hostValue.isUndefined()) {
throwVMError(globalObject, scope,
createTypeError(globalObject, "host must be a string"_s));
diff --git a/src/cli/install.ps1 b/src/cli/install.ps1
index 489209bea8..d159b87f20 100644
--- a/src/cli/install.ps1
+++ b/src/cli/install.ps1
@@ -14,10 +14,15 @@ param(
[Switch]$DownloadWithoutCurl = $false
);
-# filter out 32 bit + ARM
-if (-not ((Get-CimInstance Win32_ComputerSystem)).SystemType -match "x64-based") {
+# Detect system architecture
+$SystemType = (Get-CimInstance Win32_ComputerSystem).SystemType
+if ($SystemType -match "ARM64-based") {
+ $IsArm64 = $true
+} elseif ($SystemType -match "x64-based") {
+ $IsArm64 = $false
+} else {
Write-Output "Install Failed:"
- Write-Output "Bun for Windows is currently only available for x86 64-bit Windows.`n"
+ Write-Output "Bun for Windows is currently only available for x86 64-bit and ARM64 Windows.`n"
return 1
}
@@ -103,13 +108,18 @@ function Install-Bun {
$Version = "bun-$Version"
}
- $Arch = "x64"
- $IsBaseline = $ForceBaseline
- if (!$IsBaseline) {
- $IsBaseline = !( `
- Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);' `
- -Name 'Kernel32' -Namespace 'Win32' -PassThru `
- )::IsProcessorFeaturePresent(40);
+ if ($IsArm64) {
+ $Arch = "aarch64"
+ $IsBaseline = $false
+ } else {
+ $Arch = "x64"
+ $IsBaseline = $ForceBaseline
+ if (!$IsBaseline) {
+ $IsBaseline = !( `
+ Add-Type -MemberDefinition '[DllImport("kernel32.dll")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);' `
+ -Name 'Kernel32' -Namespace 'Win32' -PassThru `
+ )::IsProcessorFeaturePresent(40);
+ }
}
$BunRoot = if ($env:BUN_INSTALL) { $env:BUN_INSTALL } else { "${Home}\.bun" }
@@ -219,7 +229,8 @@ function Install-Bun {
# I want to keep this error message in for a few months to ensure that
# if someone somehow runs into this, it can be reported.
Write-Output "Install Failed - You are missing a DLL required to run bun.exe"
- Write-Output "This can be solved by installing the Visual C++ Redistributable from Microsoft:`nSee https://learn.microsoft.com/cpp/windows/latest-supported-vc-redist`nDirect Download -> https://aka.ms/vs/17/release/vc_redist.x64.exe`n`n"
+ $VCRedistArch = if ($Arch -eq "aarch64") { "arm64" } else { "x64" }
+ Write-Output "This can be solved by installing the Visual C++ Redistributable from Microsoft:`nSee https://learn.microsoft.com/cpp/windows/latest-supported-vc-redist`nDirect Download -> https://aka.ms/vs/17/release/vc_redist.${VCRedistArch}.exe`n`n"
Write-Output "The error above should be unreachable as Bun does not depend on this library. Please comment in https://github.com/oven-sh/bun/issues/8598 or open a new issue.`n`n"
Write-Output "The command '${BunBin}\bun.exe --revision' exited with code ${LASTEXITCODE}`n"
return 1
diff --git a/src/crash_handler.zig b/src/crash_handler.zig
index c719549cc1..cb88ae42f5 100644
--- a/src/crash_handler.zig
+++ b/src/crash_handler.zig
@@ -1700,8 +1700,8 @@ pub fn dumpStackTrace(trace: std.builtin.StackTrace, limits: WriteStackTraceLimi
const programs: []const [:0]const u8 = switch (bun.Environment.os) {
.windows => &.{"pdb-addr2line"},
- // if `llvm-symbolizer` doesn't work, also try `llvm-symbolizer-19`
- else => &.{ "llvm-symbolizer", "llvm-symbolizer-19" },
+ // if `llvm-symbolizer` doesn't work, also try `llvm-symbolizer-21`
+ else => &.{ "llvm-symbolizer", "llvm-symbolizer-21" },
};
for (programs) |program| {
var arena = bun.ArenaAllocator.init(bun.default_allocator);
diff --git a/test/napi/node-napi-tests/harness.ts b/test/napi/node-napi-tests/harness.ts
index 5b511ac346..2befe7ed97 100644
--- a/test/napi/node-napi-tests/harness.ts
+++ b/test/napi/node-napi-tests/harness.ts
@@ -20,8 +20,8 @@ export async function build(dir: string) {
// so we make it use clang instead
...(process.platform == "linux" && isCI
? {
- CC: !isMusl ? "/usr/lib/llvm-19/bin/clang" : "/usr/lib/llvm19/bin/clang",
- CXX: !isMusl ? "/usr/lib/llvm-19/bin/clang++" : "/usr/lib/llvm19/bin/clang++",
+ CC: !isMusl ? "/usr/lib/llvm-21/bin/clang" : "/usr/lib/llvm21/bin/clang",
+ CXX: !isMusl ? "/usr/lib/llvm-21/bin/clang++" : "/usr/lib/llvm21/bin/clang++",
}
: {}),
},