Bun v0.5.7 introduces FormData
support, git
dependencies, and AbortSignal
with fetch()
, setTimeout()
is now more compatible with Node.js, bun wiptest
is now bun test
— with pretty-printed diffs! — and improved support on AWS Lambda and GitHub Actions.
# Install using curl
curl -fsSL https://bun.sh/install | bash
# Install using npm
# npm install -g bun
# Upgrade
bun upgrade
FormData
support
Bun now supports FormData
, a standard Web API for working with form fields and files in multipart uploads. You can add a string
as a field or a Blob
as a file.
const formData = new FormData();
formData.set("attachment-id", crypto.randomUUID());
formData.set("attachment", Bun.file("./package.json"));
const response = await fetch("https://example.com/upload", {
method: "POST",
body: formData,
});
You can also parse FormData
from a Request
or Response
.
export default {
async fetch(request: Request): Promise<Response> {
const formData = await request.formData();
const file = formData.get("attachment");
// ...
return new Response(file);
},
};
In Bun, response.formData()
runs:
- 25x faster than Node v19.6.0
- 4x faster than Deno v1.30.3
Git dependencies
Bun now supports git
dependencies in package.json
. Bun accepts a variety of git dependency formats, including github
, git
, git+ssh
, git+https
, and many more.
{
"dependencies": {
"zod": "github:colinhacks/zod",
"lodash": "git@github.com:lodash/lodash.git#4.17.21"
}
}
You can also add a git
dependency using bun install
.
bun install git@github.com:moment/moment.git
Changes to setTimeout()
The Web standard setTimeout()
returns a number
, which represents a timeout ID. The Node.js implementation of setTimeout()
returns a Timeout
object, which has methods like ref()
and unref()
, but is coercable to a number
.
We (reluctantly) decided to change Bun's implementation to match Node.js because there are many npm
packages that depend on this legacy behaviour.
const timeout = setTimeout(() => {
process.abort(); // this is not called, see `unref()` below
}, 1000);
timeout.unref();
// For compatibility, it still works as a number
const timeoutId = +timeout; // 1
We also improved the console.log()
formatting of the Timeout
object.
AbortSignal
with fetch()
You can now cancel a fetch()
request using an AbortSignal
. This is useful for timeouts or when you need to cancel a request before a response is received.
await fetch("https://example.com", {
// Abort if the response is not received after 1 second
signal: AbortSignal.timeout(1000),
});
You can also use an AbortSignal
when receiving a Request
from the HTTP server.
export default {
async fetch(request: Request): Promise<Response> {
request.signal.addEventListener("abort", () => {
console.log("Client aborted the request");
});
// ...
return new Response();
},
};
bun wiptest
is now bun test
It's time for bun wiptest
to graduate to bun test
.
Pretty-printed diffs
bun test
now supports pretty-printed diffs, thanks to @dylan-conway for implementing and @SuperAuguste for porting the diff-match-patch algorithm to Zig.
Now:
error: expect(received).toEqual(expected)
{
abc: 123,
+ def: 456
- def: 789
}
- Expected - 1
+ Received + 1
Before:
error: Expected values to be equal:
Expected: {
abc: 123,
def: 789
}
Received: {
abc: 123,
def: 456
}
Auto-import for jest
globals
bun test
now automatically imports test()
and expect()
. This also works for the other Jest globals, including: describe
, beforeAll
, afterAll
, and more.
// import { test, expect } from "bun:test";
test("that it auto-imports expect()", () => {
expect({
abc: 123,
def: 456,
}).toEqual({
abc: 123,
def: 789,
});
});
We still recommended that you import from bun:test
, but if you have existing tests using Jest, you probably rely on its globals.
New methods on Set
The Set
class now has more built-in methods, thanks to @kmiller68 at WebKit.
const a = new Set([1, 2, 3]);
const b = new Set([1, 3, 4, 5]);
const c = new Set([1, 3]);
console.log(a.union(b)); // [1, 2, 3, 4, 5]
console.log(a.intersection(b)); // [1, 3]
console.log(a.difference(b)); // [2]
console.log(a.symmetricDifference(b)); // [2, 4, 5]
AWS Lambda support
Bun can now run AWS Lambda using a custom layer.
The layer will detect when an event is an HTTP request and transform it into a standard Request
. This means you can test your Lambda locally using bun run
, without any code changes.
export default {
async fetch(request: Request): Promise<Response> {
console.log(request.headers.get("x-amzn-function-arn"));
// ...
return new Response("Hello from Lambda!", {
status: 200,
headers: {
"Content-Type": "text/plain",
},
});
},
};
For events that are not HTTP requests, like a S3 or SQS trigger, the event will be in the body of the Request
.
export default {
async fetch(request: Request): Promise<Response> {
const event = await request.json();
// ...
return new Response();
},
};
GitHub Action support
There is a new release of the setup-bun
GitHub Action, which you can also find on the GitHub Marketplace. Thanks to @xHyroM for maintaining the initial version of it.
- uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- uses: oven-sh/setup-bun@v1
with:
bun-version: "0.5.7"
Now, with the newly added support for git
dependencies, we encourage you to try this out in your GitHub CI and see much time you can save with bun install
.
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
+ - uses: oven-sh/setup-bun@v1
+ with:
+ bun-version: latest
+ - run: bun install
- - run: npm install
Changelog
523b112 | Added auto-import for jest globals in bun test by @Jarred-Sumner |
#2029 | Fixed fs.createWriteStream() from exiting early by @alexlamsl |
995880a | Enabled more Set methods by @Jarred-Sumner |
#2039 | Fixed "Duplicate dependency" error for peerDependencies by @alexlamsl |
#2044 | Fixed incorrect build instructions for macOS by @ekzhang |
#2041 | Fixed syntax error when regex was present in package.json by @jwhear |
675529b | Fixed a bug where Buffer was not assignable by @Jarred-Sumner |
#2054 | Implemented napi_fatal_exception by @ThatOneBro |
#2045 | Fixed bun install crash during non-install script execution by @alexlamsl |
83473c6 | Defined a fallback for globalPaths in require("module") by @Jarred-Sumner |
#2057 | Fixed a bug where server.listen() did not return the server by @michalwarda |
bb2aaa3 | Enabled release signing by @Electroid |
#2059 | Implemented git://github.com dependencies by @alexlamsl |
#2051 | Implemented FormData by @Jarred-Sumner |
0db8cdf | Fixed fetch() not sending a default Content-Type header by @Jarred-Sumner |
#2061 | Implemented napi_get_value_bigint_words by @ThatOneBro |
#2062 | Allowed { port: 0 } in Bun.serve() to use a random port by @michalwarda |
37186f4 | Improved console.log() output for FormData by @Jarred-Sumner |
#2047 | Disallowed bodies when fetch() method is GET, HEAD, or OPTIONS by @ekzhang |
#1798 | Exported fs.ReadStream and fs.WriteStream by @ThatOneBro |
#2074 | Improved validation of package.json by @alexlamsl |
4dc6bf1 | Added workarounds for node:tls and node:worker_threads by @Jarred-Sumner |
#2076 | Fixed a bug where network-delayed .bin scripts were not installed by @alexlamsl |
f19e3d6 | Added a workaround for node:async_hooks by @Jarred-Sumner |
#1971 | Implemented ED25519 for WebCrypto by @Jarred-Sumner with thanks to @panva |
0d7cea6 | Added a workaround for eval("__dirname") by @Jarred-Sumner |
1125728 | Fixed bugs with napi_create_threadsafe_function by @Jarred-Sumner |
#2087 | Improved documentation to build on macOS by @controversial |
#2089 | Fixed writeFileSync({ flag: undefined }) from not working by @jwhear |
#2088 | Implemented os.machine() for Linux by @jwhear |
#2086 | Supported yarn -like workspaces by @Jarred-Sumner |
56b75db | Implemented faster Buffer.byteLength("latin1") by @Jarred-Sumner |
#2095 | Fixed bun add of packages with capital letters by @alexlamsl |
#2096 | Fixed String.replace() with non-ASCII characters by @jwhear |
#2094 | Supported git dependencies by @alexlamsl |
#2066 | Fixed a crash with invalid encoding in fetch() headers by @jwhear |
1106c8e | Fixed parsing of fs flags by @Jarred-Sumner |
#1378 | Implemented os.machine() for macOS by @sno2 |
#2104 | Fixed a change in how URLs are printed by @MichaReiser |
c006a7f | Load .env.production when NODE_ENV=production by @Jarred-Sumner |
#2122 | Added a pretty string differ to bun test by @dylan-conway |
#2124 | Supported git dependencies by @alexlamsl |
#2009 | Implemented a runtime layer for Bun on AWS Lambda by @Electroid |
#2128 | Fixed output in child_process.exec() by @ThatOneBro |
#2131 | Renamed bun wiptest to bun test by @dylan-conway |
#2126 | Fixed glibc error in alpine Docker image by @WebReflection |
#2135 | Improved various types for bun-types by @colinhacks |
2a1558e | Supported Node.js-style setTimeout() by @Jarred-Sumner |
#2097 | Supported AbortSignal in fetch() by @cirospaciari |