bun
bun copied to clipboard
Vite
Vite is on Bun's roadmap, which is awesome.
I'm opening this issue to track progress on Vite support.
A lot of Vite folks would gladly replace Node.js with Bun :-).
Edit
Shameless plug: myself and @cyco130 are the authors of:
- HatTip - a modern Express.js alternative: Fetch API / WinterCG standards + works anywhere (Node.js Edge, Deno, and Bun — of course 🙂).
- vite-plugin-ssr - Like Next.js / Nuxt but as do-one-thing-do-it-well Vite plugin. (The production runtime works with Bun.)
Tried Bun with Vite this weekend at https://github.com/bluwy/bun-vite-ts-test. Noted down some issues so far in the readme, with a patch to fix any fixable things so far. Currently stucked but I'll be watching Bun's releases and keep it up to date.
It's happening: https://twitter.com/jarredsumner/status/1551643885998247938.
As of Bun v0.1.11 (released today), here is the current status of the list of items mentioned in https://github.com/bluwy/bun-vite-ts-test
- [ ] http, http2, https not implemented.
The server parts of http are partially implemented - enough for express to work. http2 and https aren't implemented at all yet
- [x]
child_processnot implemented. Blocks esbuild.
- [x] Regex negative lookbehind not supported in JSC. PITA to refactor.
This one is tricky. It's probably the biggest JSC-specific compatibility issue I've seen. We may need to have some WASM or ffi thing inserted by the transpiler to workaround it until https://bugs.webkit.org/show_bug.cgi?id=174931 is resolved, or attempt to implement it ourselves
- [x] When
const require = createRequire()exists, bun treats the file as CJS, transpiling imports torequire(), but becauseconst requireis declared late, it givesReferenceError: Cannot access uninitialized variable. Can be workaround by avoidingrequireand rename as_require. https://github.com/oven-sh/bun/issues/453
- [ ] Dynamic
import()doesn't execute file, as if a no-op.
I'm not 100% sure what is happening in this case, but maybe it's a CommonJS module being dynamically imported? Normally, Bun's transpiler automatically calls .default() on CommonJS modules to initialize them, but it doesn't always do that for dynamic import currently.
- [ ] ESM imports aren't hoisted.
Can you point to something that shows what this breaks? Sometimes people might use dynamic imports for lazy loading
- [x]
process.stdoutnot implemented. - [x]
path.posixnot implemented. Can be polyfilled withpath.posix = pathbut works with posix env only. - [x]
fileUrlToPathdoesn't acceptfile://strings. Can be fixed by wrappingnew URL(<string>). - [x]
createRequiredoesn't work correctly withfile://strings. URL however works correctly, and can be fixed by wrappingnew URL(<string>). - [ ]
processassignment likeprocess.env.NODE_ENV = '<string>'shouldn't be replaced. Can be workaround by wrappingeval().
- [x]
performanceandperf_hooksnot implemented. Can be polyfilled withglobalThis.performance.
This is partially implemented, performance.now() exists but not performance.mark(), performance.measure(), nor the other Node-specific functions (they throw a not implemented error)
- [x]
selfnot implemented. Can be polyfilled withglobalThis.self = globalThis. - [ ]
readlinenot implemented.
- [ ] Dynamic
import()doesn't execute file, as if a no-op.I'm not 100% sure what is happening in this case, but maybe it's a CommonJS module being dynamically imported? Normally, Bun's transpiler automatically calls .default() on CommonJS modules to initialize them, but it doesn't always do that for dynamic import currently.
It's referring to this line where it's dynamically importing a file that should invoke and interpret the CLI args immediately to run the commands. Last I tested, dynamically importing it doesn't cause anything to happen. I had to do import '../dist/node/cli.js' at the top level instead to invoke it.
- [ ] ESM imports aren't hoisted.
Can you point to something that shows what this breaks? Sometimes people might use dynamic imports for lazy loading
I don't remember where I saw this, but here's an example. This might be a rare and lower-priority case.
I haven't had the time to update https://github.com/bluwy/bun-vite-ts-test but thanks for keeping up with the improvements!
Really looking forward to this as it's a perfect fit for Wails: https://github.com/wailsapp/wails How can someone who doesn't know Zig (yet) help with this? Would love to help out.
In canary (bun v0.5.1), Vite's dev server can start with some tweaks and load some files. Overall: it doesn't work yet, but we are getting close.

There is an issue preventing Vite's transform step from working consistently so files that need to be transpiled are not always transpiled. Specifically, the define plugin doesn't seem to work. It also has an issue loading the config file, but that's easy to work around since you can import typescript files in bun's runtime
My current hunch is a bug somewhere in path handling code in Bun. But I don't know yet
Some logs (the lines in [bracket] are internal debug logs in Bun)
[bun] poll(2) writable: true (4)
vite:resolve 0.16ms /Users/jarred/Build/new-vite/vite-project/node_modules/vite/dist/client/env.mjs -> null +9ms
[SYS] write(2, 176) = 176
[FileSink] Wrote 176 bytes (fd: 2, head: 0, 0/11769)
[bun] poll(2) writable: true (4)
vite:resolve 0.28ms @vite/env -> /Users/jarred/Build/new-vite/vite-project/node_modules/vite/dist/client/env.mjs +0ms
[SYS] write(2, 181) = 181
[FileSink] Wrote 181 bytes (fd: 2, head: 0, 0/11950)
[bun] poll(2) writable: true (4)
vite:resolve 0.04ms /node_modules/vite/dist/client/env.mjs -> null +0ms
[SYS] write(2, 135) = 135
[FileSink] Wrote 135 bytes (fd: 2, head: 0, 0/12085)
[bun] poll(2) writable: true (4)
vite:import-analysis 1.61ms [1 imports rewritten] node_modules/vite/dist/client/client.mjs +5ms
[SYS] write(2, 160) = 160
[FileSink] Wrote 160 bytes (fd: 2, head: 0, 0/12245)
[bun] poll(2) writable: true (4)
vite:transform 17.95ms /@vite/client +5ms
[SYS] write(2, 93) = 93
[FileSink] Wrote 93 bytes (fd: 2, head: 0, 0/12338)
[bun] poll(2) writable: true (4)
vite:time 22.58ms /@vite/client +5ms
[SYS] write(2, 88) = 88
[FileSink] Wrote 88 bytes (fd: 2, head: 0, 0/12426)
[Server] deinitIfWeCan
[SYS] open(/node_modules/vite/dist/client/env.mjs): -1
Failed to load url /node_modules/vite/dist/client/env.mjs (resolved id: /node_modules/vite/dist/client/env.mjs). Does the file exist?
[Loop] unref x 2
[SYS] open(/node_modules/vite/dist/client/env.mjs): -1
[SYS] stat(/Users/jarred/Build/new-vite/vite-project/node_modules/vite/dist/client/env.mjs) = 0
[bun] poll(2) writable: true (4)
vite:time 1.17ms /node_modules/vite/dist/client/env.mjs +4ms
[SYS] write(2, 112) = 112
[FileSink] Wrote 112 bytes (fd: 2, head: 0, 0/12538)
[Server] deinitIfWeCan
[SYS] stat(/Users/jarred/Build/new-vite/vite-project/node_modules/vite/dist/client/env.mjs.map) = 0
[SYS] open(/Users/jarred/Build/new-vite/vite-project/node_modules/vite/dist/client/env.mjs.map): 123
n @ fs.ReadStream.#internalRead, after clamp 65536
[SYS] fstat(124) = 0
[SYS] read(124, 65536) = 1797 (0.009ms)
n @ fs.ReadStream.#internalRead, after clamp 65536
[bun] poll(2) writable: true (4)
vite:time 2.41ms /node_modules/vite/dist/client/env.mjs.map +7ms
[SYS] write(2, 116) = 116
[FileSink] Wrote 116 bytes (fd: 2, head: 0, 0/12654)
[SYS] close(124)
[Server] deinitIfWeCan
[SYS] stat(/Users/jarred/Build/new-vite/vite-project/public/vite.svg) = 0
[SYS] open(/Users/jarred/Build/new-vite/vite-project/public): 124
[SYS] close(124)
[bun] poll(2) writable: true (4)
vite:time 0.34ms /vite.svg +2ms
[SYS] write(2, 83) = 83
[FileSink] Wrote 83 bytes (fd: 2, head: 0, 0/12737)
[Server] deinitIfWeCan
[bun] poll(2) writable: true (4)
vite:html-fallback Rewriting GET / to /index.html +47s
My current hunch is a bug somewhere in path handling code in Bun. But I don't know yet
When trying to make Rakkas (a Vite-based React metaframework) run on Deno, I encountered a similar problem. My current workaround is a small plugin to help Vite resolve its client and env entries.
Vite tries to resolve their full path based on the location of its package.json file which it computes using import.meta.url. Any incompatibility with the exact paths causes it to miss them. In Deno, it's because of how it links packages: import.meta.url doesn't return the same string as Vite's resolver does so it needs a hand from my little plugin.
Just my two cents, maybe it's related.
How does the move towards SWC in Vite 4.0 affect bun support?
How does the move towards SWC in Vite 4.0 affect bun support?
Just to be clear, Vite 4.0 isn't moving to SWC, it's the React plugin that now has an alternative version using SWC. In any case, you can always fallback to the slower Babel version if it doesn't work.
Any news here?
Any news here?
There's still some bugs preventing Vite from fully working, however we are working on stabilizing our Node APIs currently and it may end up working after some more big fixes we're working on. Stay tuned
I think it's important for Vite to not only work in Bun (it doesn't yet), but to be faster in Bun than other runtimes.
One of the reasons why we are building a new bundler (https://github.com/oven-sh/bun/pull/2312) is to help make that happen.
Sorry folks, I couldn't find better issue to fit this into...
Edited: created a new issue. My apologies.
I couldn't find better issue to fit this into
@pooledge you should open a new issue or discussion; this issue is tracking general support for Vite
The vite dev server is close to working. Here are the known blockers:
- #832 (for any hmr to work)
- #3216 (breaks loading config files)
For using SvelteKit on top of this I've also found:
- #3225
I'm sure there will be a few more bugs after fs.watch is implemented, as the bulk of a dev server is in it's ability to re-build code.
Also, for what it's worth, running an http stress test on the dev server shows Bun can handle 1.9x as many requests on average compared to node. This isn't really that significant because stress testing a dev server is pretty useless, but hey... it's there.
Would be nice if this comes in at v1.0 @Jarred-Sumner
Would be nice if this comes in at v1.0 @Jarred-Sumner
how about tomorrow in Bun v0.7? https://github.com/vitejs/vite/pull/13901
💯 Very much looking forward to it, especially if it solves the countless ESM-CJS compatibility issues (it's a massive pain for users). Looking forward to a bright Bun + Vike (upcoming vite-plugin-ssr rebrand) future.
It seems like require('u' + 'rl') in Vite breaks when trying to run SolidStart with the latest canary 0.7.
Error: Cannot find package "u" from [...]/vite/dist/node-cjs/publicUtils.cjs
I reported #3705 but am unsure if this is a Bun or Vite issue. It may even be a duplicate, if so, apologies.
I reported #3705 but am unsure if this is a Bun or Vite issue. It may even be a duplicate, if so, apologies. It seems like
require('u' + 'rl')in Vite breaks when trying to run SolidStart with the latest canary 0.7.Error:
Cannot find package "u" from [...]/vite/dist/node-cjs/publicUtils.cjs
Both of these should be fixed in canary (please leave a comment if you see that still)
The current blockers for SolidStart:
- Dependency on node's --experiemntal-vm-modules flag
- Event loop bug causing the process to exit prematurely while loading
es-module-loader
I can confirm that for SolidStart (0.2.27, released some hours ago) instead of an error, it now just exit early as you say, using either node / bun adapter. @Jarred-Sumner , am I right to assume both of these issues requires changes to SolidStart rather than Bun?
I just updated to latest canary. Looks like the problem persists.
Vite support has been landed in 0.7, closing this issue. Note that you need the latest version of Vite as there was a small patch in their code to fix WebSocket/HMR.
SvelteKit does not work due to worker_threads not being implemented.
🎉🎉
We'll be tracking SvelteKit specific support in #600, and SolidStart in #3736.
Please open a separate issue (if it doesnt exist) for other frameworks.
Can we have some love for parcel??
if it doesn't work, make a new issue
I’m so happy we shipped this
Can't wait for a rock-solid Bun ⛰️