Changesets does not support Bun out of the box: it doesn't resolve workspaces or catalogs. This is a known issue (Bun incompatibility, workspace protocol support request, unmerged PR for workspace support). Here's how to resolve it.
When you try to publish packages with Changesets in a Bun monorepo, your published packages will contain unresolved workspace:*
references:
{
"name": "@macalinao/eslint-config-react",
"dependencies": {
"@macalinao/eslint-config": "workspace:*"
}
}
This breaks npm installations for anyone trying to use your packages. The workspace references that work perfectly in development don't get resolved to actual version numbers during publishing.
I created custom scripts that ensure workspace references get resolved properly. You can see the full implementation in my style-guide repository:
{
"scripts": {
"ci:version": "changeset version && bun update",
"ci:publish": "for dir in packages/*; do (cd \"$dir\" && bun publish || true); done && changeset tag"
}
}
bun update
The key insight was adding bun update
after changeset version
. Here's what happens:
changeset version
updates the version numbers in package.json filesbun update
then fixes the bun.lockb file to properly resolve all workspace:*
references to these new version numbersWithout bun update
, the lockfile remains out of sync with the updated package versions. This causes bun publish
to fail or publish packages with unresolved workspace references. The bun update
command ensures that when @macalinao/eslint-config
gets bumped to version 4.2.2, the lockfile is updated so that bun publish
can properly resolve and replace workspace:*
with 4.2.2
during publishing.
Instead of using changeset publish
, I iterate through every package and publish them individually:
for dir in packages/*; do
(cd "$dir" && bun publish || true)
done && changeset tag
I do this because:
workspace:*
references are resolved before publishing|| true
means if one package fails (maybe it's already published), the others still get publishedchangeset tag
This approach prevents partial-publish disasters where some packages would fail and leave my monorepo in an inconsistent state.
The GitHub action is largely the same as the official documentation, utilizing the changesets/action GitHub action. Here's my workflow from release.yml:
name: Release
on:
push:
branches:
- master
jobs:
version:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- name: Setup npmrc
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build
run: bun run build
- name: Create and publish versions
uses: changesets/action@v1
with:
version: bun run ci:version
commit: "chore: update versions"
title: "chore: update versions"
publish: bun run ci:publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The workflow:
oven-sh/setup-bun@v2
.npmrc
with my npm auth tokenci:version
and ci:publish
scriptsWhen I push changesets to master, this workflow creates a PR with version updates. When I merge that PR, it automatically publishes all packages to npm.
Each package needs proper publishing configuration to publish to npm:
{
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
A similar configuration works for private packages published on GitHub Packages:
{
"publishConfig": {
"access": "restricted",
"registry": "https://npm.pkg.github.com/"
}
}
The workflow just uses bun publish
, so you can use the same configuration you'd use for yarn
or pnpm
.
Here's how I release packages now:
bun changeset
The beauty is that what I test locally with workspace:*
references is exactly what gets published to npm, just with resolved version numbers.
This workaround has been working reliably for my monorepo. While I'm looking forward to first-class support (tracked here), this solution gets the job done today.
The key takeaway: always run bun update
after changeset version
to fix the lockfile, and use bun publish
directly for each package. This combination ensures workspace references are properly resolved during publishing.
If you're struggling with the same issue, check out my style-guide repo for a working example. The approach has eliminated all the workspace reference issues I was experiencing, and my packages now publish reliably with properly resolved dependencies.
Thanks for reading! Have any questions, comments, or suggestions? Feel free to use the comment section below or email me at [email protected] and I'll do my best to respond.
Alternatively, you can view the source of the post here and send a pull request.