Note
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-Bun.password, function mocking inbun test, and atoMatchObjectexpect matcher. Plus an experimentalinspectormode inBun.serve().
This release reduces Bun's memory usage across the board and fixes bugs in the bundler/transpiler, CommonJS module loading, bun run, and bun install.
To install Bun:
curl
curl -fsSL https://bun.sh/install | bashnpm
npm install -g bunbrew
brew tap oven-sh/bunbrew install bundocker
docker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bunTo upgrade Bun:
bun upgradeBun.serve() uses less memory to send strings#
Bun now supports zero-copy string Response bodies in Bun.serve().
In the next version of Bun
— Jarred Sumner (@jarredsumner) June 11, 2023
Sending strings with Bun's HTTP server uses less memory.
After responding to 1000 requests with a 12 MB string
Bun: 60 MB ram
Deno: 425 MB ram
Node: 1414 MB ram pic.twitter.com/LJ6FdAcWkZ
We've also applied this optimization to Response outside of Bun.serve()
Previously, the following code would clone text twice:
const text = await Bun.file("file.txt").text();
// Copy #1
const response = new Response(text);
// Copy #2
await response.text();Now, it doesn't copy, saving you memory.
Cold bun install uses 50% less memory#
We free more memory in bun install now, reducing memory usage by 50% for cold installs.
In the next version of Bun
— Jarred Sumner (@jarredsumner) June 10, 2023
bun install (cold) uses 2x less memory pic.twitter.com/HePmK3uHUx
Importing modules in Bun's runtime uses less memory#
We've fixed a couple memory leaks in Bun that happened when importing modules in Bun's runtime, and improved our bindings with JavaScriptCore for source code management.
Non-ascii filenames#
Previously, Bun would throw an error when importing a file with a non-ascii filename.
shell
bun run 👋.jserror: FileNotFound reading "/Users/jarred/Desktop/ð.js"👋.js
console.log("hello!");This error was caused by both a printing bug and a bug in Bun's JavaScriptCore bindings when reading import identifier names.
Bugfixes to mocks in bun test#
mockResolvedValue is fixed in bun test now. Previously, mockResolvedValue would appear to do nothing in bun test.
To use mockResolvedValue:
import { mock, test, expect } from "bun:test";
test("hey", async () => {
const fn = mock.mockResolvedValue(1);
expect(fn()).toBeInstanceOf(Promise);
const value = await fn();
expect(value).toBe(1); // 1
});The mock object returned was missing a .bind, .apply, .call, .name, and .length functions. This has been fixed. We've also made it so that the .name of the mocked function is copied over from the original function automatically.
import { mock, test, expect } from "bun:test";
test("hey", async () => {
const hey = mock(function yo() {
return 42;
});
expect(hey.name).toBe("yo");
});Crash in CommonJS require() fixed#
This release fixes a crash that can occur when many CommonJS files are imported and then the garbage collector is run after the files are no longer in use:
import "lodash/omit.js";
import "lodash/findIndex.js";
import "discord.js";
Bun.gc(true);This was a bug in the CommonJS module loader not correctly preventing the function from being garbage collected.
A memory leak in node:crypto has been fixed#
This release fixes a memory leak in node:crypto. The following code would leak about 192 bytes per call.
const crypto = require("crypto");
function sha256(buf) {
return crypto.createHash("sha256").update(buf).digest();
}
async function main() {
for (var i = 1000000; i >= 0; i--) {
const buf = Buffer.alloc(2046);
const hash = sha256(buf);
if (i % 1000 === 0) {
await new Promise((r) => setTimeout(r, 20));
global.gc ? global.gc() : Bun?.gc(true);
}
}
}
main();After:
Before:
Node.js, for comparison:
Changelog#
#3277 | add --save argument to install by @kvakil |
#3292 | handle unwrapping require in any expression by @dylan-conway |
#3286 | Typo in readline by @paperclover |
#3290 | workaround quote escape issues for bun run |