The error, verbatim
Jump to the fix ↓error: Cannot find module '@mono/ui' from 'D:\nk-repro\bun-cnf\e-mono\apps\web\index.ts'
Bun v1.4.2 (Windows x64)
Tested on
- Bun
- 1.4.2 (latest)
- OS
- Windows 11 Pro, and Linux (node:24 Docker image)
- Node / TypeScript
- 24.14.0 / 5.9.3 and 7.0.2
✓ Re-verified on bun 1.4.2 (Linux + Windows): 16/16 checks still hold · results
Contents
Bun uses one message, error: Cannot find module '<name>' from '<file>', for very different problems: a workspace package it hid on purpose, a test alias it never read, a JSX runtime you didn’t install. The message doesn’t tell you which one you have.
I reproduced each case on Bun 1.4.2 in a clean project, on Windows 11 and on Linux. Find yours in the table, then jump to its section.
| You’re doing this | What Bun prints | Case |
|---|---|---|
| Importing a workspace package in a monorepo | Cannot find module '@mono/ui' |
1 |
| Importing a package another workspace package depends on | Cannot find package 'ms' |
1 |
bun test with a path alias (~/, @/) |
Cannot find module '~/lib/math' |
2 |
Running a .tsx or .jsx file |
Cannot find module 'react/jsx-dev-runtime' |
3 |
Using bun:sqlite or import { $ } from 'bun' |
Cannot find module 'bun:sqlite', or TS2307 in your editor |
4 |
| A plain import of a package or file | Cannot find package 'lodash' or Cannot find module './nope' |
5 |
| Code that works on Windows or macOS, fails in Docker or CI | ENOENT reading "/tmp/b/utils.ts" |
6 |
1. Monorepo and workspace packages
This is the case most people hit after moving a monorepo to Bun, and it comes from a default that changed. A new Bun workspace now installs with the isolated linker: my fresh bun install wrote "configVersion": 1 into bun.lock and linked each workspace package only into the node_modules of the packages that declare it. Nothing was hoisted to the root node_modules.
So an app can no longer import a package just because it happens to be in the repo, and it can no longer borrow a dependency that only a sibling package declares. Both worked with npm’s hoisting:
$ cd apps/web && bun run index.ts
error: Cannot find module '@mono/ui' from 'D:\nk-repro\bun-cnf\e-mono\apps\web\index.ts'
$ bun run phantom.ts
error: Cannot find package 'ms' from 'D:\nk-repro\bun-cnf\e-mono\apps\web\phantom.ts'
The second one is the sneaky one: ms was installed, but only packages/ui listed it.
Declare what each package imports, in that package’s own package.json:
cd apps/web
bun add @mono/ui@workspace:*
bun add msIf you’d rather keep the old behaviour while you sort out the missing declarations, switch the linker back in bunfig.toml at the repo root, then delete node_modules and bun.lock and reinstall:
[install]
linker = "hoisted"The same Cannot find module '@mono/ui' also appears when the package is declared but its package.json points main at a build folder that doesn’t exist yet ("main": "dist/index.js" before you’ve built it). Bun found the package, then found nothing to load.
Either build the package first, or point Bun at the source with an exports condition, which Bun reads before default:
{
"name": "@mono/ui",
"exports": {
".": {
"bun": "./src/index.ts",
"types": "./src/index.ts",
"default": "./dist/index.js"
}
}
}2. bun test and path aliases
If you’re moving tests from Jest, your aliases probably live in Jest’s moduleNameMapper. bun test doesn’t read Jest config, so the alias doesn’t exist:
$ bun test
tests\alias.test.ts:
# Unhandled error between tests
error: Cannot find module '~/lib/math' from 'D:\nk-repro\bun-cnf\f-test\tests\alias.test.ts'
Bun reads path aliases from tsconfig.json. Move the alias there:
{
"compilerOptions": {
"paths": { "~/*": ["./src/*"] }
}
}The Vitest side is not a problem: a test that imports describe, it and expect from "vitest" passed under bun test with Vitest not installed at all, because Bun handles that import itself.
3. react/jsx-dev-runtime
Bun compiles JSX for you, and the compiled code imports React’s JSX runtime. In a project with no React installed, a two-line .tsx file fails before it runs:
$ bun run index.tsx
error: Cannot find module 'react/jsx-dev-runtime' from 'D:\nk-repro\bun-cnf\c-jsx\index.tsx'
The name changes with the setup. With NODE_ENV=production it’s react/jsx-runtime. With "jsxImportSource": "preact" in tsconfig.json it’s preact/jsx-runtime.
Install the library the error names:
bun add react # or: bun add preact, for preact/jsx-runtimeIf you aren’t using React at all, check jsxImportSource in your tsconfig.json. It decides which package the error asks for.
4. bun:sqlite and ‘bun’ imports outside Bun
bun:sqlite, bun:test and import { $ } from 'bun' only exist inside the Bun runtime. Run the same file with anything else and it fails. These are the messages I got:
| Ran with | Message |
|---|---|
node (ES module) |
ERR_UNSUPPORTED_ESM_URL_SCHEME … Received protocol 'bun:' |
node (CommonJS) |
Error: Cannot find module 'bun:sqlite' |
node, importing 'bun' |
Cannot find package 'bun' imported from D:\tmp\h2\shell.js |
tsx |
ERR_UNSUPPORTED_ESM_URL_SCHEME, same as Node |
tsc / your editor |
TS2307: Cannot find module 'bun:sqlite' or its corresponding type declarations. |
The TypeScript one is only about types: the code runs fine under Bun.
For the editor and tsc error, install Bun’s types:
bun add -d @types/bunFor the runtime errors, the code has to run under Bun. That’s easy to get wrong with bun run dev: if the script calls a tool whose launcher starts with #!/usr/bin/env node (Next.js, Vite and most CLIs do), Bun respects that line and runs the tool in Node. Any bun:sqlite import inside it fails, even though you typed bun.
Bun has a flag for this, --bun, and on Windows it has a catch I had to track down: it only works when bun.exe is on the same drive as your temp folder. With --bun, Bun puts a stand-in node.exe in %TEMP%un-node-<revision> and links it to its own bun.exe. Windows can’t make that kind of link across drives, and Bun carries on silently with the real Node. That’s exactly the setup you get with Bun installed as a project dependency (npm i -D bun) in a project on D: while %TEMP% is on C:. There, even a script that was literally node -e "console.log(typeof Bun)" printed undefined. The same root cause is reported upstream as oven-sh/bun#44033, where it shows up loudly as bun: command not found: node on machines without Node. With Node installed, it fails silently instead. A fix (#44058) was still unmerged on October 8, 2026, and this check is re-run nightly, so this section will change when it ships.
Force Bun with --bun:
bun --bun run devIf bun.exe is on a different drive from %TEMP%, bun --bun run dev, bun run --bun dev and [run] bun = true in bunfig.toml all still ran the tool in Node. Either put the flag inside the script itself:
{
"scripts": {
"dev": "bun --bun next dev"
}
}Or point your temp folder at Bun’s drive, for that terminal:
$env:TEMP = "D: mp"; $env:TMP = "D: mp"Bun’s official Windows installer puts bun.exe in your user folder on C:, the same drive as %TEMP%, so that install doesn’t hit this.
5. A package or file that isn’t there
The plain cases, for completeness. Note the different wording: a bare package name says package, a path says module.
This is also why the error can seem random. In a folder with no node_modules anywhere above it, Bun auto-installs missing packages: the same lodash import, and the JSX file from case 3, ran fine there, because Bun downloaded the package on the fly. As soon as the project has a node_modules folder (any project after its first bun install), auto-install switches off and you get the error instead. A script that worked in a scratch folder can fail once it’s moved into a project.
error: Cannot find package 'lodash' from 'D:\nk-repro\bun-cnf\a-missing-pkg\index.ts'
error: Cannot find module './nope' from 'D:\nk-repro\bun-cnf\b-relative\missing.ts'
For a package, install it: bun add lodash, or bun install if it’s already in package.json. For a path, check the spelling against the file on disk, including its case (see the next section).
6. Works locally, fails on Linux
Windows and macOS don’t care about letter case in file names. Linux does. I imported ./utils while the file was Utils.ts. On Windows it ran and printed 3. Copied into the Linux container, Bun didn’t even say “Cannot find module”:
$ bun run index.ts
error: ENOENT reading "/tmp/b/utils.ts"
$ bun build index.ts --outdir out
error: File not found "/tmp/b/utils.ts"
There’s a trap in testing this: when I ran the project from a folder mounted from Windows into Docker, it still worked, because the files were still on Windows’ case-insensitive disk. It only failed once the files were copied into the container. A fresh git clone in CI behaves like the copy.
Make the import match the file name exactly (./Utils), or rename the file. On a case-insensitive disk, Git doesn’t pick up a rename that only changes case, so rename through Git:
git mv Utils.ts utils.tsWhat didn’t work
I didn’t reproduce two searched variants: Cannot find module './cjs/index.cjs' from '' and paths starting with B:/~BUN/root/. Both come from compiled Bun executables (bun build --compile), the format some CLI tools ship in. If you see them from a tool you installed, it’s the tool’s own build, so update it or report it to its maintainers.
How this was tested
Bun 1.4.2 (the latest release, from npm) on Windows 11 Pro with Node 24.14.0, and on Linux in the official node:24 Docker image with Bun 1.4.2 installed from npm. Each case was a fresh folder:
- a two-package workspace (
packages/ui,apps/web) installed with the default linker, then--linker hoistedand thebunfig.tomlsetting - a Jest-style project run with
bun test .tsxfiles with no React, with Preact asjsxImportSource, and withNODE_ENV=productionbun:sqliteand'bun'imports run withnode,tsxandtsc(TypeScript 5.9.3 and 7.0.2)- a local CLI package whose bin starts with
#!/usr/bin/env node, run through package.json scripts with and without--bun, withbun.exeonC:and onD:(%TEMP%onC:), and withTEMPmoved toD: - a wrong-case import, run from a Windows-mounted folder and from a copy inside the container
Every message above was copied from those runs on October 8, 2026. These checks are re-run automatically against the newest Bun, on Windows and Linux; the date of the last run is shown at the top of this post.
The code for every case above is public, so you can run it yourself: bun-cannot-find-module in nk-repro.
— N.K., end of entry No.053