We're hiring C/C++ and Zig engineers to build the future of JavaScript! Join our team →
We've been releasing a lot of changes to Bun recently, here's a recap in case you missed it:
v0.6.0- Introducingbun build, Bun's new JavaScript bundler.v0.6.2- Performance boosts: 20% fasterJSON.parse, up to 2x fasterProxyandarguments.v0.6.3- Implementednode:vm, lots of fixes tonode:httpandnode:tls.v0.6.4- Implementedrequire.cache,process.env.TZ, and 80% fasterbun test.v0.6.5- Native support for CommonJS modules (previously, Bun did CJS to ESM transpilation),v0.6.6-bun testimprovements, including Github Actions support,test.only(),test.if(),describe.skip(), and 15+ moreexpect()matchers; also streaming file uploads usingfetch().v0.6.7- Node.js compatibility improvements to unblock Discord.js, Prisma, and Puppeteerv0.6.8- IntroducedBun.password, mocking inbun test, andtoMatchObject()v0.6.9- Less memory usage and support for non-ascii filenamesv0.6.10-fs.watch(),bun installbug fixes,bun testfeatures, and improved CommonJS supportv0.6.11- address a release build issue fromv0.6.10
This release makes it easier to read runtime errors, improves Node.js compatiblity, adds await Bun.file(path).exists(), fixes bundler bugs and slightly reduces minifier output size.
To install Bun:
curl -fsSL https://bun.sh/install | bashnpm install -g bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bunTo upgrade Bun:
bun upgradeBetter runtime errors
We've made several improvements to runtime errors in Bun:
- Patched JavaScriptCore to allow Bun to print
Error.prototype.stackin the same style as V8. - Stack traces show fewer internal builtin functions
console.error(error)now includes indirect function names, such aslet foo = function() {}will now showfooinstead ofanonymousError.captureStackTrace(err)'serr.stackproperty is no longer marked as read-only (this was incorrect)Error.prototype.stackis now automatically sourcemapped.
Bun transpiles every file in the runtime. Before this release, error.stack would show the stack for the transpiled source, which was not very useful. Now, error.stack shows the stack for the original source, following an internal sourcemap generated for each file.
The output of console.log(error.stack) after:
Error: hello!
at hey (error.js:1:29)
at module code (error.js:4:16)
The output of console.log(error.stack) before:
hey@error.js:1:29
module code@error.js:4:16
evaluate@[native code]
moduleEvaluation@[native code]
moduleEvaluation@[native code]
@[native code]
asyncFunctionResume@[native code]
promiseReactionJobWithoutPromise@[native code]
promiseReactionJob@[native code]
Input:
function hey() {
return new Error("hello!").stack;
}
console.log(hey());
In the next version of Bun
— Jarred Sumner (@jarredsumner) June 28, 2023
error.stack is formatted like in node/V8 and automatically sourcemapped. pic.twitter.com/BQ3uSVTloy
Improvements to CommonJS <> ES Module interop
When using require to load an ES Module at runtime, Bun now inserts the __esModule annotation which many npm packages transpiled with Babel need in order to work correctly. This fixed a bug with using @mui/styled-engine with bun test.
package.json "module" field is no longer used in Bun's runtime
Bundlers use the "module" field in package.json with a higher priority over the "main" field when bundling ES Modules, but Node.js does not use the "module" field at all.
Previously, Bun used the "module" at runtime (when package.json "exports" wasn't in use) similar to how bundlers use it, but this caused some packages to load the browser version of their code in Bun and Node.js versions in Node.
Bun's bundler continues to support the "module" field when building for browsers, but to improve Node.js compatibility, Bun's runtime no longer uses the "module" field.
SQLite3 Full-text search is enabled
In the next version of Bun
— Jarred Sumner (@jarredsumner) June 28, 2023
You can use full text search with sqlite (via fts5), thanks to @ItsRedraskal pic.twitter.com/NCP8BezEmQ
Bun.file(path).exists()
Bun.file(path).exists() is a new method that returns a boolean indicating whether a file exists at the given path.
import { file, write } from "bun";
console.log(await file("hello.txt").exists()); // false
await write("hello.txt", "hello world");
console.log(await file("hello.txt").exists()); // true
Node.js compatibility improvements
Several bugfixes to node:http and node:stream have landed
Google Maps works
The @googlemaps/google-maps-services-js package now works in Bun, thanks to @dylan-conway fixing a bug in our node:http implmenetation where properties were marked as read only that shouldn't have been marked as read-only.
import { Client } from "@googlemaps/google-maps-services-js";
const client = new Client({});
client
.elevation({
params: {
locations: [{ lat: 45, lng: -110 }],
key: "asdf",
},
timeout: 1000, // milliseconds
})
.then((r) => {
console.log(r.data.results[0].elevation);
})
.catch((e) => {
console.log(e.response.data.error_message);
});
ytdl-core now works
The ytdl-core package now works in Bun, thanks to @paperclover fixing a couple bugs in our node:http and node:stream implementations:
import { createWriteStream } from "fs";
import ytdl from "ytdl-core";
ytdl("https://www.youtube.com/watch?v=dQw4w9WgXcQ").pipe(
createWriteStream("secret-video-do-not-download.mp4"),
);
Minifier improvements
Bun's minifier now minifies obj["a"] into obj.a and obj["a"] = 1 into obj.a = 1.
Build:
bun build --minify ./input.js`Input:
const obj = {};
obj["a"] = 1;
After:
const obj = {};
obj.a = 1;
Before:
const obj = {};
obj["a"] = 1;
This yields a 0.02% reduction in bundle size for vue and potentially a little faster at runtime (engines implement computed property accesses differently than regular property accesses).
Bundler bugfixes
A bug where two consecutive files that re-export another file using CommonJS module.exports = require() would produce invalid code has been fixed
// a.js
module.exports = require("./b");
// b.js
module.exports = require("./c");
// c.js
module.exports = {};
- In certain cases, Bun's CommonJS -> ES Module transform in the bundler would inject
exports.foo = undefinedand that caused some packages which used Object prototype methods to throw an error and it bloated the code. This has been fixed.
More bugfixes
- A regression breaking macros has been fixed
- The
resolve6export in dns/promises was missing - The
errorMonitorexport innode:eventswas missing