bun-types 1.1.37-canary.20241123T140655 → 1.1.37-canary.20241125T140601
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/api/binary-data.md +1028 -0
- package/docs/api/cc.md +197 -0
- package/docs/api/color.md +262 -0
- package/docs/api/console.md +38 -0
- package/docs/api/dns.md +113 -0
- package/docs/api/fetch.md +308 -0
- package/docs/api/ffi.md +536 -0
- package/docs/api/file-io.md +358 -0
- package/docs/api/file-system-router.md +112 -0
- package/docs/api/file.md +19 -0
- package/docs/api/glob.md +157 -0
- package/docs/api/globals.md +387 -0
- package/docs/api/hashing.md +314 -0
- package/docs/api/html-rewriter.md +31 -0
- package/docs/api/http.md +661 -0
- package/docs/api/import-meta.md +69 -0
- package/docs/api/node-api.md +16 -0
- package/docs/api/semver.md +52 -0
- package/docs/api/spawn.md +441 -0
- package/docs/api/sqlite.md +692 -0
- package/docs/api/streams.md +214 -0
- package/docs/api/tcp.md +221 -0
- package/docs/api/test.md +1 -0
- package/docs/api/transpiler.md +274 -0
- package/docs/api/udp.md +125 -0
- package/docs/api/utils.md +773 -0
- package/docs/api/websockets.md +547 -0
- package/docs/api/workers.md +230 -0
- package/docs/benchmarks.md +120 -0
- package/docs/bun-flavored-toml.md +42 -0
- package/docs/bundler/executables.md +291 -0
- package/docs/bundler/index.md +1543 -0
- package/docs/bundler/intro.md +75 -0
- package/docs/bundler/loaders.md +288 -0
- package/docs/bundler/macros.md +327 -0
- package/docs/bundler/plugins.md +30 -0
- package/docs/bundler/vs-esbuild.md +1127 -0
- package/docs/cli/add.md +163 -0
- package/docs/cli/bun-completions.md +3 -0
- package/docs/cli/bun-create.md +254 -0
- package/docs/cli/bun-dev.md +21 -0
- package/docs/cli/bun-install.md +255 -0
- package/docs/cli/bun-upgrade.md +39 -0
- package/docs/cli/bunx.md +80 -0
- package/docs/cli/filter.md +57 -0
- package/docs/cli/init.md +40 -0
- package/docs/cli/install.md +205 -0
- package/docs/cli/link.md +38 -0
- package/docs/cli/outdated.md +61 -0
- package/docs/cli/patch-commit.md +9 -0
- package/docs/cli/pm.md +150 -0
- package/docs/cli/publish.md +107 -0
- package/docs/cli/remove.md +5 -0
- package/docs/cli/run.md +196 -0
- package/docs/cli/test.md +247 -0
- package/docs/cli/unlink.md +7 -0
- package/docs/cli/update.md +34 -0
- package/docs/contributing/upgrading-webkit.md +57 -0
- package/docs/ecosystem/elysia.md +24 -0
- package/docs/ecosystem/express.md +37 -0
- package/docs/ecosystem/hono.md +18 -0
- package/docs/ecosystem/react.md +65 -0
- package/docs/ecosystem/stric.md +37 -0
- package/docs/guides/binary/arraybuffer-to-array.md +27 -0
- package/docs/guides/binary/arraybuffer-to-blob.md +24 -0
- package/docs/guides/binary/arraybuffer-to-buffer.md +25 -0
- package/docs/guides/binary/arraybuffer-to-string.md +15 -0
- package/docs/guides/binary/arraybuffer-to-typedarray.md +39 -0
- package/docs/guides/binary/blob-to-arraybuffer.md +14 -0
- package/docs/guides/binary/blob-to-dataview.md +14 -0
- package/docs/guides/binary/blob-to-stream.md +14 -0
- package/docs/guides/binary/blob-to-string.md +15 -0
- package/docs/guides/binary/blob-to-typedarray.md +14 -0
- package/docs/guides/binary/buffer-to-arraybuffer.md +14 -0
- package/docs/guides/binary/buffer-to-blob.md +14 -0
- package/docs/guides/binary/buffer-to-readablestream.md +41 -0
- package/docs/guides/binary/buffer-to-string.md +25 -0
- package/docs/guides/binary/buffer-to-typedarray.md +14 -0
- package/docs/guides/binary/dataview-to-string.md +15 -0
- package/docs/guides/binary/typedarray-to-arraybuffer.md +25 -0
- package/docs/guides/binary/typedarray-to-blob.md +16 -0
- package/docs/guides/binary/typedarray-to-buffer.md +14 -0
- package/docs/guides/binary/typedarray-to-dataview.md +14 -0
- package/docs/guides/binary/typedarray-to-readablestream.md +41 -0
- package/docs/guides/binary/typedarray-to-string.md +16 -0
- package/docs/guides/ecosystem/astro.md +72 -0
- package/docs/guides/ecosystem/discordjs.md +77 -0
- package/docs/guides/ecosystem/docker.md +140 -0
- package/docs/guides/ecosystem/drizzle.md +185 -0
- package/docs/guides/ecosystem/edgedb.md +228 -0
- package/docs/guides/ecosystem/elysia.md +31 -0
- package/docs/guides/ecosystem/express.md +40 -0
- package/docs/guides/ecosystem/hono.md +39 -0
- package/docs/guides/ecosystem/mongoose.md +87 -0
- package/docs/guides/ecosystem/neon-drizzle.md +220 -0
- package/docs/guides/ecosystem/neon-serverless-postgres.md +55 -0
- package/docs/guides/ecosystem/nextjs.md +38 -0
- package/docs/guides/ecosystem/nuxt.md +56 -0
- package/docs/guides/ecosystem/pm2.md +57 -0
- package/docs/guides/ecosystem/prisma.md +140 -0
- package/docs/guides/ecosystem/qwik.md +107 -0
- package/docs/guides/ecosystem/react.md +49 -0
- package/docs/guides/ecosystem/remix.md +78 -0
- package/docs/guides/ecosystem/render.md +79 -0
- package/docs/guides/ecosystem/sentry.md +52 -0
- package/docs/guides/ecosystem/solidstart.md +58 -0
- package/docs/guides/ecosystem/ssr-react.md +51 -0
- package/docs/guides/ecosystem/stric.md +55 -0
- package/docs/guides/ecosystem/sveltekit.md +125 -0
- package/docs/guides/ecosystem/systemd.md +113 -0
- package/docs/guides/ecosystem/vite.md +70 -0
- package/docs/guides/http/cluster.md +66 -0
- package/docs/guides/http/fetch-unix.md +33 -0
- package/docs/guides/http/fetch.md +24 -0
- package/docs/guides/http/file-uploads.md +94 -0
- package/docs/guides/http/hot.md +22 -0
- package/docs/guides/http/proxy.md +24 -0
- package/docs/guides/http/server.md +46 -0
- package/docs/guides/http/simple.md +18 -0
- package/docs/guides/http/stream-file.md +48 -0
- package/docs/guides/http/stream-iterator.md +47 -0
- package/docs/guides/http/stream-node-streams-in-bun.md +20 -0
- package/docs/guides/http/tls.md +30 -0
- package/docs/guides/install/add-dev.md +26 -0
- package/docs/guides/install/add-git.md +36 -0
- package/docs/guides/install/add-optional.md +25 -0
- package/docs/guides/install/add-peer.md +17 -0
- package/docs/guides/install/add-tarball.md +33 -0
- package/docs/guides/install/add.md +42 -0
- package/docs/guides/install/azure-artifacts.md +73 -0
- package/docs/guides/install/cicd.md +41 -0
- package/docs/guides/install/custom-registry.md +30 -0
- package/docs/guides/install/from-npm-install-to-bun-install.md +214 -0
- package/docs/guides/install/git-diff-bun-lockfile.md +38 -0
- package/docs/guides/install/jfrog-artifactory.md +28 -0
- package/docs/guides/install/npm-alias.md +23 -0
- package/docs/guides/install/registry-scope.md +36 -0
- package/docs/guides/install/trusted.md +48 -0
- package/docs/guides/install/workspaces.md +70 -0
- package/docs/guides/install/yarnlock.md +42 -0
- package/docs/guides/process/argv.md +57 -0
- package/docs/guides/process/ctrl-c.md +16 -0
- package/docs/guides/process/ipc.md +66 -0
- package/docs/guides/process/nanoseconds.md +13 -0
- package/docs/guides/process/os-signals.md +39 -0
- package/docs/guides/process/spawn-stderr.md +31 -0
- package/docs/guides/process/spawn-stdout.md +26 -0
- package/docs/guides/process/spawn.md +41 -0
- package/docs/guides/process/stdin.md +54 -0
- package/docs/guides/read-file/arraybuffer.md +28 -0
- package/docs/guides/read-file/buffer.md +19 -0
- package/docs/guides/read-file/exists.md +16 -0
- package/docs/guides/read-file/json.md +17 -0
- package/docs/guides/read-file/mime.md +20 -0
- package/docs/guides/read-file/stream.md +26 -0
- package/docs/guides/read-file/string.md +22 -0
- package/docs/guides/read-file/uint8array.md +21 -0
- package/docs/guides/read-file/watch.md +68 -0
- package/docs/guides/runtime/cicd.md +43 -0
- package/docs/guides/runtime/define-constant.md +145 -0
- package/docs/guides/runtime/import-html.md +15 -0
- package/docs/guides/runtime/import-json.md +44 -0
- package/docs/guides/runtime/import-toml.md +30 -0
- package/docs/guides/runtime/read-env.md +32 -0
- package/docs/guides/runtime/set-env.md +37 -0
- package/docs/guides/runtime/shell.md +40 -0
- package/docs/guides/runtime/timezone.md +35 -0
- package/docs/guides/runtime/tsconfig-paths.md +29 -0
- package/docs/guides/runtime/typescript.md +47 -0
- package/docs/guides/runtime/vscode-debugger.md +47 -0
- package/docs/guides/runtime/web-debugger.md +82 -0
- package/docs/guides/streams/node-readable-to-arraybuffer.md +11 -0
- package/docs/guides/streams/node-readable-to-blob.md +11 -0
- package/docs/guides/streams/node-readable-to-json.md +12 -0
- package/docs/guides/streams/node-readable-to-string.md +12 -0
- package/docs/guides/streams/node-readable-to-uint8array.md +11 -0
- package/docs/guides/streams/to-array.md +14 -0
- package/docs/guides/streams/to-arraybuffer.md +14 -0
- package/docs/guides/streams/to-blob.md +14 -0
- package/docs/guides/streams/to-buffer.md +15 -0
- package/docs/guides/streams/to-json.md +14 -0
- package/docs/guides/streams/to-string.md +14 -0
- package/docs/guides/streams/to-typedarray.md +22 -0
- package/docs/guides/test/bail.md +22 -0
- package/docs/guides/test/coverage-threshold.md +60 -0
- package/docs/guides/test/coverage.md +44 -0
- package/docs/guides/test/happy-dom.md +68 -0
- package/docs/guides/test/migrate-from-jest.md +110 -0
- package/docs/guides/test/mock-clock.md +48 -0
- package/docs/guides/test/mock-functions.md +68 -0
- package/docs/guides/test/rerun-each.md +14 -0
- package/docs/guides/test/run-tests.md +111 -0
- package/docs/guides/test/skip-tests.md +39 -0
- package/docs/guides/test/snapshot.md +99 -0
- package/docs/guides/test/spy-on.md +46 -0
- package/docs/guides/test/testing-library.md +87 -0
- package/docs/guides/test/timeout.md +15 -0
- package/docs/guides/test/todo-tests.md +67 -0
- package/docs/guides/test/update-snapshots.md +50 -0
- package/docs/guides/test/watch-mode.md +19 -0
- package/docs/guides/util/base64.md +15 -0
- package/docs/guides/util/deep-equals.md +39 -0
- package/docs/guides/util/deflate.md +18 -0
- package/docs/guides/util/detect-bun.md +23 -0
- package/docs/guides/util/entrypoint.md +17 -0
- package/docs/guides/util/escape-html.md +22 -0
- package/docs/guides/util/file-url-to-path.md +14 -0
- package/docs/guides/util/gzip.md +18 -0
- package/docs/guides/util/hash-a-password.md +54 -0
- package/docs/guides/util/import-meta-dir.md +13 -0
- package/docs/guides/util/import-meta-file.md +13 -0
- package/docs/guides/util/import-meta-path.md +13 -0
- package/docs/guides/util/main.md +32 -0
- package/docs/guides/util/path-to-file-url.md +14 -0
- package/docs/guides/util/sleep.md +22 -0
- package/docs/guides/util/version.md +21 -0
- package/docs/guides/util/which-path-to-executable-bin.md +15 -0
- package/docs/guides/websocket/compression.md +31 -0
- package/docs/guides/websocket/context.md +72 -0
- package/docs/guides/websocket/pubsub.md +38 -0
- package/docs/guides/websocket/simple.md +33 -0
- package/docs/guides/write-file/append.md +52 -0
- package/docs/guides/write-file/basic.md +44 -0
- package/docs/guides/write-file/blob.md +28 -0
- package/docs/guides/write-file/cat.md +17 -0
- package/docs/guides/write-file/file-cp.md +16 -0
- package/docs/guides/write-file/filesink.md +52 -0
- package/docs/guides/write-file/response.md +17 -0
- package/docs/guides/write-file/stdout.md +21 -0
- package/docs/guides/write-file/stream.md +17 -0
- package/docs/guides/write-file/unlink.md +23 -0
- package/docs/index.md +77 -0
- package/docs/install/cache.md +57 -0
- package/docs/install/index.md +202 -0
- package/docs/install/lifecycle.md +46 -0
- package/docs/install/lockfile.md +90 -0
- package/docs/install/npmrc.md +75 -0
- package/docs/install/overrides.md +73 -0
- package/docs/install/patch.md +57 -0
- package/docs/install/registries.md +30 -0
- package/docs/install/workspaces.md +70 -0
- package/docs/installation.md +289 -0
- package/docs/project/benchmarking.md +203 -0
- package/docs/project/building-windows.md +162 -0
- package/docs/project/internals/build-process-for-ci.md +75 -0
- package/docs/project/roadmap.md +87 -0
- package/docs/quickstart.md +144 -0
- package/docs/runtime/autoimport.md +94 -0
- package/docs/runtime/bun-apis.md +129 -0
- package/docs/runtime/bunfig.md +532 -0
- package/docs/runtime/debugger.md +325 -0
- package/docs/runtime/env.md +214 -0
- package/docs/runtime/hot.md +139 -0
- package/docs/runtime/index.md +309 -0
- package/docs/runtime/jsx.md +326 -0
- package/docs/runtime/loaders.md +127 -0
- package/docs/runtime/modules.md +298 -0
- package/docs/runtime/nodejs-apis.md +456 -0
- package/docs/runtime/plugins.md +605 -0
- package/docs/runtime/shell.md +537 -0
- package/docs/runtime/typescript.md +60 -0
- package/docs/runtime/web-apis.md +128 -0
- package/docs/test/coverage.md +91 -0
- package/docs/test/dom.md +75 -0
- package/docs/test/hot.md +15 -0
- package/docs/test/lifecycle.md +81 -0
- package/docs/test/mocks.md +236 -0
- package/docs/test/snapshots.md +15 -0
- package/docs/test/time.md +106 -0
- package/docs/test/writing.md +547 -0
- package/docs/typescript.md +51 -0
- package/package.json +5 -4
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Bun provides a fast native implementation of the `HTMLRewriter` pattern developed by Cloudflare. It provides a convenient, `EventListener`-like API for traversing and transforming HTML documents.
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
const rewriter = new HTMLRewriter();
|
|
5
|
+
|
|
6
|
+
rewriter.on("*", {
|
|
7
|
+
element(el) {
|
|
8
|
+
console.log(el.tagName); // "body" | "div" | ...
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To parse and/or transform the HTML:
|
|
14
|
+
|
|
15
|
+
```ts#rewriter.ts
|
|
16
|
+
rewriter.transform(
|
|
17
|
+
new Response(`
|
|
18
|
+
<!DOCTYPE html>
|
|
19
|
+
<html>
|
|
20
|
+
<!-- comment -->
|
|
21
|
+
<head>
|
|
22
|
+
<title>My First HTML Page</title>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<h1>My First Heading</h1>
|
|
26
|
+
<p>My first paragraph.</p>
|
|
27
|
+
</body>
|
|
28
|
+
`));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
View the full documentation on the [Cloudflare website](https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/).
|
package/docs/api/http.md
ADDED
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
The page primarily documents the Bun-native `Bun.serve` API. Bun also implements [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and the Node.js [`http`](https://nodejs.org/api/http.html) and [`https`](https://nodejs.org/api/https.html) modules.
|
|
2
|
+
|
|
3
|
+
{% callout %}
|
|
4
|
+
These modules have been re-implemented to use Bun's fast internal HTTP infrastructure. Feel free to use these modules directly; frameworks like [Express](https://expressjs.com/) that depend on these modules should work out of the box. For granular compatibility information, see [Runtime > Node.js APIs](https://bun.sh/docs/runtime/nodejs-apis).
|
|
5
|
+
{% /callout %}
|
|
6
|
+
|
|
7
|
+
To start a high-performance HTTP server with a clean API, the recommended approach is [`Bun.serve`](#start-a-server-bun-serve).
|
|
8
|
+
|
|
9
|
+
## `Bun.serve()`
|
|
10
|
+
|
|
11
|
+
Start an HTTP server in Bun with `Bun.serve`.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
Bun.serve({
|
|
15
|
+
fetch(req) {
|
|
16
|
+
return new Response("Bun!");
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `fetch` request handler
|
|
22
|
+
|
|
23
|
+
The `fetch` handler handles incoming requests. It receives a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object and returns a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) or `Promise<Response>`.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
Bun.serve({
|
|
27
|
+
fetch(req) {
|
|
28
|
+
const url = new URL(req.url);
|
|
29
|
+
if (url.pathname === "/") return new Response("Home page!");
|
|
30
|
+
if (url.pathname === "/blog") return new Response("Blog!");
|
|
31
|
+
return new Response("404!");
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The `fetch` handler supports async/await:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { sleep, serve } from "bun";
|
|
40
|
+
serve({
|
|
41
|
+
async fetch(req) {
|
|
42
|
+
const start = performance.now();
|
|
43
|
+
await sleep(10);
|
|
44
|
+
const end = performance.now();
|
|
45
|
+
return new Response(`Slept for ${end - start}ms`);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Promise-based responses are also supported:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
Bun.serve({
|
|
54
|
+
fetch(req) {
|
|
55
|
+
// Forward the request to another server.
|
|
56
|
+
return fetch("https://example.com");
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
You can also access the `Server` object from the `fetch` handler. It's the second argument passed to the `fetch` function.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// `server` is passed in as the second argument to `fetch`.
|
|
65
|
+
const server = Bun.serve({
|
|
66
|
+
fetch(req, server) {
|
|
67
|
+
const ip = server.requestIP(req);
|
|
68
|
+
return new Response(`Your IP is ${ip}`);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Static routes
|
|
74
|
+
|
|
75
|
+
Use the `static` option to serve static `Response` objects by route.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// Bun v1.1.27+ required
|
|
79
|
+
Bun.serve({
|
|
80
|
+
static: {
|
|
81
|
+
// health-check endpoint
|
|
82
|
+
"/api/health-check": new Response("All good!"),
|
|
83
|
+
|
|
84
|
+
// redirect from /old-link to /new-link
|
|
85
|
+
"/old-link": Response.redirect("/new-link", 301),
|
|
86
|
+
|
|
87
|
+
// serve static text
|
|
88
|
+
"/": new Response("Hello World"),
|
|
89
|
+
|
|
90
|
+
// serve a file by buffering it in memory
|
|
91
|
+
"/index.html": new Response(await Bun.file("./index.html").bytes(), {
|
|
92
|
+
headers: {
|
|
93
|
+
"Content-Type": "text/html",
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
"/favicon.ico": new Response(await Bun.file("./favicon.ico").bytes(), {
|
|
97
|
+
headers: {
|
|
98
|
+
"Content-Type": "image/x-icon",
|
|
99
|
+
},
|
|
100
|
+
}),
|
|
101
|
+
|
|
102
|
+
// serve JSON
|
|
103
|
+
"/api/version.json": Response.json({ version: "1.0.0" }),
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
fetch(req) {
|
|
107
|
+
return new Response("404!");
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Static routes support headers, status code, and other `Response` options.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
Bun.serve({
|
|
116
|
+
static: {
|
|
117
|
+
"/api/time": new Response(new Date().toISOString(), {
|
|
118
|
+
headers: {
|
|
119
|
+
"X-Custom-Header": "Bun!",
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
fetch(req) {
|
|
125
|
+
return new Response("404!");
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Static routes can serve Response bodies faster than `fetch` handlers because they don't create `Request` objects, they don't create `AbortSignal`, they don't create additional `Response` objects. The only per-request memory allocation is the TCP/TLS socket data needed for each request.
|
|
131
|
+
|
|
132
|
+
{% note %}
|
|
133
|
+
`static` is experimental
|
|
134
|
+
{% /note %}
|
|
135
|
+
|
|
136
|
+
Static route responses are cached for the lifetime of the server object. To reload static routes, call `server.reload(options)`.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const server = Bun.serve({
|
|
140
|
+
static: {
|
|
141
|
+
"/api/time": new Response(new Date().toISOString()),
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
fetch(req) {
|
|
145
|
+
return new Response("404!");
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Update the time every second.
|
|
150
|
+
setInterval(() => {
|
|
151
|
+
server.reload({
|
|
152
|
+
static: {
|
|
153
|
+
"/api/time": new Response(new Date().toISOString()),
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
fetch(req) {
|
|
157
|
+
return new Response("404!");
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}, 1000);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Reloading static routes only impact the next request. In-flight requests continue to use the old static routes. After in-flight requests to old static routes are finished, the old static routes are freed from memory.
|
|
164
|
+
|
|
165
|
+
To simplify error handling, static routes do not support streaming response bodies from `ReadableStream` or an `AsyncIterator`. Fortunately, you can still buffer the response in memory first:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const time = await fetch("https://api.example.com/v1/data");
|
|
169
|
+
// Buffer the response in memory first.
|
|
170
|
+
const blob = await time.blob();
|
|
171
|
+
|
|
172
|
+
const server = Bun.serve({
|
|
173
|
+
static: {
|
|
174
|
+
"/api/data": new Response(blob),
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
fetch(req) {
|
|
178
|
+
return new Response("404!");
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Changing the `port` and `hostname`
|
|
184
|
+
|
|
185
|
+
To configure which port and hostname the server will listen on, set `port` and `hostname` in the options object.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
Bun.serve({
|
|
189
|
+
port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
|
|
190
|
+
hostname: "mydomain.com", // defaults to "0.0.0.0"
|
|
191
|
+
fetch(req) {
|
|
192
|
+
return new Response("404!");
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
To randomly select an available port, set `port` to `0`.
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
const server = Bun.serve({
|
|
201
|
+
port: 0, // random port
|
|
202
|
+
fetch(req) {
|
|
203
|
+
return new Response("404!");
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// server.port is the randomly selected port
|
|
208
|
+
console.log(server.port);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
You can view the chosen port by accessing the `port` property on the server object, or by accessing the `url` property.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
console.log(server.port); // 3000
|
|
215
|
+
console.log(server.url); // http://localhost:3000
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### Configuring a default port
|
|
219
|
+
|
|
220
|
+
Bun supports several options and environment variables to configure the default port. The default port is used when the `port` option is not set.
|
|
221
|
+
|
|
222
|
+
- `--port` CLI flag
|
|
223
|
+
|
|
224
|
+
```sh
|
|
225
|
+
$ bun --port=4002 server.ts
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- `BUN_PORT` environment variable
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
$ BUN_PORT=4002 bun server.ts
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
- `PORT` environment variable
|
|
235
|
+
|
|
236
|
+
```sh
|
|
237
|
+
$ PORT=4002 bun server.ts
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
- `NODE_PORT` environment variable
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
$ NODE_PORT=4002 bun server.ts
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Unix domain sockets
|
|
247
|
+
|
|
248
|
+
To listen on a [unix domain socket](https://en.wikipedia.org/wiki/Unix_domain_socket), pass the `unix` option with the path to the socket.
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
Bun.serve({
|
|
252
|
+
unix: "/tmp/my-socket.sock", // path to socket
|
|
253
|
+
fetch(req) {
|
|
254
|
+
return new Response(`404!`);
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Abstract namespace sockets
|
|
260
|
+
|
|
261
|
+
Bun supports Linux abstract namespace sockets. To use an abstract namespace socket, prefix the `unix` path with a null byte.
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
Bun.serve({
|
|
265
|
+
unix: "\0my-abstract-socket", // abstract namespace socket
|
|
266
|
+
fetch(req) {
|
|
267
|
+
return new Response(`404!`);
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Unlike unix domain sockets, abstract namespace sockets are not bound to the filesystem and are automatically removed when the last reference to the socket is closed.
|
|
273
|
+
|
|
274
|
+
## Error handling
|
|
275
|
+
|
|
276
|
+
To activate development mode, set `development: true`.
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
Bun.serve({
|
|
280
|
+
development: true,
|
|
281
|
+
fetch(req) {
|
|
282
|
+
throw new Error("woops!");
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
In development mode, Bun will surface errors in-browser with a built-in error page.
|
|
288
|
+
|
|
289
|
+
{% image src="/images/exception_page.png" caption="Bun's built-in 500 page" /%}
|
|
290
|
+
|
|
291
|
+
### `error` callback
|
|
292
|
+
|
|
293
|
+
To handle server-side errors, implement an `error` handler. This function should return a `Response` to serve to the client when an error occurs. This response will supersede Bun's default error page in `development` mode.
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
Bun.serve({
|
|
297
|
+
fetch(req) {
|
|
298
|
+
throw new Error("woops!");
|
|
299
|
+
},
|
|
300
|
+
error(error) {
|
|
301
|
+
return new Response(`<pre>${error}\n${error.stack}</pre>`, {
|
|
302
|
+
headers: {
|
|
303
|
+
"Content-Type": "text/html",
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
{% callout %}
|
|
311
|
+
[Learn more about debugging in Bun](https://bun.sh/docs/runtime/debugger)
|
|
312
|
+
{% /callout %}
|
|
313
|
+
|
|
314
|
+
The call to `Bun.serve` returns a `Server` object. To stop the server, call the `.stop()` method.
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
const server = Bun.serve({
|
|
318
|
+
fetch() {
|
|
319
|
+
return new Response("Bun!");
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
server.stop();
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## TLS
|
|
327
|
+
|
|
328
|
+
Bun supports TLS out of the box, powered by [BoringSSL](https://boringssl.googlesource.com/boringssl). Enable TLS by passing in a value for `key` and `cert`; both are required to enable TLS.
|
|
329
|
+
|
|
330
|
+
```ts-diff
|
|
331
|
+
Bun.serve({
|
|
332
|
+
fetch(req) {
|
|
333
|
+
return new Response("Hello!!!");
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
+ tls: {
|
|
337
|
+
+ key: Bun.file("./key.pem"),
|
|
338
|
+
+ cert: Bun.file("./cert.pem"),
|
|
339
|
+
+ }
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
The `key` and `cert` fields expect the _contents_ of your TLS key and certificate, _not a path to it_. This can be a string, `BunFile`, `TypedArray`, or `Buffer`.
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
Bun.serve({
|
|
347
|
+
fetch() {},
|
|
348
|
+
|
|
349
|
+
tls: {
|
|
350
|
+
// BunFile
|
|
351
|
+
key: Bun.file("./key.pem"),
|
|
352
|
+
// Buffer
|
|
353
|
+
key: fs.readFileSync("./key.pem"),
|
|
354
|
+
// string
|
|
355
|
+
key: fs.readFileSync("./key.pem", "utf8"),
|
|
356
|
+
// array of above
|
|
357
|
+
key: [Bun.file("./key1.pem"), Bun.file("./key2.pem")],
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
If your private key is encrypted with a passphrase, provide a value for `passphrase` to decrypt it.
|
|
363
|
+
|
|
364
|
+
```ts-diff
|
|
365
|
+
Bun.serve({
|
|
366
|
+
fetch(req) {
|
|
367
|
+
return new Response("Hello!!!");
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
tls: {
|
|
371
|
+
key: Bun.file("./key.pem"),
|
|
372
|
+
cert: Bun.file("./cert.pem"),
|
|
373
|
+
+ passphrase: "my-secret-passphrase",
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Optionally, you can override the trusted CA certificates by passing a value for `ca`. By default, the server will trust the list of well-known CAs curated by Mozilla. When `ca` is specified, the Mozilla list is overwritten.
|
|
379
|
+
|
|
380
|
+
```ts-diff
|
|
381
|
+
Bun.serve({
|
|
382
|
+
fetch(req) {
|
|
383
|
+
return new Response("Hello!!!");
|
|
384
|
+
},
|
|
385
|
+
tls: {
|
|
386
|
+
key: Bun.file("./key.pem"), // path to TLS key
|
|
387
|
+
cert: Bun.file("./cert.pem"), // path to TLS cert
|
|
388
|
+
+ ca: Bun.file("./ca.pem"), // path to root CA certificate
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
To override Diffie-Hellman parameters:
|
|
394
|
+
|
|
395
|
+
```ts
|
|
396
|
+
Bun.serve({
|
|
397
|
+
// ...
|
|
398
|
+
tls: {
|
|
399
|
+
// other config
|
|
400
|
+
dhParamsFile: "/path/to/dhparams.pem", // path to Diffie Hellman parameters
|
|
401
|
+
},
|
|
402
|
+
});
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Server name indication (SNI)
|
|
406
|
+
|
|
407
|
+
To configure the server name indication (SNI) for the server, set the `serverName` field in the `tls` object.
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
Bun.serve({
|
|
411
|
+
// ...
|
|
412
|
+
tls: {
|
|
413
|
+
// ... other config
|
|
414
|
+
serverName: "my-server.com", // SNI
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
To allow multiple server names, pass an array of objects to `tls`, each with a `serverName` field.
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
Bun.serve({
|
|
423
|
+
// ...
|
|
424
|
+
tls: [
|
|
425
|
+
{
|
|
426
|
+
key: Bun.file("./key1.pem"),
|
|
427
|
+
cert: Bun.file("./cert1.pem"),
|
|
428
|
+
serverName: "my-server1.com",
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
key: Bun.file("./key2.pem"),
|
|
432
|
+
cert: Bun.file("./cert2.pem"),
|
|
433
|
+
serverName: "my-server2.com",
|
|
434
|
+
},
|
|
435
|
+
],
|
|
436
|
+
});
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## idleTimeout
|
|
440
|
+
|
|
441
|
+
To configure the idle timeout, set the `idleTimeout` field in Bun.serve.
|
|
442
|
+
|
|
443
|
+
```ts
|
|
444
|
+
Bun.serve({
|
|
445
|
+
// 10 seconds:
|
|
446
|
+
idleTimeout: 10,
|
|
447
|
+
|
|
448
|
+
fetch(req) {
|
|
449
|
+
return new Response("Bun!");
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
This is the maximum amount of time a connection is allowed to be idle before the server closes it. A connection is idling if there is no data sent or received.
|
|
455
|
+
|
|
456
|
+
## export default syntax
|
|
457
|
+
|
|
458
|
+
Thus far, the examples on this page have used the explicit `Bun.serve` API. Bun also supports an alternate syntax.
|
|
459
|
+
|
|
460
|
+
```ts#server.ts
|
|
461
|
+
import {type Serve} from "bun";
|
|
462
|
+
|
|
463
|
+
export default {
|
|
464
|
+
fetch(req) {
|
|
465
|
+
return new Response("Bun!");
|
|
466
|
+
},
|
|
467
|
+
} satisfies Serve;
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Instead of passing the server options into `Bun.serve`, `export default` it. This file can be executed as-is; when Bun sees a file with a `default` export containing a `fetch` handler, it passes it into `Bun.serve` under the hood.
|
|
471
|
+
|
|
472
|
+
<!-- This syntax has one major advantage: it is hot-reloadable out of the box. When any source file is changed, Bun will reload the server with the updated code _without restarting the process_. This makes hot reloads nearly instantaneous. Use the `--hot` flag when starting the server to enable hot reloading. -->
|
|
473
|
+
|
|
474
|
+
<!-- ```bash
|
|
475
|
+
$ bun --hot server.ts
|
|
476
|
+
``` -->
|
|
477
|
+
|
|
478
|
+
<!-- It's possible to configure hot reloading while using the explicit `Bun.serve` API; for details refer to [Runtime > Hot reloading](https://bun.sh/docs/runtime/hot). -->
|
|
479
|
+
|
|
480
|
+
## Streaming files
|
|
481
|
+
|
|
482
|
+
To stream a file, return a `Response` object with a `BunFile` object as the body.
|
|
483
|
+
|
|
484
|
+
```ts
|
|
485
|
+
Bun.serve({
|
|
486
|
+
fetch(req) {
|
|
487
|
+
return new Response(Bun.file("./hello.txt"));
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
{% callout %}
|
|
493
|
+
⚡️ **Speed** — Bun automatically uses the [`sendfile(2)`](https://man7.org/linux/man-pages/man2/sendfile.2.html) system call when possible, enabling zero-copy file transfers in the kernel—the fastest way to send files.
|
|
494
|
+
{% /callout %}
|
|
495
|
+
|
|
496
|
+
You can send part of a file using the [`slice(start, end)`](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice) method on the `Bun.file` object. This automatically sets the `Content-Range` and `Content-Length` headers on the `Response` object.
|
|
497
|
+
|
|
498
|
+
```ts
|
|
499
|
+
Bun.serve({
|
|
500
|
+
fetch(req) {
|
|
501
|
+
// parse `Range` header
|
|
502
|
+
const [start = 0, end = Infinity] = req.headers
|
|
503
|
+
.get("Range") // Range: bytes=0-100
|
|
504
|
+
.split("=") // ["Range: bytes", "0-100"]
|
|
505
|
+
.at(-1) // "0-100"
|
|
506
|
+
.split("-") // ["0", "100"]
|
|
507
|
+
.map(Number); // [0, 100]
|
|
508
|
+
|
|
509
|
+
// return a slice of the file
|
|
510
|
+
const bigFile = Bun.file("./big-video.mp4");
|
|
511
|
+
return new Response(bigFile.slice(start, end));
|
|
512
|
+
},
|
|
513
|
+
});
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## Benchmarks
|
|
517
|
+
|
|
518
|
+
Below are Bun and Node.js implementations of a simple HTTP server that responds `Bun!` to each incoming `Request`.
|
|
519
|
+
|
|
520
|
+
{% codetabs %}
|
|
521
|
+
|
|
522
|
+
```ts#Bun
|
|
523
|
+
Bun.serve({
|
|
524
|
+
fetch(req: Request) {
|
|
525
|
+
return new Response("Bun!");
|
|
526
|
+
},
|
|
527
|
+
port: 3000,
|
|
528
|
+
});
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
```ts#Node
|
|
532
|
+
require("http")
|
|
533
|
+
.createServer((req, res) => res.end("Bun!"))
|
|
534
|
+
.listen(8080);
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
{% /codetabs %}
|
|
538
|
+
The `Bun.serve` server can handle roughly 2.5x more requests per second than Node.js on Linux.
|
|
539
|
+
|
|
540
|
+
{% table %}
|
|
541
|
+
|
|
542
|
+
- Runtime
|
|
543
|
+
- Requests per second
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
- Node 16
|
|
548
|
+
- ~64,000
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
- Bun
|
|
553
|
+
- ~160,000
|
|
554
|
+
|
|
555
|
+
{% /table %}
|
|
556
|
+
|
|
557
|
+
{% image width="499" alt="image" src="https://user-images.githubusercontent.com/709451/162389032-fc302444-9d03-46be-ba87-c12bd8ce89a0.png" /%}
|
|
558
|
+
|
|
559
|
+
## Reference
|
|
560
|
+
|
|
561
|
+
{% details summary="See TypeScript definitions" %}
|
|
562
|
+
|
|
563
|
+
```ts
|
|
564
|
+
interface Bun {
|
|
565
|
+
serve(options: {
|
|
566
|
+
development?: boolean;
|
|
567
|
+
error?: (
|
|
568
|
+
request: ErrorLike,
|
|
569
|
+
) => Response | Promise<Response> | undefined | Promise<undefined>;
|
|
570
|
+
fetch(request: Request, server: Server): Response | Promise<Response>;
|
|
571
|
+
hostname?: string;
|
|
572
|
+
id?: string | null;
|
|
573
|
+
maxRequestBodySize?: number;
|
|
574
|
+
port?: string | number;
|
|
575
|
+
reusePort?: boolean;
|
|
576
|
+
tls?: TLSOptions | Array<TLSOptions>;
|
|
577
|
+
unix: string;
|
|
578
|
+
websocket: WebSocketHandler<WebSocketDataType>;
|
|
579
|
+
}): Server;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
interface TLSOptions {
|
|
583
|
+
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
|
|
584
|
+
cert?:
|
|
585
|
+
| string
|
|
586
|
+
| Buffer
|
|
587
|
+
| BunFile
|
|
588
|
+
| Array<string | Buffer | BunFile>
|
|
589
|
+
| undefined;
|
|
590
|
+
dhParamsFile?: string;
|
|
591
|
+
key?:
|
|
592
|
+
| string
|
|
593
|
+
| Buffer
|
|
594
|
+
| BunFile
|
|
595
|
+
| Array<string | Buffer | BunFile>
|
|
596
|
+
| undefined;
|
|
597
|
+
lowMemoryMode?: boolean;
|
|
598
|
+
passphrase?: string;
|
|
599
|
+
secureOptions?: number | undefined;
|
|
600
|
+
serverName?: string;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
interface WebSocketHandler<T = undefined> {
|
|
604
|
+
backpressureLimit?: number;
|
|
605
|
+
close?(
|
|
606
|
+
ws: ServerWebSocket<T>,
|
|
607
|
+
code: number,
|
|
608
|
+
reason: string,
|
|
609
|
+
): void | Promise<void>;
|
|
610
|
+
closeOnBackpressureLimit?: boolean;
|
|
611
|
+
drain?(ws: ServerWebSocket<T>): void | Promise<void>;
|
|
612
|
+
idleTimeout?: number;
|
|
613
|
+
maxPayloadLength?: number;
|
|
614
|
+
message(
|
|
615
|
+
ws: ServerWebSocket<T>,
|
|
616
|
+
message: string | Buffer,
|
|
617
|
+
): void | Promise<void>;
|
|
618
|
+
open?(ws: ServerWebSocket<T>): void | Promise<void>;
|
|
619
|
+
perMessageDeflate?:
|
|
620
|
+
| boolean
|
|
621
|
+
| {
|
|
622
|
+
compress?: WebSocketCompressor | boolean;
|
|
623
|
+
decompress?: WebSocketCompressor | boolean;
|
|
624
|
+
};
|
|
625
|
+
ping?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>;
|
|
626
|
+
pong?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>;
|
|
627
|
+
publishToSelf?: boolean;
|
|
628
|
+
sendPings?: boolean;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
interface Server {
|
|
632
|
+
fetch(request: Request | string): Response | Promise<Response>;
|
|
633
|
+
publish(
|
|
634
|
+
compress?: boolean,
|
|
635
|
+
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
|
|
636
|
+
topic: string,
|
|
637
|
+
): ServerWebSocketSendStatus;
|
|
638
|
+
ref(): void;
|
|
639
|
+
reload(options: Serve): void;
|
|
640
|
+
requestIP(request: Request): SocketAddress | null;
|
|
641
|
+
stop(closeActiveConnections?: boolean): void;
|
|
642
|
+
unref(): void;
|
|
643
|
+
upgrade<T = undefined>(
|
|
644
|
+
options?: {
|
|
645
|
+
data?: T;
|
|
646
|
+
headers?: Bun.HeadersInit;
|
|
647
|
+
},
|
|
648
|
+
request: Request,
|
|
649
|
+
): boolean;
|
|
650
|
+
|
|
651
|
+
readonly development: boolean;
|
|
652
|
+
readonly hostname: string;
|
|
653
|
+
readonly id: string;
|
|
654
|
+
readonly pendingRequests: number;
|
|
655
|
+
readonly pendingWebSockets: number;
|
|
656
|
+
readonly port: number;
|
|
657
|
+
readonly url: URL;
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
{% /details %}
|