---
title: "How to Migrate Astro to Bun on CloudFlare Pages (2026 Guide)"
description: "Migrate your Astro project from Node.js to Bun on CloudFlare Pages. Step-by-step guide with build commands, BUN_VERSION setup, verification & troubleshooting."
date: 2026-07-27
categories: ["web-development"]
tags: ["bun","astro","cloudflare"]
---

import YouTubeEmbed from "../../components/widgets/YouTubeEmbed.astro";
import Notice from "../../components/widgets/Notice.astro";
import ListCheck from "../../components/widgets/ListCheck.astro";
import Tabs from "../../components/widgets/Tabs.astro";
import Tab from "../../components/widgets/Tab.astro";
import Accordion from "../../components/widgets/Accordion.astro";

Swapping Node.js and npm for Bun on CloudFlare Pages can cut dependency install times by 10-30x and shave 15-30% off I/O-heavy builds. Bun is a supported build runtime on CloudFlare Pages, not an experiment. If you have an existing Astro static site on Node.js and npm, this guide covers the full migration. Whether you [built a free blog with Astro and Cloudflare](/build-astro-blog-free/) or [migrated from WordPress to Astro](/wordpress-to-astro-migration/), the Bun swap is the next step for faster deploys.

<YouTubeEmbed
  url="https://www.youtube.com/embed/RUBWS6zp2us"
  label="How to Migrate Astro to Bun on CloudFlare"
/>

<Notice type="info" title="Video Note">The video above shows the original 2024 migration flow. The written guide below is fully updated for 2025 with current Bun versions, Cloudflare build system changes, and new troubleshooting guidance.</Notice>

## Prerequisites and compatibility

### Astro version compatibility

This migration works the same way for Astro v3 through v7 on static (SSG) sites. Astro 7 added a Rust compiler and Rolldown (Vite 8), which means faster builds. You can read more about [Astro 7 build performance](/astro-7-faster-builds/) for details. The Bun migration steps themselves have not changed across Astro versions.

<Notice type="info" title="Static sites only">This guide covers static (SSG) Astro sites. If you use SSR, read the next section first.</Notice>

### SSR users: important caveat

If you use `@astrojs/cloudflare` for server-side rendering with Astro 6+, Cloudflare Pages is **no longer supported** for SSR deployments. As of `@astrojs/cloudflare` v13, only Cloudflare Workers is supported for on-demand rendering. Static sites are unaffected by this change.

<Notice type="warning" title="SSR on Cloudflare Pages no longer supported">If you use `@astrojs/cloudflare` for SSR with Astro 6+, you must deploy to Cloudflare Workers, not Pages. Static sites are unaffected.</Notice>

## 1. Install Bun

<Tabs>
<Tab name="macOS / Linux (curl)">
```sh
curl -fsSL https://bun.sh/install | bash
```
</Tab>
<Tab name="macOS (Homebrew)">
```sh
brew install bun
```
</Tab>
<Tab name="Windows (PowerShell)">
```powershell
powershell -c "irm bun.sh/install.ps1 | iex"
```
</Tab>
<Tab name="Via npm (universal)">
```sh
npm install -g bun
```
</Tab>
</Tabs>

After installing, verify it works:

```sh
bun --version
```

You should see `1.3.x` or later. If you get `command not found`, restart your terminal or run `source ~/.bashrc` / `source ~/.zshrc`.

<Notice type="info" title="Verify your install">Run `bun --version`. You should see 1.3.x or later. If it is below 1.1.x, you will want to upgrade for Sharp image optimization compatibility.</Notice>

You can check [Bun vs NPM, Yarn, PNPM, and Others](/bun-package-manager/) for a detailed comparison of Bun against other package managers.

## 2. Remove existing lock files

Remove the lockfile from whatever package manager you were using before:

```sh
# If you were using npm:
rm package-lock.json

# If you were using pnpm:
rm pnpm-lock.yaml

# If you were using Yarn:
rm yarn.lock
```

Bun creates its own lockfile: `bun.lock` (text format, default since ~v1.2) or `bun.lockb` (binary). This gets generated on the next `bun install`.

<Notice type="warning" title="Commit your lockfile">Cloudflare Pages runs `bun install --frozen-lockfile` by default. If `bun.lock` or `bun.lockb` is not committed to your repo, your build will fail with a lockfile mismatch error.</Notice>

## 3. Install dependencies with Bun

Run `bun install` to install your project's dependencies:

```sh
bun install
```

This reads your `package.json` and downloads packages much faster than npm (typically 10-30x for fresh installs). The biggest win is CI/CD dependency install time.

Sharp, Astro's image optimization library, works with Bun natively. It was broken in 2023-2024 but has been fixed since Bun ~1.1.x. No workarounds needed.

If you need to update packages to their latest versions later, see how to [update packages with Bun](/bun-update-packages/).

## 4. Test your Astro project locally

Start the dev server to make sure everything works:

```sh
bun run dev
```

Open `http://localhost:4321` and verify your pages load correctly. Then test the production build:

```sh
bun run build
```

The `dist/` directory should be created without errors.

### Understanding the `--bun` flag

There is a distinction most guides skip:

- `bun run dev` / `bun run build` runs Astro through Bun's **Node.js compatibility layer**. This is stable and recommended for most projects.
- `bun run --bun dev` / `bun run --bun build` runs Astro using the **actual Bun runtime**. Faster, but some integrations may have rough edges.

<Notice type="info" title="The --bun flag">Start with `bun run build` (Node compat mode) for stability. If your project builds cleanly and you want more speed, try `bun run --bun build`. If you hit `ERR_HTTP_SOCKET_ASSIGNED` or other Node-specific errors, drop back to compat mode. It is still faster than npm.</Notice>

If you want to squeeze more speed out of your builds, check the guides on [Astro 7 build performance](/astro-7-faster-builds/) and how to [optimize Astro build speed](/astro-ssg-build-optimization/).

## 5. Configure Cloudflare Pages for Bun

Log into the Cloudflare dashboard and go to your project's settings. You'll need to update the build command and optionally pin your Bun version. If you haven't set up Cloudflare Pages yet, see how to [deploy an Astro site on Cloudflare Pages](/deploy-astrojs-cloudflare/) first.

### Update the build command

Change your Cloudflare Pages build command to:

<Tabs>
<Tab name="Recommended (Node compat)">
```
bun run build
```
</Tab>
<Tab name="Bun runtime (faster)">
```
bun run --bun build
```
</Tab>
</Tabs>

The recommended `bun run build` uses Bun's Node.js compatibility layer, which is stable and faster than npm. The `--bun` variant uses the native Bun runtime. It is faster but may not work with all integrations. Start with the recommended option.

### Pin your Bun version with BUN_VERSION

In Cloudflare Dashboard → Settings → Environment variables, add:

```
BUN_VERSION=1.3.14
```

Replace `1.3.14` with the latest stable Bun release. Pinning prevents surprise breakage when Cloudflare updates the default Bun version on their build image.

<Notice type="error" title="Avoid BUN_VERSION=latest">Setting `BUN_VERSION=latest` causes a 403 error during build. Bun's installer script hits rate-limiting issues when fetching the version list through Cloudflare's build image (which uses `asdf` under the hood). Always pin a specific version like `1.3.14`.</Notice>

### Cloudflare Pages build system versions (v2 vs v3)

Cloudflare Pages has three build system versions:

- **v3**: default for new projects. Bun 1.2.15, Node 22.16.0, Ubuntu 22.04.2.
- **v2**: default Bun 1.1.33, Node 18.17.1. Auto-migrating to v3 by February 2027.
- **v1**: deprecated. Auto-migrating to v3 by September 2026.

<Notice type="info" title="Check your build system">New projects default to v3. If you are on v1 or v2, consider upgrading in Cloudflare Dashboard, Pages, Settings. v1 does not have Bun preinstalled, so you need v2 or v3.</Notice>

Cloudflare Pages free tier gives you 500 builds/month, 1 concurrent build, and a 20-minute hard build timeout. Bun's faster installs help large projects stay under that timeout. No additional cost for using Bun vs Node.

## 6. Deploy to Cloudflare

Commit your changes and push to your Git repository:

```sh
git add .
git commit -m "Migrate to Bun"
git push
```

Cloudflare will detect the push and start building with the new Bun settings. You can watch the build progress in Cloudflare Dashboard → Pages → your project → Deployments.

## 7. Verify the deployment

Do not just assume it worked. Check these things:

<ListCheck>
<ul>
<li>Build log shows `bun install vX.X.X` (confirming Bun, not npm, ran the install)</li>
<li>Build completes without errors</li>
<li>Site loads correctly at your production URL</li>
<li>No hydration errors or console warnings in browser DevTools</li>
</ul>
</ListCheck>

How to verify:

1. **Build log**: Cloudflare Dashboard → Pages → Deployments → click the latest build → read the log. Look for `bun install vX.X.X` near the top.
2. **Site check**: Visit your production URL and click through several pages.
3. **Console check**: Open browser DevTools → Console tab. Look for any errors or warnings that weren't there before.

```sh
# Quick HTTP check from your terminal:
curl -I https://your-site.pages.dev
```

You should get a `200 OK` response.

## Troubleshooting common issues

<Accordion label="Build hangs on bun install" group="troubleshooting">
Bun install can intermittently hang on Cloudflare Pages. This is a known issue.

**Fix**: Set `SKIP_DEPENDENCY_INSTALL=true` as an environment variable in Cloudflare Dashboard, then change your build command to install Bun manually via npm:

```bash
npm install -g --allow-scripts=bun bun && export PATH="$(npm prefix -g)/bin:$PATH" && bun --version && bun install && bun run build
```

This bypasses the preinstalled Bun and installs a fresh copy during the build.
</Accordion>

<Accordion label="BUN_VERSION=latest causes 403 error" group="troubleshooting">
Setting `BUN_VERSION=latest` fails because Bun's installer script can't fetch the version list through Cloudflare's `asdf`-based build image.

**Fix**: Pin a specific Bun version instead:
```
BUN_VERSION=1.3.14
```
</Accordion>

<Accordion label="bun: command not found in build" group="troubleshooting">
Your Cloudflare Pages project is probably on build system v1, which doesn't have Bun preinstalled.

**Fix**: Go to Cloudflare Dashboard → Pages → Settings and upgrade to build system v2 or v3.
</Accordion>

<Accordion label="Sharp / image optimization errors" group="troubleshooting">
In 2023-2024, Sharp (Astro's image optimizer) didn't work with Bun. This has been resolved since Bun ~1.1.x.

**Fix**: Make sure you're running Bun 1.1.x or later. If you're on an older version, update your `BUN_VERSION` environment variable.
</Accordion>

<Accordion label="ERR_HTTP_SOCKET_ASSIGNED or Node-specific errors" group="troubleshooting">
You're likely using the `--bun` flag, which runs Astro through the native Bun runtime instead of Node.js compatibility mode. Some integrations don't work cleanly with native Bun.

**Fix**: Remove the `--bun` flag. Use `bun run build` instead of `bun run --bun build`. You still get Bun's faster install times.
</Accordion>

<Accordion label="Lockfile conflicts / frozen lockfile errors" group="troubleshooting">
Cloudflare Pages runs `bun install --frozen-lockfile` by default. If your `bun.lock` or `bun.lockb` file isn't committed, the build fails.

**Fix**: Run `bun install` locally, then commit the lockfile:
```sh
git add bun.lock
git commit -m "Add Bun lockfile"
git push
```
</Accordion>

<Notice type="info" title="Need the latest Bun on Cloudflare?">
If the preinstalled Bun is too old and `BUN_VERSION` doesn't support the version you need, use this workaround. Set `SKIP_DEPENDENCY_INSTALL=true` as an environment variable, then use this build command:
</Notice>

```bash
npm install -g --allow-scripts=bun bun && export PATH="$(npm prefix -g)/bin:$PATH" && bun --version && bun install && bun run build
```

This installs a fresh Bun during the build. If your build is timing out, Bun's faster installs may help. The 20-minute build timeout is a hard limit. See how to [optimize Astro build speed](/astro-ssg-build-optimization/) for more tips.

## When not to migrate to Bun

<Notice type="warning" title="Consider skipping if...">

- You use **Astro SSR with `@astrojs/cloudflare`** on Astro 6+. Cloudflare Pages no longer supports SSR, only Workers. This guide will not help.
- You rely on **Node.js-specific packages** that have not been tested with Bun.
- You use **Vite plugins that assume Node.js internals**. These may break under the `--bun` flag.
- Your project **already builds and deploys fine** with npm or pnpm. Consider whether the migration effort is worth it for your use case.

</Notice>

## Conclusion

Bun on Cloudflare Pages is a supported runtime with a mature build system (v3) and proper version pinning. The migration is a one-time effort: swap your lockfile, install dependencies with `bun install`, update the build command to `bun run build`, and pin `BUN_VERSION` in Cloudflare Dashboard. You get faster dependency installs, faster builds for I/O-heavy projects, and a simpler local dev experience.

If you are starting a new project, you can [build a free blog with Astro and Cloudflare](/build-astro-blog-free/) with Bun from day one. If you are looking at alternative deployment platforms for static Astro sites, Bunny.net is a solid option. Here is how to [deploy Astro to Bunny.net](/deploy-astro-bunny-net/).