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 fasterProxy
andarguments
.v0.6.3
- Implementednode:vm
, lots of fixes tonode:http
andnode: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 test
improvements, 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 atoMatchObject
expect matcher. Plus an experimentalinspector
mode 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 -fsSL https://bun.sh/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
To upgrade Bun:
bun upgrade
Bun.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.
bun run 👋.js
error: FileNotFound reading "/Users/jarred/Desktop/ð.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 |