Compare commits

...

107 Commits

Author SHA1 Message Date
Colin McDonnell
17b5f79567 Remove --save from helptext 2023-09-13 19:33:49 -07:00
Steven
64033f11cc chore(docs): include missing links to Node.js APIs (#5281)
These links make it easy to click and jump to another section.
2023-09-13 14:08:28 -07:00
wing
1c570b41bc docs(guide): fix expect assertion example in guide for spyOn (#5294)
Fixes example with `spyOn` and assertions. The example failed because the spied function would be called once but the expectation asserted 0 calls.
2023-09-13 14:08:09 -07:00
Andrew Brown
500bd15fb5 add uninstall instructions (#5311)
it's always good to have uninstall instructions as well as install, and I couldn't find them anywhere else on the site.

IMO, this gives users a little more confidence to try new tools out, as they know it's easily reversible.

I'm not familiar with how to uninstall with Docker, so would appreciate some help there.

We could possibly add a note for "bash" on how to remove Bun from the `$PATH`.
2023-09-13 14:07:43 -07:00
Guilherme J. Tramontina
687e31dc3a docs: update lockfile diff instructions (#5275) 2023-09-13 10:27:32 -07:00
David Hewitt
c3455c0cee fix(node/fetch): Make data URL fetch consistent with node (#5126) 2023-09-13 05:35:39 -07:00
iidebyo
9101774593 avoid inserting extraneous"accept-encoding" header (#5057)
* add no extraneous accept-encoding header test

* ensure fetch honors no decompress opt

* fix format on test/js/node/http/node-http.test.ts
2023-09-13 02:02:25 -07:00
Zong
9a0ea00705 docs(runtime): fix plugins loader extensions typo (#5250) 2023-09-13 02:00:11 -07:00
Gareth Jones
ec6b75ff54 chore: make comment grammatically correct (#5140) 2023-09-13 01:56:19 -07:00
Colin McDonnell
a18e3ff451 Add informative message on 'bun create react' (#5248) 2023-09-13 01:48:42 -07:00
Zong
eeb790a2f1 docs(runtime): fix jsx FragmentFactory output example (#5243) 2023-09-13 01:47:54 -07:00
amt8u
878b473085 file.exists() needs to be awaited to get the value (#5061) 2023-09-13 01:41:18 -07:00
Antonin CLAUZIER
6161c201e1 Update discordjs.md (#5227) 2023-09-13 01:38:17 -07:00
Dylan Conway
32664df254 decode regex if needed (#5167)
* decode regex if non-ascii

* make it comptime

* add test

* use `bun.BabyList(u16)`
2023-09-13 01:26:18 -07:00
Nathan Hammond
15f7bacb8b Correct the configuration file names. (#5234) 2023-09-13 01:19:15 -07:00
Colin McDonnell
473513db7e Update tsconfig.json for bun init 2023-09-12 23:53:28 -07:00
cfal
75b5c71540 js/node/stream.js: call write() callback when encoding is not provided (#4841)
* js/node/stream.js: call write() callback when encoding is not provided

* js/out/InternalModuleRegistryConstants.h: update
2023-09-12 22:21:58 -07:00
Gordon Goldbach
c9c62f37e5 docs: Made bun-types install as dev dependency in example (#5120) 2023-09-12 22:04:39 -07:00
Colin McDonnell
18b521d9b8 Various docs (#5201)
* Updates

* Improve jest guide

* Improve
2023-09-12 21:51:49 -07:00
Southpaw
534fd30dbd Use git's --global flag for lockfile diffs instead of manually modifying config files (#5143) 2023-09-12 21:51:07 -07:00
Jonathan Neal
3b2c0941e4 docs: fix typo in import.meta.resolve (#5146) 2023-09-12 19:14:26 -07:00
Nazeel
8d3829114e Update hot.md (#4990) 2023-09-12 18:54:23 -07:00
Tom Redman
5f9c30b717 Update simple.md (#4997)
Remove errant slash preventing the correct console log
2023-09-12 18:53:55 -07:00
xnacly
c55574b4d3 fix typo and grammar errors (#5046) 2023-09-12 18:53:23 -07:00
mi4uu
2f27e24778 clang and llvm on arch install v16, update to use v15 (#5069) 2023-09-12 18:52:30 -07:00
Diogo Goncalves
b910db74be Add missing full stop on nodejs-apis.md (#5072) 2023-09-12 18:51:15 -07:00
Toby
b37cb98a6e udate README.md (#5127)
update path
2023-09-12 18:50:50 -07:00
Samuel Rigaud
263382103f docs: fix typos (#5151) 2023-09-12 18:50:05 -07:00
Thomas Rupprecht
8777c3f72c fix lifecycle docu (#5159) 2023-09-12 18:49:19 -07:00
Colin McDonnell
996491f719 Clean up Modules doc 2023-09-12 16:54:07 -07:00
Colin McDonnell
12c2da0ebf Create SECURITY.md 2023-09-12 16:53:59 -07:00
Dylan Conway
a3166457d3 Update node-dns.test.js 2023-09-12 16:50:11 -07:00
Mitchell K
b1bd93bffc fix(bun-lambda) Fix API Gateway V1 events and expand on Lambda documentation (#5161)
* Fix issues with using V1 API Gateway events with Bun Lambda Layer.

* Remove aws-lambda as it is not needed
2023-09-12 14:59:19 -07:00
James Gordo
4c113d1866 Fixed Websocket Compression Example. (#5087)
* Passed message variable to ws.send() method.

* Passed message variable to ws.send() method.
2023-09-12 08:30:23 -07:00
ped
f9d2e687f5 Fix typo in http file upload example (#5088) 2023-09-12 08:30:06 -07:00
Jarred Sumner
31aec4ebe3 Fix bug with bun build --compile (#5102)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-09-12 07:07:07 -07:00
Jarred Sumner
b432006e43 Clean up some edgecases with posix_spawn usage (#5079)
* Check that the pid matches

* Fixup EINTR check

* Remove extra slashes

* fixup

* fixup

* != 0

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-09-12 06:34:20 -07:00
Alex Lam S.L
015f0a6e9a fix up with prettier (#5092) 2023-09-12 05:53:55 -07:00
David Hewitt
07a6443a80 fix(node/path): Prevent memory corruption in parse (#5083)
* Add failing test for issue #4954

* fix(node/path): Return results with toValueGC
2023-09-12 05:05:00 -07:00
Jarred Sumner
6e4f746ace Fix some bugs blocking Turborepo from using bun run (#5071)
* Clean up some error handling when loading `tsconfig.json`

* [bun run] don't parse tsconfig.json for package.json scripts

* Make this error message better

* Bump

* Don't print build errors twice

* Handle quotes in error messages a little better

* Add a couple tests

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-09-12 03:35:29 -07:00
Ai Hoshino
b5a3bed7f2 fix(JSC): copy string in toJSStringValueGC (#5067) 2023-09-12 03:08:42 -07:00
Ciro Spaciari
8615b8ad6b add NODE_TLS_REJECT_UNAUTHORIZED (#4829) 2023-09-11 21:52:31 -07:00
Eric Bidelman
4992839232 Update gzip.md (#5041)
typo
2023-09-11 21:47:35 -07:00
Colin McDonnell
03b8e9d5cf fix formatting in sveltekit guide 2023-09-11 20:12:48 -07:00
Ai Hoshino
f267c1d097 fix(path): Fix edge case in path.relative (#4811)
Close: #4789
2023-09-11 17:53:43 -07:00
Ai Hoshino
c4507a5db3 Fix Buffer.from to handle double-byte hex encoding strings (#4933)
Close: #4919
2023-09-11 17:27:12 -07:00
Ciro Spaciari
c9a0ea96cd fix(BunFile) .slice offset on macOS (#4991)
* fix offset

* simplify error
2023-09-11 17:19:43 -07:00
Dylan Conway
ca461f9e83 fix loading env from .env.production and friends (#4630)
* reload conditional vars

* test

* change `get` and `put` methods

* dont clone empty env variables
2023-09-11 17:19:21 -07:00
Colin McDonnell
9c4765f616 Update benchmark readme 2023-09-11 16:53:34 -07:00
Justin "J.R." Hill
e091290748 fix(bun-lambda): Don't drop arguments in console.log(...) (#4992)
Closes #4826
2023-09-11 12:39:56 -07:00
Ben Jervis
350403663e Fix error message typo in js_ast.zig (#4937) 2023-09-11 11:03:45 -07:00
Dylan Conway
895f3824b5 update test 2023-09-11 10:43:33 -07:00
Diogo Goncalves
58e69ef9f4 Remove unnecessary backticks in quickstart doc page (#4927) 2023-09-11 08:54:22 -07:00
Vladimir Pesterev
decad91d24 Fixed inconsistent log messages in the Quickstart guide (#4942)
Looks like it is just a typo and needs to be fixed.

Signed-off-by: Vladimir Pesterev <8786922+pesterev@users.noreply.github.com>
2023-09-11 08:53:54 -07:00
Yonathan Benolol
ea56182c5a Update http.js - Fix Methods Fallback naming (#4948) 2023-09-11 08:51:35 -07:00
Matthew Yu
9d6a8ee79d Fix punctuation (#4870) 2023-09-11 08:50:39 -07:00
fehnomenal
b55b511f68 Make detect-libc package match the upstream api (#4910) 2023-09-11 08:49:57 -07:00
Krzysztof Szala
49b9306dce fix: changes wrong command name in the tests chapter (#4965)
This PR fixes the command name for running tests flagged with `.only`
2023-09-11 08:48:53 -07:00
Krystian Pracuk
2956ed4289 added .idea to .gitignore (#4951) 2023-09-11 08:48:26 -07:00
Jarred Sumner
51d3d43822 Support named imports for json & toml files at runtime (#4783)
* Support named exports in json imports

* Support named imports for `*.json` files

* Remove stale comments

* Don't export arrays as non-default

* Add test for default exports

* Don't break webpack

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-09-10 23:15:35 -07:00
Jarred Sumner
edea4f095a Fixes #4588 (#4804)
* Fixes #4588

* typo

* fixup

---------

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
2023-09-10 21:40:46 -07:00
Diogo Goncalves
07c88435e0 Replace unnecessary '' wih "` in code snippets (#4792) 2023-09-10 11:34:04 -07:00
Jeroen van Rensen
7121c1d6ab Update modules.md - Explain case-insensitivity (#4782) 2023-09-10 11:33:39 -07:00
Ed Knowles
60dc76676c docs: remove duplicate sentence from debugger (#4807) 2023-09-10 11:33:04 -07:00
toneyzhen
f64b504bae Update todo-tests.md (#4771) 2023-09-10 11:32:31 -07:00
Vyacheslav Kulik
97153c5a5f Add compatibility page link to index.md (#4809)
Add a link to compatibility page (https://bun.sh/docs/runtime/nodejs-apis) to its reference in index.md, so it's easier to reach out to.
2023-09-10 11:30:46 -07:00
Tom Sherman
d48ff53e4e docs: Update Bun.write(path, Response) example to be clear that it writes the body (#4802) 2023-09-10 05:06:25 -07:00
WingLim
afcbed218c fix(bindings): add missing binding (#4682) 2023-09-10 02:58:10 -07:00
Rinku Chaudhari
682406c42c docs: fix spelling (#4763) 2023-09-09 22:40:56 -07:00
Richard
6fe40f383a Fix mongoose ecosystem guid (#4740)
Fix missing method declaration on schema and Schema database name from Kitten to Animal
2023-09-09 19:05:13 -07:00
thunfisch987
e2d327881c fix(docs); typo on Nuxt guide page (#4745) 2023-09-09 19:04:05 -07:00
Robert Soriano
4280f74429 docs: fix wasi-js link (#4741) 2023-09-09 19:03:46 -07:00
Chris Hutchinson
8139a20c9f fix: remove from bun-server.test.ts test case (#4709) 2023-09-09 19:03:28 -07:00
akumarujon
620f6c51ce fix typo (#4639) 2023-09-09 14:46:41 -07:00
Ashcon Partovi
ffe4f561a3 Fix listen() using unix socket if argument is a valid port (#4620)
* Fix listen() using unix socket if argument is a valid port

Fixes #4582

* Add test
2023-09-08 16:27:44 -07:00
Ana Margarida Silva
c896792c37 fix(docs): connect websocket client repeated documentation (#4615) 2023-09-08 14:22:28 -07:00
Colin McDonnell
088491cb59 Add extension guide 2023-09-08 13:49:12 -07:00
xxxhussein
f27ef667c7 Delete docs/ecosystem/buchta.md (#4536)
Delete buchta.md since its development is discontinued by LowByteFox: https://twitter.com/LowByteFox/status/1694025965452636612
2023-09-08 13:21:41 -07:00
Arjunkumar
7d9820d478 Update mongoose.md (#4534) 2023-09-08 13:20:07 -07:00
Ethan Steere
b5da5168bf Update Svelte Kit Docs (#4541)
* Update Svelte Kit Docs

I added some guidance about how to build for production. Still WIP since I would like to add a more complete deployment guide.

* Formatting

---------

Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
2023-09-08 13:19:53 -07:00
rajatdua
61569fab80 docs(template.md): spelling (#4614) 2023-09-08 13:19:33 -07:00
Frederik De Bleser
0887825f54 Fix code typo in transpiler.md (#4604)
There are some extra closing brackets at the end of the `scanImports` example. These cause a syntax error ("Unterminated string literal")
2023-09-08 12:10:17 -07:00
Colin McDonnell
6d02b18680 Remove await plugin 2023-09-08 11:42:27 -07:00
Vitor Dino
1b8c6f266f docs: fix --backend options list on cache.md (#4599)
`symlink` wasn’t an item, it appeared the same as `copyfile`
2023-09-08 11:19:29 -07:00
Dan Fabulich
989dd92ea8 Move "Importing CJS from CJS" back out of low-level details section (#4600)
This section appears to have been accidentally moved into the low-level details section in 5424ea3403.

This fixes the example in the low-level details section, because the "Importing CJS from CJS" section is not the example code that the low-level details section is intended to provide.
2023-09-08 11:18:52 -07:00
Colin McDonnell
9e3cabc540 Remove community-templates 2023-09-08 10:55:16 -07:00
Ondrej Brablc
3170cf08ba Make the link to application clickable in the terminal (#4544)
Terminals like iTerm require valid URL to make them clickable. Adding a space to make it valid. Similar problem is on https://bun.sh/, where protocol is missing.
2023-09-08 09:33:35 -07:00
Samual Norman
182d3f1567 Fix Bun.CryptoHasher missing argument in docs (#4585) 2023-09-08 09:32:36 -07:00
Tiramify (A.K. Daniel)
189f0f7c36 Update development.md (#4578) 2023-09-08 09:32:15 -07:00
Ashcon Partovi
a05a1780c1 Fix bun-types 2023-09-08 08:29:59 -07:00
Jarred Sumner
822a00c4d5 Fix a couple important bugs (#4560) 2023-09-07 21:07:00 -08:00
Adam
f6a621f36a Fix typo in sveltekit.md (#4550) 2023-09-07 13:11:09 -07:00
dave caruso
5b9d8b87c4 Bump version to Bun 1.0.0 (#4543)
* hi

* Update Version to 1.0.0

* 2

---------

Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com>
2023-09-07 10:57:46 -07:00
Colin McDonnell
a7c3bc8a5a Fix markdown 2023-09-07 10:12:52 -07:00
Colin McDonnell
5424ea3403 Doc updates for v1.0 (#4485)
* Remove v0.x messages

* Add windows section to Installatino

* update

* update

* Update

* Comment out windows
2023-09-07 10:09:09 -07:00
dave caruso
4b63ced72d fix(cli): final touches for 1.0 (#4538)
* better

* cli

* remove submodule

---------

Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2023-09-07 09:04:21 -07:00
Ciro Spaciari
c8883a39a5 fix(fetch) closeAndFail instead of close (#4537)
* closeAndFail instead of close

* use constant

* add some protection

* dont deinit

---------

Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2023-09-07 08:34:13 -07:00
dave caruso
36e5a072a9 revert (#4539)
* Revert "remove native events from streams"

This reverts commit e063a47a53.

* finish revert

* remove accidental submodule

* dfghj
2023-09-07 07:45:00 -07:00
dave caruso
57a06745a4 Progress for Next.js (#4468)
* L

* ipc

* asdfghjkl

* dfghjk

* it works!

* types

* patches for next.js

* sdfghj

* wsdfgn,./

* this

* yolo

* okay loser

* asdfghjk

* add some more APIs

* MESS

* sdfghjkl

* remove native events from streams

* stuff

* remove lazy(primordials) test

* debugging

* okay

* less fake extensions object

* fix `Buffer.toString()` args logic

* fix deserialize

* make tests work

* add test for `Buffer.toString` args

* Update server.zig

* remove test

* update test

* Update spawn-streaming-stdin.test.ts

* fix linux build

* Update fs.test.ts

* cli message improvements

* dfshaj

* Fix fs.watch bug maybe?

* remove

---------

Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
2023-09-07 04:58:44 -07:00
Ciro Spaciari
4360ec83b4 feat(fetch) rejectUnauthorized and checkServerIdentity (#4514)
* enable root certs on fetch

* rebase

* fix lookup

* some fixes and improvements

* fmt

* more fixes

* more fixes

* check detached onHandshake

* fix promise case

* fix cert non-Native

* add fetch tls tests

* more one test
2023-09-06 22:23:24 -07:00
Birk Skyum
3b9829f171 Update nodejs compat docs cp/cpSync/watchFile/unwatchFile (#4525) 2023-09-06 14:04:07 -07:00
Ashcon Partovi
849a2cdfae Add bun-types to 'bun fmt' script 2023-09-06 10:03:12 -07:00
Ashcon Partovi
77f1f2480d Add types for watchFile and unwatchFile 2023-09-06 10:02:48 -07:00
Ashcon Partovi
5e074209c6 Add types for cp and cpSync 2023-09-06 09:58:00 -07:00
Ashcon Partovi
0c2675c8d3 Remove issue template for install
It's not used, and use the bug issue instead.
2023-09-06 09:37:39 -07:00
dave caruso
a79440f0c3 fix(runtime): fix events.once not working (#4520) 2023-09-06 07:13:05 -07:00
Dylan Conway
daaac7792c allocate task for ThreadSafeFunction (#4513)
* create thread safe function task

* Update napi.zig

* Update napi.zig
2023-09-06 02:04:00 -07:00
227 changed files with 5418 additions and 2228 deletions

View File

@@ -1,35 +0,0 @@
name: 📥 Install Problem
description: Report an issue during install or upgrade
labels: [bug, install]
body:
- type: markdown
attributes:
value: |
Thank you for submitting a bug report. It helps make Bun better.
If you need help or support using Bun, and are not reporting an issue, please
join our [Discord](https://discord.gg/CXdq2DP29u) server, where you can ask questions in the [`#help`](https://discord.gg/32EtH6p7HN) forum.
Please try to include as much information as possible.
- type: input
attributes:
label: What platform is your computer?
description: |
For MacOS and Linux: copy the output of `uname -mprs`
For Windows: copy the output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in the PowerShell console
- type: textarea
attributes:
label: How did you attempt to install or upgrade?
description: Please provide the commands you ran to install or upgrade.
validations:
required: true
- type: textarea
attributes:
label: What do you see instead?
description: If possible, please provide text instead of a screenshot.
validations:
required: true
- type: textarea
attributes:
label: Additional information
description: Is there anything else you think we should know?

View File

@@ -20,7 +20,7 @@ ARG ZIG_FILENAME=${ZIG_FOLDERNAME}.tar.xz
ARG WEBKIT_URL="https://github.com/oven-sh/WebKit/releases/download/$WEBKIT_TAG/${WEBKIT_BASENAME}.tar.gz"
ARG ZIG_URL="https://ziglang.org/builds/${ZIG_FILENAME}"
ARG GIT_SHA=""
ARG BUN_BASE_VERSION=0.8
ARG BUN_BASE_VERSION=1.0
FROM bitnami/minideb:bullseye as bun-base

View File

@@ -38,7 +38,7 @@ NATIVE_OR_OLD_MARCH = -march=nehalem
endif
MIN_MACOS_VERSION ?= $(DEFAULT_MIN_MACOS_VERSION)
BUN_BASE_VERSION = 0.8
BUN_BASE_VERSION = 1.0
CI ?= false
@@ -1880,7 +1880,7 @@ PACKAGE_MAP = --pkg-begin async_io $(BUN_DIR)/src/io/io_darwin.zig --pkg-begin b
.PHONY: base64
base64:
cd $(BUN_DEPS_DIR)/base64 && make clean && cmake $(CMAKE_FLAGS) . && make
cd $(BUN_DEPS_DIR)/base64 && make clean && rm -rf CMakeCache.txt CMakeFiles && cmake $(CMAKE_FLAGS) . && make
cp $(BUN_DEPS_DIR)/base64/libbase64.a $(BUN_DEPS_OUT_DIR)/libbase64.a
.PHONY: cold-jsc-start

12
SECURITY.md Normal file
View File

@@ -0,0 +1,12 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 1.x.x | :white_check_mark: |
## Reporting a Vulnerability
Report any discovered vulnerabilities to the Bun team by emailing `security@bun.sh`. Your report will acknowledged within 5 days, and a team member will be assigned as the primary handler. To the greatest extent possible, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement, and may ask for additional information or guidance surrounding the reported issue.

View File

@@ -10,7 +10,7 @@ To run in Bun:
```bash
# so it doesn't run the vitest one
bun wiptest expect-to-equal.test.js
bun test expect-to-equal.test.js
```
To run in Jest:

View File

@@ -1,11 +1,33 @@
# `install` benchmark
Requires [`hyperfine`](https://github.com/sharkdp/hyperfine)
Requires [`hyperfine`](https://github.com/sharkdp/hyperfine). The goal of this benchmark is to compare installation performance of Bun with other package managers _when caches are hot_.
```
### With lockfile, online mode
To run the benchmark with the standard "install" command for each package manager:
```sh
$ hyperfine --prepare 'rm -rf node_modules' --warmup 1 --runs 3 'bun install' 'pnpm install' 'yarn' 'npm install'
```
### With lockfile, offline mode
Even though all packages are cached, some tools may hit the npm API during the version resolution step. (This is not the same as re-downloading a package.) To entirely avoid network calls, the other package managers require `--prefer-offline/--offline` flag. To run the benchmark using "offline" mode:
```sh
$ hyperfine --prepare 'rm -rf node_modules' --runs 1 'bun install' 'pnpm install --prefer-offline' 'yarn --offline' 'npm install --prefer-offline'
```
### Without lockfile, offline mode
To run the benchmark with offline mode but without lockfiles:
```sh
$ hyperfine --prepare 'rm -rf node_modules' --warmup 1 'rm bun.lockb && bun install' 'rm pnpm-lock.yaml && pnpm install --prefer-offline' 'rm yarn.lock && yarn --offline' 'rm package-lock.json && npm install --prefer-offline'
```
##
To check that the app is working as expected:
```

View File

@@ -1,8 +1,8 @@
[test]
# Large monorepos (like Bun) may want to specify the test directory more specifically
# By default, `bun test` scans every single folder recurisvely which, if you
# have a gigantic submodule (like WebKit), it has to do lots of directory
# By default, `bun test` scans every single folder recursively which, if you
# have a gigantic submodule (like WebKit), requires lots of directory
# traversals
#
# Instead, we can just make it scan only the test directory for Bun's runtime tests
# Instead, we can only scan the test directory for Bun's runtime tests
root = "test"

View File

@@ -74,7 +74,7 @@ dv.getUint8(0); // => 3
// [0x11, 0x0, 0x0, 0x0]
```
Now lets write a `Uint16` at byte offset `1`. This requires two bytes. We're using the value `513`, which is `2 * 256 + 1`; in bytes, that's `00000010 00000001`.
Now let's write a `Uint16` at byte offset `1`. This requires two bytes. We're using the value `513`, which is `2 * 256 + 1`; in bytes, that's `00000010 00000001`.
```ts
dv.setUint16(1, 513);
@@ -90,7 +90,7 @@ console.log(dv.getUint8(1)); // => 2
console.log(dv.getUint8(2)); // => 1
```
Attempting to write a value that requires more space than is available in the underlying `ArrayBuffer` will cuase an error. Below we attempt to write a `Float64` (which requires 8 bytes) at byte offset `0`, but there are only four total bytes in the buffer.
Attempting to write a value that requires more space than is available in the underlying `ArrayBuffer` will cause an error. Below we attempt to write a `Float64` (which requires 8 bytes) at byte offset `0`, but there are only four total bytes in the buffer.
```ts
dv.setFloat64(0, 3.1415);
@@ -412,7 +412,7 @@ For complete documentation, refer to the [Node.js documentation](https://nodejs.
`Blob` is a Web API commonly used for representing files. `Blob` was initially implemented in browsers (unlike `ArrayBuffer` which is part of JavaScript itself), but it is now supported in Node and Bun.
It isn't common to directly create `Blob` instances. More often, you'll recieve instances of `Blob` from an external source (like an `<input type="file">` element in the browser) or library. That said, it is possible to create a `Blob` from one or more string or binary "blob parts".
It isn't common to directly create `Blob` instances. More often, you'll receive instances of `Blob` from an external source (like an `<input type="file">` element in the browser) or library. That said, it is possible to create a `Blob` from one or more string or binary "blob parts".
```ts
const blob = new Blob(["<html>Hello</html>"], {
@@ -507,7 +507,7 @@ for await (const chunk of stream) {
}
```
For a more complete discusson of streams in Bun, see [API > Streams](/docs/api/streams).
For a more complete discussion of streams in Bun, see [API > Streams](/docs/api/streams).
## Conversion

View File

@@ -229,7 +229,11 @@ const lib = linkSymbols({
},
});
const [major, minor, patch] = [lib.symbols.getMajor(), lib.symbols.getMinor(), lib.symbols.getPatch()];
const [major, minor, patch] = [
lib.symbols.getMajor(),
lib.symbols.getMinor(),
lib.symbols.getPatch(),
];
```
## Callbacks
@@ -249,10 +253,13 @@ const {
},
});
const searchIterator = new JSCallback((ptr, length) => /hello/.test(new CString(ptr, length)), {
returns: "bool",
args: ["ptr", "usize"],
});
const searchIterator = new JSCallback(
(ptr, length) => /hello/.test(new CString(ptr, length)),
{
returns: "bool",
args: ["ptr", "usize"],
},
);
const str = Buffer.from("wwutwutwutwutwutwutwutwutwutwutut\0", "utf8");
if (search(ptr(str), searchIterator)) {
@@ -376,10 +383,6 @@ If you want to track when a `TypedArray` is no longer in use from JavaScript, yo
#### From C, Rust, Zig, etc
{% callout %}
**Note** — Available in Bun v0.1.8 and later.
{% /callout %}
If you want to track when a `TypedArray` is no longer in use from C or FFI, you can pass a callback and an optional context pointer to `toArrayBuffer` or `toBuffer`. This function is called at some point later, once the garbage collector frees the underlying `ArrayBuffer` JavaScript object.
The expected signature is the same as in [JavaScriptCore's C API](https://developer.apple.com/documentation/javascriptcore/jstypedarraybytesdeallocator?language=objc):

View File

@@ -195,7 +195,7 @@ const input = Bun.file("input.txt");
await Bun.write(Bun.stdout, input);
```
To write an HTTP response to disk:
To write the body of an HTTP response to disk:
```ts
const response = await fetch("https://bun.sh");

View File

@@ -6,10 +6,6 @@ Bun implements the `createHash` and `createHmac` functions from [`node:crypto`](
## `Bun.password`
{% callout %}
**Note** — Added in Bun 0.6.8.
{% /callout %}
`Bun.password` is a collection of utility functions for hashing and verifying passwords with various cryptographically secure algorithms.
```ts
@@ -136,7 +132,7 @@ hasher.digest();
Once initialized, data can be incrementally fed to to the hasher using `.update()`. This method accepts `string`, `TypedArray`, and `ArrayBuffer`.
```ts
const hasher = new Bun.CryptoHasher();
const hasher = new Bun.CryptoHasher("sha256");
hasher.update("hello world");
hasher.update(new Uint8Array([1, 2, 3]));
@@ -174,7 +170,7 @@ hasher.update("hello world", "latin1");
After the data has been feed into the hasher, a final hash can be computed using `.digest()`. By default, this method returns a `Uint8Array` containing the hash.
```ts
const hasher = new Bun.CryptoHasher();
const hasher = new Bun.CryptoHasher("sha256");
hasher.update("hello world");
hasher.digest();

View File

@@ -13,7 +13,7 @@ Start an HTTP server in Bun with `Bun.serve`.
```ts
Bun.serve({
fetch(req) {
return new Response(`Bun!`);
return new Response("Bun!");
},
});
```
@@ -24,9 +24,9 @@ The `fetch` handler handles incoming requests. It receives a [`Request`](https:/
Bun.serve({
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/") return new Response(`Home page!`);
if (url.pathname === "/") return new Response("Home page!");
if (url.pathname === "/blog") return new Response("Blog!");
return new Response(`404!`);
return new Response("404!");
},
});
```
@@ -38,7 +38,7 @@ Bun.serve({
port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
hostname: "mydomain.com", // defaults to "0.0.0.0"
fetch(req) {
return new Response(`404!`);
return new Response("404!");
},
});
```
@@ -140,12 +140,6 @@ Bun.serve({
});
```
{% callout %}
**Note** — Earlier versions of Bun supported passing a file path as `keyFile` and `certFile`; this has been deprecated as of `v0.6.3`.
{% /callout %}
If your private key is encrypted with a passphrase, provide a value for `passphrase` to decrypt it.
```ts-diff
@@ -198,7 +192,7 @@ import {type Serve} from "bun";
export default {
fetch(req) {
return new Response(`Bun!`);
return new Response("Bun!");
},
} satisfies Serve;
```
@@ -231,7 +225,7 @@ serve({
⚡️ **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.
{% /callout %}
**[v0.3.0+]** 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.
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.
```ts
Bun.serve({
@@ -260,7 +254,7 @@ Below are Bun and Node.js implementations of a simple HTTP server that responds
```ts#Bun
Bun.serve({
fetch(req: Request) {
return new Response(`Bun!`);
return new Response("Bun!");
},
port: 3000,
});

View File

@@ -39,7 +39,7 @@ import.meta.resolveSync("zod")
---
- `import.meta.resolve{Sync}`
- Resolve a module specifier (e.g. `"zod"` or `"./file.tsx`) to an absolute path. While file would be imported if the specifier were imported from this file?
- Resolve a module specifier (e.g. `"zod"` or `"./file.tsx"`) to an absolute path. While file would be imported if the specifier were imported from this file?
```ts
import.meta.resolveSync("zod");

View File

@@ -28,7 +28,9 @@ By default, the input stream of the subprocess is undefined; it can be configure
```ts
const proc = Bun.spawn(["cat"], {
stdin: await fetch("https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js"),
stdin: await fetch(
"https://raw.githubusercontent.com/oven-sh/bun/main/examples/hashing.js",
),
});
const text = await new Response(proc.stdout).text();
@@ -209,7 +211,7 @@ Bun's `spawnSync` spawns processes 60% faster than the Node.js `child_process` m
```bash
$ bun spawn.mjs
cpu: Apple M1 Max
runtime: bun 0.2.0 (arm64-darwin)
runtime: bun 1.x (arm64-darwin)
benchmark time (avg) (min … max) p75 p99 p995
--------------------------------------------------------- -----------------------------
@@ -230,10 +232,15 @@ A simple reference of the Spawn API and types are shown below. The real types ha
```ts
interface Bun {
spawn(command: string[], options?: SpawnOptions.OptionsObject): Subprocess;
spawnSync(command: string[], options?: SpawnOptions.OptionsObject): SyncSubprocess;
spawnSync(
command: string[],
options?: SpawnOptions.OptionsObject,
): SyncSubprocess;
spawn(options: { cmd: string[] } & SpawnOptions.OptionsObject): Subprocess;
spawnSync(options: { cmd: string[] } & SpawnOptions.OptionsObject): SyncSubprocess;
spawnSync(
options: { cmd: string[] } & SpawnOptions.OptionsObject,
): SyncSubprocess;
}
namespace SpawnOptions {
@@ -243,7 +250,12 @@ namespace SpawnOptions {
stdin?: SpawnOptions.Readable;
stdout?: SpawnOptions.Writable;
stderr?: SpawnOptions.Writable;
onExit?: (proc: Subprocess, exitCode: number | null, signalCode: string | null, error: Error | null) => void;
onExit?: (
proc: Subprocess,
exitCode: number | null,
signalCode: string | null,
error: Error | null,
) => void;
}
type Readable =

View File

@@ -76,12 +76,6 @@ Bun.listen({
});
```
{% callout %}
**Note** Earlier versions of Bun supported passing a file path as `keyFile` and `certFile`; this has been deprecated as of `v0.6.3`.
{% /callout %}
The `key` and `cert` fields expect the _contents_ of your TLS key and certificate. This can be a string, `BunFile`, `TypedArray`, or `Buffer`.
```ts
@@ -95,7 +89,7 @@ Bun.listen({
// string
key: fs.readFileSync("./key.pem", "utf8"),
// array of above
key: [Bun.file('./key1.pem'), Bun.file('./key2.pem')]
key: [Bun.file("./key1.pem"), Bun.file("./key2.pem")],
},
});
```

View File

@@ -76,7 +76,7 @@ await transpiler.transform("<div>hi!</div>", "tsx");
```
{% details summary="Nitty gritty" %}
The `.tranform()` method runs the transpiler in Bun's worker threadpool, so if you run it 100 times, it will run it across `Math.floor($cpu_count * 0.8)` threads, without blocking the main JavaScript thread.
The `.transform()` method runs the transpiler in Bun's worker threadpool, so if you run it 100 times, it will run it across `Math.floor($cpu_count * 0.8)` threads, without blocking the main JavaScript thread.
If your code uses a macro, it will potentially spawn a new copy of Bun's JavaScript runtime environment in that new thread.
{% /details %}
@@ -160,7 +160,6 @@ export const name = "hello";
`;
const result = transpiler.scanImports(code);
`);
```
```json#Results

View File

@@ -43,7 +43,7 @@ This is analogous to the [`require.main = module` trick](https://stackoverflow.c
## `Bun.sleep()`
`Bun.sleep(ms: number)` (added in Bun v0.5.6)
`Bun.sleep(ms: number)`
Returns a `Promise` that resolves after the given number of milliseconds.
@@ -65,7 +65,7 @@ console.log("hello one second later!");
## `Bun.sleepSync()`
`Bun.sleepSync(ms: number)` (added in Bun v0.5.6)
`Bun.sleepSync(ms: number)`
A blocking synchronous version of `Bun.sleep`.
@@ -108,7 +108,7 @@ console.log(ls); // null
## `Bun.peek()`
`Bun.peek(prom: Promise)` (added in Bun v0.2.2)
`Bun.peek(prom: Promise)`
Reads a promise's result without `await` or `.then`, but only if the promise has already fulfilled or rejected.
@@ -204,7 +204,7 @@ Bun.ArrayBufferSink;
## `Bun.deepEquals()`
Nestedly checks if two objects are equivalent. This is used internally by `expect().toEqual()` in `bun:test`.
Recursively checks if two objects are equivalent. This is used internally by `expect().toEqual()` in `bun:test`.
```ts
const foo = { a: 1, b: 2, c: { d: 3 } };

View File

@@ -87,7 +87,7 @@ ws.send(new Uint8Array([1, 2, 3])); // TypedArray | DataView
### Headers
Once the upgrade succeeds, Bun will send a `101 Switching Protocols` response per the [spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism). Additional `headers` can be attched to this `Response` in the call to `server.upgrade()`.
Once the upgrade succeeds, Bun will send a `101 Switching Protocols` response per the [spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism). Additional `headers` can be attached to this `Response` in the call to `server.upgrade()`.
```ts
Bun.serve({
@@ -236,7 +236,11 @@ This gives you better control over backpressure in your server.
## Connect to a `Websocket` server
To connect to an external socket server, either from a browser or from Bun, create an instance of `WebSocket` with the constructor.
{% callout %}
**🚧** — The `WebSocket` client still does not pass the full [Autobahn test suite](https://github.com/crossbario/autobahn-testsuite) and should not be considered ready for production.
{% /callout %}
Bun implements the `WebSocket` class. To create a WebSocket client that connects to a `ws://` or `wss://` server, create an instance of `WebSocket`, as you would in the browser.
```ts
const socket = new WebSocket("ws://localhost:3000");

View File

@@ -1,5 +1,5 @@
{% callout %}
`Worker` support was added in Bun v0.7.0.
**🚧** — The `Worker` API is still experimental and should not be considered ready for production.
{% /callout %}
[`Worker`](https://developer.mozilla.org/en-US/docs/Web/API/Worker) lets you start and communicate with a new JavaScript instance running on a separate thread while sharing I/O resources with the main thread.
@@ -123,7 +123,7 @@ By default, an active `Worker` will keep the main (spawning) process alive, so a
### `worker.unref()`
To stop a running worker from keeping the process alive, call `worker.unref()`. This decouples the lifetime of the worker to the lifetime of the main process, and is equivlent to what Node.js' `worker_threads` does.
To stop a running worker from keeping the process alive, call `worker.unref()`. This decouples the lifetime of the worker to the lifetime of the main process, and is equivalent to what Node.js' `worker_threads` does.
```ts
const worker = new Worker(new URL("worker.ts", import.meta.url).href);

View File

@@ -52,7 +52,6 @@ Run this with `bun cat.js /path/to/big/file`.
## Reading from standard input
```ts
// As of Bun v0.3.0, console is an AsyncIterable
for await (const line of console) {
// line of text from stdin
console.log(line);

View File

@@ -28,7 +28,7 @@ All imported files and packages are bundled into the executable, along with a co
- `--outdir` — use `outfile` instead.
- `--external`
- `--splitting`
- `--publicPath`
- `--public-path`
{% /callout %}

View File

@@ -960,7 +960,7 @@ By specifying `.` as `root`, the generated file structure will look like this:
A prefix to be appended to any import paths in bundled code.
<!-- $ bun build ./index.tsx --outdir ./out --publicPath https://cdn.example.com -->
<!-- $ bun build ./index.tsx --outdir ./out --public-path https://cdn.example.com -->
In many cases, generated bundles will contain no `import` statements. After all, the goal of bundling is to combine all of the code into a single file. However there are a number of cases with the generated bundles will contain `import` statements.

View File

@@ -40,7 +40,7 @@ When a user visits this website, the files are loaded in the following order:
This approach works, it requires three round-trip HTTP requests before the browser is ready to render the page. On slow internet connections, this may add up to a non-trivial delay.
This example is extremely simplistic. A modern app may be loading dozens of modules from `node_modules`, each consisting of hundrends of files. Loading each of these files with a separate HTTP request becomes untenable very quickly. While most of these requests will be running in parallel, the number of round-trip requests can still be very high; plus, there are limits on how many simultaneous requests a browser can make.
This example is extremely simplistic. A modern app may be loading dozens of modules from `node_modules`, each consisting of hundred of files. Loading each of these files with a separate HTTP request becomes untenable very quickly. While most of these requests will be running in parallel, the number of round-trip requests can still be very high; plus, there are limits on how many simultaneous requests a browser can make.
{% callout %}
Some recent advances like modulepreload and HTTP/3 are intended to solve some of these problems, but at the moment bundling is still the most performant approach.

View File

@@ -16,7 +16,7 @@ Parses the code and applies a set of default transforms, like dead-code eliminat
**JavaScript + JSX.**. Default for `.js` and `.jsx`.
Same as the `js` loader, but JSX syntax is supported. By default, JSX is downconverted to plain JavaScript; the details of how this is done depends on the `jsx*` compiler options in your `tsconfig.json`. Refer to the TypeScript documentation [on JSX](https://www.typescriptlang.org/docs/handbook/jsx.html) for more information.
Same as the `js` loader, but JSX syntax is supported. By default, JSX is down-converted to plain JavaScript; the details of how this is done depends on the `jsx*` compiler options in your `tsconfig.json`. Refer to the TypeScript documentation [on JSX](https://www.typescriptlang.org/docs/handbook/jsx.html) for more information.
### `ts`

View File

@@ -129,7 +129,7 @@ if (returnFalse()) {
}
```
## Serializablility
## Serializability
Bun's transpiler needs to be able to serialize the result of the macro so it can be inlined into the AST. All JSON-compatible data structures are supported:

View File

@@ -1,7 +1,3 @@
{% callout %}
**Note** — Introduced in Bun v0.1.11.
{% /callout %}
Bun provides a universal plugin API that can be used to extend both the _runtime_ and _bundler_.
Plugins intercept imports and perform custom loading logic: reading files, transpiling code, etc. They can be used to add support for additional file types, like `.scss` or `.yaml`. In the context of Bun's bundler, plugins can be used to implement framework-level features like CSS extraction, macros, and client-server code co-location.

View File

@@ -1,7 +1,3 @@
{% callout %}
**Note** — Available in Bun v0.6.0 and later.
{% /callout %}
Bun's bundler API is inspired heavily by [esbuild](https://esbuild.github.io/). Migrating to Bun's bundler from esbuild should be relatively painless. This guide will briefly explain why you might consider migrating to Bun's bundler and provide a side-by-side API comparison reference for those who are already familiar with esbuild's API.
There are a few behavioral differences to note.
@@ -129,7 +125,7 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
- `--target`
- n/a
- No supported. Bun's bundler performs no syntactic downleveling at this time.
- No supported. Bun's bundler performs no syntactic down-leveling at this time.
---

View File

@@ -13,8 +13,6 @@ If you pass `-y` or `--yes`, it will assume you want to continue without asking
At the end, it runs `bun install` to install `bun-types`.
Added in Bun v0.1.7.
#### How is `bun init` different than `bun create`?
`bun init` is for blank projects. `bun create` applies templates.

View File

@@ -1,6 +1,6 @@
Bundling is currently an important mechanism for building complex web apps.
Modern apps typically consist of a large number of files and package dependencies. Despite the fact that modern browsers support [ES Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) imports, it's still too slow to fetch each file via inidividual HTTP requests. _Bundling_ is the process of concatenating several source files into a single large file that can be loaded in a single request.
Modern apps typically consist of a large number of files and package dependencies. Despite the fact that modern browsers support [ES Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) imports, it's still too slow to fetch each file via individual HTTP requests. _Bundling_ is the process of concatenating several source files into a single large file that can be loaded in a single request.
{% callout %}
**On bundling** — Despite recent advances like [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) and [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3), bundling is still the most performant approach.

View File

@@ -50,7 +50,7 @@ Running `bun create` performs the following steps:
- Initialize a fresh Git repo. Opt out with the `--no-git` flag.
- Run the template's configured `start` script, if defined.
## Official templates
<!-- ## Official templates
The following official templates are available.
@@ -73,7 +73,7 @@ Welcome to bun! Create a new project by pasting any of the following:
{% callout %}
⚡️ **Speed** — At the time of writing, `bun create react app` runs ~11x faster on a M1 Macbook Pro than `yarn create react-app app`.
{% /callout %}
{% /callout %} -->
## GitHub repos

View File

@@ -69,7 +69,7 @@ $ bun install --silent # no logging
```
{% details summary="Configuring behavior" %}
The default behavior of `bun install` can be configured in `bun.toml`:
The default behavior of `bun install` can be configured in `bunfig.toml`:
```toml
[install]
@@ -197,7 +197,7 @@ $ cat package.json
"version": "1.0.0"
}
$ bun link
bun link v0.5.7 (7416672e)
bun link v1.x (7416672e)
Success! Registered "cool-pkg"
To use cool-pkg in a project, run:
@@ -289,7 +289,7 @@ Bun supports a variety of protocols, including [`github`](https://docs.npmjs.com
## Tarball dependencies
A package name can correspond to a publically hosted `.tgz` file. During `bun install`, Bun will download and install the package from the specified tarball URL, rather than from the package registry.
A package name can correspond to a publicly hosted `.tgz` file. During `bun install`, Bun will download and install the package from the specified tarball URL, rather than from the package registry.
```json#package.json
{

View File

@@ -42,10 +42,6 @@ $ bun --watch run index.tsx
### `--smol`
{% callout %}
Added in Bun v0.7.0.
{% /callout %}
In memory-constrained environments, use the `--smol` flag to reduce memory usage at a cost to performance.
```bash

View File

@@ -1,36 +0,0 @@
[Buchta](https://buchtajs.com) is a fullstack framework designed to take full advantage of Bun's strengths. It currently supports Preact and Svelte.
To get started:
```bash
$ bunx buchta init myapp
Project templates:
- svelte
- default
- preact
Name of template: preact
Do you want TSX? y
Do you want SSR? y
Enable livereload? y
Buchta Preact project was setup successfully!
$ cd myapp
$ bun install
$ bunx buchta serve
```
To implement a simple HTTP server with Buchta:
```ts#server.ts
import { Buchta, type BuchtaRequest, type BuchtaResponse } from "buchta";
const app = new Buchta();
app.get("/api/hello/", (req: BuchtaRequest, res: BuchtaResponse) => {
res.send("Hello, World!");
});
app.run();
```
For more information, refer to Buchta's [documentation](https://buchtajs.com/docs/).

View File

@@ -2,7 +2,7 @@
name: Convert a Blob to a ReadableStream
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.stream()`. This returns `Promise<ReadableStream>`.
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, including `.stream()`. This returns `Promise<ReadableStream>`.
```ts
const blob = new Blob(["hello world"]);

View File

@@ -2,7 +2,7 @@
name: Convert a Blob to a string
---
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, inluding `.text()`.
The [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) class provides a number of methods for consuming its contents in different formats, including `.text()`.
```ts
const blob = new Blob(["hello world"]);

View File

@@ -2,7 +2,7 @@
name: Create a Discord bot
---
Discord.js works [out of the box](https://bun.sh/blog/bun-v0.6.7) with Bun. Let's write a simple bot. First create a directory and initialize it with `bun init`.
Discord.js works out of the box with Bun. Let's write a simple bot. First create a directory and initialize it with `bun init`.
```bash
mkdir my-bot
@@ -74,4 +74,4 @@ Ready! Logged in as my-bot#1234
---
You're up and running with a bare-bones Discord.js bot! This is a basic guide to setting up your bot with Bun; we recommend the [official Discord docs](https://discordjs.guide/) for complete information on the `discord.js` API.
You're up and running with a bare-bones Discord.js bot! This is a basic guide to setting up your bot with Bun; we recommend the [official discord.js docs](https://discordjs.guide/) for complete information on the `discord.js` API.

View File

@@ -33,11 +33,18 @@ const animalSchema = new mongoose.Schema(
{
name: {type: String, required: true},
sound: {type: String, required: true},
},
{
methods: {
speak() {
console.log(`${this.sound}!`);
},
},
}
);
export type Animal = mongoose.InferSchemaType<typeof animalSchema>;
export const Animal = mongoose.model('Kitten', animalSchema);
export const Animal = mongoose.model('Animal', animalSchema);
```
---
@@ -62,13 +69,13 @@ await cow.save(); // saves to the database
const animals = await Animal.find();
animals[0].speak(); // logs "Moo!"
// disconect
// disconnect
await mongoose.disconnect();
```
---
Lets run this with `bun run`.
Let's run this with `bun run`.
```bash
$ bun run index.ts

View File

@@ -9,7 +9,7 @@ $ bunx nuxi init my-nuxt-app
✔ Which package manager would you like to use?
bun
◐ Installing dependencies...
bun install v0.8.1 (16b4bf34)
bun install v1.x (16b4bf34)
+ @nuxt/devtools@0.8.2
+ nuxt@3.7.0
785 packages installed [2.67s]
@@ -45,9 +45,9 @@ Nuxt 3.6.5 with Nitro 2.5.2
---
Once the dev server spins up, open [http://localhost:3000](http://localhost:3000) to see the app. The app will render Nuxt's built-in `WelcomePage` template component.
Once the dev server spins up, open [http://localhost:3000](http://localhost:3000) to see the app. The app will render Nuxt's built-in `NuxtWelcome` template component.
To start developing your app, replace `<WelcomePage />` in `app.vue` with your own UI.
To start developing your app, replace `<NuxtWelcome />` in `app.vue` with your own UI.
{% image src="https://github.com/oven-sh/bun/assets/3084745/2c683ecc-3298-4bb0-b8c0-cf4cfaea1daa" caption="Demo Nuxt app running on localhost" /%}

View File

@@ -30,7 +30,7 @@ cloned solidjs/solid-start#main to /path/to/my-app/.solid-start
---
As instructed by the `create-solid` CLI, lets install our dependencies.
As instructed by the `create-solid` CLI, let's install our dependencies.
```sh
$ cd my-app

View File

@@ -2,7 +2,7 @@
name: Build an app with SvelteKit and Bun
---
Use `bunx` to scaffold your app with the `create-svelte` CLI. Answer the prompts to slect a template and set up your development environment.
Use `bunx` to scaffold your app with the `create-svelte` CLI. Answer the prompts to select a template and set up your development environment.
```sh
$ bunx create-svelte my-app
@@ -63,3 +63,58 @@ Visit [http://localhost:5173](http://localhost:5173/) in a browser to see the te
---
If you edit and save `src/routes/+page.svelte`, you should see your changes hot-reloaded in the browser.
---
To build for production, you'll need to add the right SvelteKit adapter. Currently we recommend the
`bun add -D svelte-adapter-bun`.
Now, make the following changes to your `svelte.config.js`.
```ts-diff
- import adapter from "@sveltejs/adapter-auto";
+ import adapter from "svelte-adapter-bun";
import { vitePreprocess } from "@sveltejs/kit/vite";
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter(),
},
preprocess: vitePreprocess(),
};
export default config;
```
---
To build a production bundle:
```sh
$ bun run build
$ vite build
vite v4.4.9 building SSR bundle for production...
transforming (60) node_modules/@sveltejs/kit/src/utils/escape.js
✓ 98 modules transformed.
Generated an empty chunk: "entries/endpoints/waitlist/_server.ts".
vite v4.4.9 building for production...
✓ 92 modules transformed.
Generated an empty chunk: "7".
.svelte-kit/output/client/_app/version.json 0.03 kB │ gzip: 0.05 kB
...
.svelte-kit/output/server/index.js 86.47 kB
Run npm run preview to preview your production build locally.
> Using svelte-adapter-bun
✔ Start server with: bun ./build/index.js
✔ done
✓ built in 7.81s
```

View File

@@ -8,7 +8,7 @@ While Vite currently works with Bun, it has not been heavily optimized, nor has
---
Vite works out of the box with Bun (v0.7 and later). Get started with one of Vite's templates.
Vite works out of the box with Bun. Get started with one of Vite's templates.
```bash
$ bunx create-vite my-app

View File

@@ -59,7 +59,7 @@ Listening on http://localhost:4000
Our form will send a `POST` request to the `/action` endpoint with the form data. Let's handle that request in our server.
First we use the [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) method on the incoming `Request` to asynchonously parse its contents to a `FormData` instance. Then we can use the [`.get()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get) method to extract the value of the `name` and `profilePicture` fields. Here `name` corresponds to a `string` and `profilePicture` is a `Blob`.
First we use the [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/API/Request/formData) method on the incoming `Request` to asynchronously parse its contents to a `FormData` instance. Then we can use the [`.get()`](https://developer.mozilla.org/en-US/docs/Web/API/FormData/get) method to extract the value of the `name` and `profilePicture` fields. Here `name` corresponds to a `string` and `profilePicture` is a `Blob`.
Finally, we write the `Blob` to disk using [`Bun.write()`](/docs/api/file-io#writing-files-bun-write).
@@ -81,7 +81,7 @@ const server = Bun.serve({
+ if (url.pathname === '/action') {
+ const formdata = await req.formData();
+ const name = formdata.get('name');
+ const profilePicture = formdata.get('profilePicture');+
+ const profilePicture = formdata.get('profilePicture');
+ if (!profilePicture) throw new Error('Must upload a profile picture.');
+ // write profilePicture to disk
+ await Bun.write('profilePicture.png', profilePicture);

View File

@@ -0,0 +1,29 @@
---
name: Add a trusted dependency
---
Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for installed dependencies, such as `postinstall` and `node-gyp` builds. These scripts represent a potential security risk, as they can execute arbitrary code on your machine.
---
To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json.
```json-diff
{
"name": "my-app",
"version": "1.0.0",
+ "trustedDependencies": ["my-trusted-package"]
}
```
<!-- Bun maintains an allow-list of popular packages containing `postinstall` scripts that are known to be safe. To run lifecycle scripts for packages that aren't on this list, add the package to `trustedDependencies` in your package.json. -->
---
Note that this only allows lifecycle scripts for the specific package listed in `trustedDependencies`, _not_ the dependencies of that dependency!
Soon, Bun will include a built-in allow-list that automatically allows lifecycle scripts to be run by popular packages that are known to be safe. This is still under development.
---
See [Docs > Package manager > Trusted dependencies](/docs/cli/install#trusted-dependencies) for complete documentation of trusted dependencies.

View File

@@ -35,7 +35,7 @@ It's common to place all packages in a `packages` directory. The `"workspaces"`
---
To add one workspace as a dependency of another, modify its `package.json`. Here were adding `stuff-a` as a dependency of `stuff-b`.
To add one workspace as a dependency of another, modify its `package.json`. Here we're adding `stuff-a` as a dependency of `stuff-b`.
```json#packages/stuff-b/package.json
{

View File

@@ -8,7 +8,7 @@ The `Bun.file()` function accepts a path and returns a `BunFile` instance. Use t
const path = "/path/to/package.json";
const file = Bun.file(path);
file.exists(); // boolean;
await file.exists(); // boolean;
```
---

View File

@@ -0,0 +1,41 @@
---
name: Debugging Bun with the VS Code extension
---
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-vscode/types/jsc.d.ts) so you can debug your code with an interactive debugger.
---
To install the extension, visit the [Bun for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=oven.bun-vscode) page on the VS Code marketplace website, then click Install.
{% image src="https://github.com/oven-sh/bun/assets/3084745/7c8c80e6-d49e-457a-a45e-45ebed946d56" /%}
---
Alternatively, search `bun-vscode` in the Extensions tab of VS Code.
{% image src="https://github.com/oven-sh/bun/assets/3084745/664b4c40-944c-4076-a4c2-f812aebd3dc9" /%}
---
Make sure you are installing the extension published by the verified Oven organization.
{% image src="https://github.com/oven-sh/bun/assets/3084745/73e6b09f-9ff1-4d85-b725-c5eb7215b6ae" /%}
---
Once installed, two new Bun-specific commands will appear in the Command Palette. To open the palette, click View > Command Palette, or type `Ctrl+Shift+P` (Windows, Linux) or `Cmd+Shift+P` on (Mac).
---
The `Bun: Run File` command will execute your code and print the output to the Debug Console in VS Code. Breakpoints will be ignored; this is similar to executing the file with `bun <file>` from the command line.
{% image src="https://github.com/oven-sh/bun/assets/3084745/1b2c7fd9-fbb9-486a-84d0-eb7ec135ded3" /%}
---
The `Bun: Debug File` command will execute your code and print the output to the Debug Console in VS Code. You can set breakpoints in your code by clicking to the left of a line number; a red dot should appear.
When you run the file with `Bun: Debug File`, execution will pause at the breakpoint. You can inspect the variables in scope and step through the code line-by-line using the VS Code controls.
{% image src="https://github.com/oven-sh/bun/assets/3084745/c579a36c-eb21-4a58-bc9c-74612aad82af" /%}

View File

@@ -49,7 +49,7 @@ test("set button text", () => {
---
With Happy DOM propertly configured, this test runs as expected.
With Happy DOM properly configured, this test runs as expected.
```sh
$ bun test

View File

@@ -0,0 +1,112 @@
---
name: Migrate from Jest to Bun's test runner
---
In many cases, Bun's test runner can run Jest test suites with no code changes. Just run `bun test` instead of `npx jest`, `yarn test`, etc.
```sh-diff
- $ npx jest
- $ yarn test
+ $ bun test
```
---
There's often no need for code changes.
- Bun internally re-writes imports from `@jest/globals` to use the `bun:test` equivalents.
- If you're relying on Jest to inject `test`, `expect`, etc. as globals, Bun does that too.
But if you'd rather switch to the `bun:test` imports, you can do that too.
```ts-diff
- import {test, expect} from "@jest/globals";
+ import {test, expect} from "bun:test";
```
---
Bun implements the vast majority of Jest's matchers, but compatibility isn't 100% yet. Refer to the full compatibility table at [Docs > Test runner > Writing tests](/docs/test/writing#matchers).
Some notable missing features:
- `expect.extend()`
- `expect().toMatchInlineSnapshot()`
- `expect().toHaveBeenCalledWith()`
- `expect().toHaveReturned()`
---
If you're using `testEnvironment: "jsdom"` to run your tests in a browser-like environment, you should follow the [DOM testing with Bun and happy-dom](/guides/test/happy-dom) guide to inject browser APIs into the global scope. This guide relies on [`happy-dom`](https://github.com/capricorn86/happy-dom), which is a leaner and faster alternative to [`jsdom`](https://github.com/jsdom/jsdom).
At the moment jsdom does not work in Bun due to its internal use of V8 APIs. Track support for it [here](https://github.com/oven-sh/bun/issues/3554).
```toml#bunfig.toml
[test]
preload = ["./happy-dom.ts"]
```
---
Replace `bail` in your Jest config with the `--bail` CLI flag.
<!-- ```ts-diff
- import type {Config} from 'jest';
-
- const config: Config = {
- bail: 3
- };
``` -->
```sh-diff
$ bun test --bail 3
```
---
Replace `collectCoverage` with the `--coverage` CLI flag.
<!-- ```ts-diff
- import type {Config} from 'jest';
-
- const config: Config = {
- collectCoverageFrom: [
- '**/*.{js,jsx}',
- '!**/node_modules/**',
- '!**/vendor/**',
- ],
- };
``` -->
```sh
$ bun test --coverage
```
---
Replace `testTimeout` with the `--test-timeout` CLI flag.
```sh
$ bun test --timeout 10000
```
---
Many other flags become irrelevant or obsolete when using `bun test`.
- `transform` — Buns supports TypeScript & JSX. Other file types can be configured with [Plugins](/docs/runtime/plugins).
- `extensionsToTreatAsEsm`
- `haste` — Bun uses it's own internal source maps
- `watchman`, `watchPlugins`, `watchPathIgnorePatterns` — use `--watch` to run tests in watch mode
- `verbose` — set `logLevel: "debug"` in [`bunfig.toml`](/docs/runtime/configuration.md#runtime)
---
Settings that aren't mentioned here are not supported or have no equivalent. Please [file a feature request](https://github.com/oven-sh/bun) if something important is missing.
---
See also:
- [Mark a test as a todo](/guides/test/todo-tests)
- [Docs > Test runner > Writing tests](/docs/test/writing)

View File

@@ -21,7 +21,7 @@ Here's what the output of a typical test run looks like. In this case, there are
```sh
$ bun test
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test.test.js:
✓ add [0.87ms]
@@ -47,7 +47,7 @@ To only run certain test files, pass a positional argument to `bun test`. The ru
```sh
$ bun test test3
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test3.test.js:
✓ add [1.40ms]
@@ -85,7 +85,7 @@ Adding `-t add` will only run tests with "add" in the name. This works with test
```sh
$ bun test -t add
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test.test.js:
✓ add [1.79ms]

View File

@@ -22,7 +22,7 @@ The first time this test is executed, Bun will evaluate the value passed into `e
```sh
$ bun test test/snap
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test/snap.test.ts:
✓ snapshot [1.48ms]
@@ -65,7 +65,7 @@ Later, when this test file is executed again, Bun will read the snapshot file an
```sh
$ bun test
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test/snap.test.ts:
✓ snapshot [1.05ms]
@@ -82,7 +82,7 @@ To update snapshots, use the `--update-snapshots` flag.
```sh
$ bun test --update-snapshots
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test/snap.test.ts:
✓ snapshot [0.86ms]

View File

@@ -36,7 +36,7 @@ Once the spy is created, it can be used to write `expect` assertions relating to
+ test("turtles", ()=>{
+ expect(spy).toHaveBeenCalledTimes(0);
+ leo.sayHi("pizza");
+ expect(spy).toHaveBeenCalledTimes(0);
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy.mock.calls).toEqual([[ "pizza" ]]);
+ })
```

View File

@@ -44,7 +44,7 @@ test.todo("unimplemented feature", () => {
---
If an implementation is provides, it will be executed and _expected to fail_ by test runner! If a todo test passes, the `bun test` run will return a non-zero exit code to signal the failure.
If an implementation is provided, it will be executed and _expected to fail_ by test runner! If a todo test passes, the `bun test` run will return a non-zero exit code to signal the failure.
```sh
$ bun test

View File

@@ -33,7 +33,7 @@ To regenerate snapshots, use the `--update-snapshots` flag.
```sh
$ bun test --update-snapshots
bun test v0.8.0 (9c68abdb)
bun test v1.x (9c68abdb)
test/snap.test.ts:
✓ snapshot [0.86ms]

View File

@@ -6,7 +6,7 @@ Use `Bun.gzipSync()` to compress a `Uint8Array` with gzip.
```ts
const data = Buffer.from("Hello, world!");
const compressed = Bun.gzipSync("Hello, world!");
const compressed = Bun.gzipSync(data);
// => Uint8Array
const decompressed = Bun.gunzipSync(compressed);

View File

@@ -24,7 +24,7 @@ Bun.serve({
websocket: {
async message(ws, message) {
// send a compressed message
ws.send("Hello world!", true);
ws.send(message, true);
},
},
});

View File

@@ -29,5 +29,5 @@ const server = Bun.serve<{ authToken: string }>({
},
});
console.log(`Listening on localhost:\${server.port}`);
console.log(`Listening on localhost:${server.port}`);
```

View File

@@ -66,7 +66,7 @@ Bun is designed from the ground-up with today's JavaScript ecosystem in mind.
- **TypeScript & JSX support**. You can directly execute `.jsx`, `.ts`, and `.tsx` files; Bun's transpiler converts these to vanilla JavaScript before execution.
- **ESM & CommonJS compatibility**. The world is moving towards ES modules (ESM), but millions of packages on npm still require CommonJS. Bun recommends ES modules, but supports CommonJS.
- **Web-standard APIs**. Bun implements standard Web APIs like `fetch`, `WebSocket`, and `ReadableStream`. Bun is powered by the JavaScriptCore engine, which is developed by Apple for Safari, so some APIs like [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) directly use [Safari's implementation](https://github.com/oven-sh/bun/blob/HEAD/src/bun.js/bindings/webcore/JSFetchHeaders.cpp).
- **Node.js compatibility**. In addition to supporting Node-style module resolution, Bun aims for full compatibility with built-in Node.js globals (`process`, `Buffer`) and modules (`path`, `fs`, `http`, etc.) _This is an ongoing effort that is not complete._ Refer to the compatibility page for the current status.
- **Node.js compatibility**. In addition to supporting Node-style module resolution, Bun aims for full compatibility with built-in Node.js globals (`process`, `Buffer`) and modules (`path`, `fs`, `http`, etc.) _This is an ongoing effort that is not complete._ Refer to the [compatibility page](https://bun.sh/docs/runtime/nodejs-apis) for the current status.
Bun is more than a runtime. The long-term goal is to be a cohesive, infrastructural toolkit for building apps with JavaScript/TypeScript, including a package manager, transpiler, bundler, script runner, test runner, and more.

View File

@@ -46,7 +46,7 @@ This behavior is configurable with the `--backend` flag, which is respected by a
- **`clonefile`** Default on macOS.
- **`clonefile_each_dir`**: Similar to `clonefile`, except it clones each file individually per directory. It is only available on macOS and tends to perform slower than `clonefile`.
- **`copyfile`**: The fallback used when any of the above fail. It is the slowest option. On macOS, it uses `fcopyfile()`; on Linux it uses `copy_file_range()`.
**`symlink`**: Currently used only `file:` (and eventually `link:`) dependencies. To prevent infinite loops, it skips symlinking the `node_modules` folder.
- **`symlink`**: Currently used only `file:` (and eventually `link:`) dependencies. To prevent infinite loops, it skips symlinking the `node_modules` folder.
If you install with `--backend=symlink`, Node.js won't resolve node_modules of dependencies unless each dependency has its own `node_modules` folder or you pass `--preserve-symlinks` to `node`. See [Node.js documentation on `--preserve-symlinks`](https://nodejs.org/api/cli.html#--preserve-symlinks).

View File

@@ -69,7 +69,7 @@ $ bun install --silent # no logging
```
{% details summary="Configuring behavior" %}
The default behavior of `bun install` can be configured in `bun.toml`:
The default behavior of `bun install` can be configured in `bunfig.toml`:
```toml
[install]
@@ -188,7 +188,7 @@ Bun supports a variety of protocols, including [`github`](https://docs.npmjs.com
## Tarball dependencies
A package name can correspond to a publically hosted `.tgz` file. During `bun install`, Bun will download and install the package from the specified tarball URL, rather than from the package registry.
A package name can correspond to a publicly hosted `.tgz` file. During `bun install`, Bun will download and install the package from the specified tarball URL, rather than from the package registry.
```json#package.json
{

View File

@@ -10,32 +10,26 @@ Run `bun install -y` to generate a Yarn-compatible `yarn.lock` (v1) that can be
#### How do I `git diff` Bun's lockfile?
To add to the global gitattributes file:
- First try `$XDG_CONFIG_HOME/git/attributes`
- If `$XDG_CONFIG_HOME` is not set, try `~/.config/git/attributes`
For example, on macOS, add the following to `~/.config/git/attributes`:
Add the following to your local or global `.gitattributes` file:
```
*.lockb diff=lockb
*.lockb binary diff=lockb
```
Then add the following to `~/.gitconfig`:
```
[diff "lockb"]
textconv = bun
binary = true
```
To only add to the local gitattributes file:
Then add the following to you local git config with:
```sh
$ git config diff.lockb.textconv bun
$ git config diff.lockb.binary true
```
Or to your global git config (system-wide) with the `--global` option:
```sh
$ git config --global diff.lockb.textconv bun
$ git config --global diff.lockb.binary true
```
**Why this works:**
- `textconv` tells git to run `bun` on the file before diffing

View File

@@ -11,7 +11,7 @@ To try it, specify a list of sub-packages in the `workspaces` field of your `pac
```
{% callout %}
**Glob support** — Bun v0.5.8 added support for simple `<directory>/*` globs in `"workspaces"`. Full glob syntax (e.g. `**` and `?`) is not yet supported (soon!).
**Glob support** — Bun supports simple `<directory>/*` globs in `"workspaces"`. Full glob syntax (e.g. `**` and `?`) is not yet supported.
{% /callout %}
This has a couple major benefits.

View File

@@ -1,14 +1,14 @@
Bun ships as a single executable that can be installed a few different ways.
{% callout %}
**Windows users** — Bun does not currently provide a native Windows build. We're working on this; progress can be tracked at [this issue](https://github.com/oven-sh/bun/issues/43). In the meantime, use one of the installation methods below for Windows Subsystem for Linux.
## macOS and Linux
{% callout %}
**Linux users** — The `unzip` package is required to install Bun. Kernel version 5.6 or higher is strongly recommended, but the minimum is 5.1.
{% /callout %}
{% codetabs %}
```bash#Native
```bash#macOS/Linux_(curl)
$ curl -fsSL https://bun.sh/install | bash # for macOS, Linux, and WSL
```
@@ -32,6 +32,20 @@ $ proto install bun
{% /codetabs %}
## Windows
Bun provides a _limited, experimental_ native build for Windows. At the moment, only the Bun runtime is supported.
- `bun <file>`
- `bun run <file>`
The test runner, package manager, and bundler are still under development. The following commands have been disabled.
- `bun test`
- `bun install/add/remove`
- `bun link/unlink`
- `bun build`
## Upgrading
Once installed, the binary can upgrade itself.
@@ -135,3 +149,27 @@ To write the completions to a custom location:
$ bun completions > path-to-file # write to file
$ bun completions /path/to/directory # write into directory
```
## Uninstall
If you need to remove Bun from your system, use the following commands.
{% codetabs %}
```bash#macOS/Linux_(curl)
$ rm -rf ~/.bun # for macOS, Linux, and WSL
```
```bash#NPM
$ npm uninstall -g bun
```
```bash#Homebrew
$ brew uninstall bun
```
```bash#Proto
$ proto uninstall bun
```
{% /codetabs %}

View File

@@ -166,7 +166,7 @@ export default {
divider("Bundler"),
page("bundler", "`Bun.build`", {
description: "Bundle code for comsumption in the browser with Bun's native bundler.",
description: "Bundle code for consumption in the browser with Bun's native bundler.",
}),
// page("bundler/intro", "How bundlers work", {
// description: "A visual introduction to bundling",

View File

@@ -46,7 +46,8 @@ $ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 15 all
```
```bash#Arch
$ sudo pacman -S llvm clang lld
$ sudo pacman -S llvm15 clang15 lld
```
{% /codetabs %}
@@ -70,6 +71,14 @@ $ export LDFLAGS="$LDFLAGS -L$(brew --prefix llvm@15)/lib"
$ export CPPFLAGS="$CPPFLAGS -I$(brew --prefix llvm@15)/include"
```
```bash#Arch
$ export PATH="$PATH:/usr/lib/llvm15/bin"
$ export LDFLAGS="$LDFLAGS -L/usr/lib/llvm15/lib"
$ export CPPFLAGS="$CPPFLAGS -I/usr/lib/llvm15/include"
```
{% /codetabs %}
## Install Dependencies
@@ -127,11 +136,11 @@ After cloning the repository, run the following command to run the first build.
$ make setup
```
The binary will be located at `packages/debug-bun-{platform}-{arch}/bun-debug`. It is recommended to add this to your `$PATH`. To verify the build worked, lets print the version number on the development build of Bun.
The binary will be located at `packages/debug-bun-{platform}-{arch}/bun-debug`. It is recommended to add this to your `$PATH`. To verify the build worked, let's print the version number on the development build of Bun.
```bash
$ packages/debug-bun-*/bun-debug --version
bun 0.x.y__dev
bun 1.x.y__dev
```
Note: `make setup` is just an alias for the following:
@@ -192,7 +201,7 @@ Bun uses a series of make commands to rebuild parts of the codebase. The general
---
- Code using `cppFn`/`JSC.markBinding`
- `make headers` (TODO: explain explain what this is used for and why it's useful)
- `make headers` (TODO: explain what this is used for and why it's useful)
{% /table %}

View File

@@ -95,7 +95,7 @@ Bun statically links these libraries:
---
- Parts of Tigerbeetle's IO code https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1
- Parts of [Tigerbeetle's IO code](https://github.com/tigerbeetle/tigerbeetle/blob/532c8b70b9142c17e07737ab6d3da68d7500cbca/src/io/windows.zig#L1)
- Apache 2.0 licensed
{% /table %}

View File

@@ -1,4 +1,4 @@
Bun is a project with an incredibly large scope and is still in its early days. Long-term, Bun aims to provide an all-in-one tookit to replace the complex, fragmented toolchains common today: Node.js, Jest, Webpack, esbuild, Babel, yarn, PostCSS, etc.
Bun is a project with an incredibly large scope and is still in its early days. Long-term, Bun aims to provide an all-in-one toolkit to replace the complex, fragmented toolchains common today: Node.js, Jest, Webpack, esbuild, Babel, yarn, PostCSS, etc.
Refer to [Bun's Roadmap](https://github.com/oven-sh/bun/issues/159) on GitHub to learn more about the project's long-term plans and priorities.

View File

@@ -35,18 +35,18 @@ Open `index.ts` and paste the following code snippet, which implements a simple
const server = Bun.serve({
port: 3000,
fetch(req) {
return new Response(`Bun!`);
return new Response("Bun!");
},
});
console.log(`Listening on http://localhost:${server.port}...`);
console.log(`Listening on http://localhost:${server.port} ...`);
```
Run the file from your shell.
```bash
$ bun index.ts
Listening at http://localhost:3000...
Listening on http://localhost:3000 ...
```
Visit [http://localhost:3000](http://localhost:3000) to test the server. You should see a simple page that says "Bun!".
@@ -97,9 +97,9 @@ Update `index.ts` to use `figlet` in the `fetch` handler.
const server = Bun.serve({
fetch() {
+ const body = figlet.textSync('Bun!');
+ const body = figlet.textSync("Bun!");
+ return new Response(body);
- return new Response(`Bun!`);
- return new Response("Bun!");
},
port: 3000,
});

View File

@@ -1,7 +1,3 @@
{% callout %}
**Note** — Added in Bun v0.3.0
{% /callout %}
If no `node_modules` directory is found in the working directory or higher, Bun will abandon Node.js-style module resolution in favor of the **Bun module resolution algorithm**.
Under Bun-style module resolution, all imported packages are auto-installed on the fly into a [global module cache](/docs/install/cache) during execution (the same cache used by [`bun install`](/docs/cli/install)).

View File

@@ -10,9 +10,11 @@ You can also create a global configuration file at the following paths:
- `$HOME/.bunfig.toml`
- `$XDG_CONFIG_HOME/.bunfig.toml`
If both a global and local `bunfig` are detected, the results are shallow-merged, with local overridding global. CLI flags will override `bunfig` setting where applicable.
If both a global and local `bunfig` are detected, the results are shallow-merged, with local overriding global. CLI flags will override `bunfig` setting where applicable.
## Runtime
## `bunfig.toml`
### Runtime
```toml
# scripts to run before `bun run`ning a file or script
@@ -42,7 +44,7 @@ logLevel = "debug" # "debug", "warn", "error"
".bagel" = "js"
```
## Test runner
### Test runner
```toml
[test]
@@ -53,7 +55,7 @@ preload = ["./setup.ts"]
smol = true
```
## Package manager
### Package manager
Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured in [`bunfig.toml`](/docs/runtime/configuration).

View File

@@ -2,7 +2,7 @@
name: Debugger
---
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-vscode/types/jsc.d.ts). For demonstration purposes, consider the following simple web server.
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-vscode/types/jsc.d.ts), so you can debug your code with an interactive debugger. For demonstration purposes, consider the following simple web server.
```ts#server.ts
Bun.serve({
@@ -48,7 +48,7 @@ $ bun --inspect=localhost:4000/prefix server.ts
## Debuggers
Various debugging tools can connect to this server to provide an interactive debugging experience. Bun hosts a web-based debugger at [debug.bun.sh](https://debug.bun.sh). It is a modified version of WebKit's [Web Inspector Interface](https://webkit.org/web-inspector/web-inspector-interface/), which will look familiar to Safari users.
Various debugging tools can connect to this server to provide an interactive debugging experience.
### `debug.bun.sh`

View File

@@ -1,7 +1,7 @@
Bun supports two kinds of automatic reloading via CLI flags:
- `--watch` mode, which hard restarts Bun's process when imported files change (introduced in Bun v0.5.9)
- `--hot` mode, which soft reloads the code (without restarting the process) when imported files change (introduced in Bun v0.2.0)
- `--watch` mode, which hard restarts Bun's process when imported files change/
- `--hot` mode, which soft reloads the code (without restarting the process) when imported files change.
## `--watch` mode
@@ -117,7 +117,7 @@ serve({
The file above is simply exporting an object with a `fetch` handler defined. When this file is executed, Bun interprets this as an HTTP server and passes the exported object into `Bun.serve`.
When you save the file, your HTTP server be reloaded with the updated code without the process being restarted. This results in seriously fast refresh speeds.
When you save the file, your HTTP server will be reloaded with the updated code without the process being restarted. This results in seriously fast refresh speeds.
{% image src="https://user-images.githubusercontent.com/709451/195477632-5fd8a73e-014d-4589-9ba2-e075ad9eb040.gif" alt="Bun vs Nodemon refresh speeds" caption="Bun on the left, Nodemon on the right." /%}

View File

@@ -2,7 +2,7 @@ Bun is a new JavaScript & TypeScript runtime designed to be a faster, leaner, an
## Speed
Bun is designed to start fast and run fast. It's transpiler and runtime are written in Zig, a modern, high-performance language. On Linux, this translates into startup times [4x faster](https://twitter.com/jarredsumner/status/1499225725492076544) than Node.js.
Bun is designed to start fast and run fast. Its transpiler and runtime are written in Zig, a modern, high-performance language. On Linux, this translates into startup times [4x faster](https://twitter.com/jarredsumner/status/1499225725492076544) than Node.js.
{% image src="/images/bun-run-speed.jpeg" caption="Bun vs Node.js vs Deno running Hello World" /%}
@@ -27,7 +27,7 @@ Some aspects of Bun's runtime behavior are affected by the contents of your `tsc
<!--
every file before execution. It's transpiler can directly run TypeScript and JSX `{.js|.jsx|.ts|.tsx}` files directly. During execution, Bun internally transpiles all files (including `.js` files) to vanilla JavaScript with it's fast native transpiler. -->
every file before execution. Its transpiler can directly run TypeScript and JSX `{.js|.jsx|.ts|.tsx}` files directly. During execution, Bun internally transpiles all files (including `.js` files) to vanilla JavaScript with its fast native transpiler. -->
<!-- A loader determines how to map imports &amp; file extensions to transforms and output. -->
@@ -103,7 +103,11 @@ import bunfig from "./bunfig.toml";
## WASM
As of v0.5.2, experimental support exists for WASI, the [WebAssembly System Interface](https://github.com/WebAssembly/WASI). To run a `.wasm` binary with Bun:
{% callout %}
🚧 **Experimental**
{% /callout %}
Bun has experimental support for WASI, the [WebAssembly System Interface](https://github.com/WebAssembly/WASI). To run a `.wasm` binary with Bun:
```bash
$ bun ./my-wasm-app.wasm
@@ -113,7 +117,7 @@ $ bun run ./my-wasm-app.whatever
{% callout %}
**Note** — WASI support is based on [wasi-js](https://github.com/sagemathinc/cowasm/tree/main/packages/wasi-js). Currently, it only supports WASI binaries that use the `wasi_snapshot_preview1` or `wasi_unstable` APIs. Bun's implementation is not fully optimized for performance; this will become more of a priority as WASM grows in popularity.
**Note** — WASI support is based on [wasi-js](https://github.com/sagemathinc/cowasm/tree/main/core/wasi-js). Currently, it only supports WASI binaries that use the `wasi_snapshot_preview1` or `wasi_unstable` APIs. Bun's implementation is not fully optimized for performance; this will become more of a priority as WASM grows in popularity.
{% /callout %}
## Node.js compatibility

View File

@@ -175,7 +175,7 @@ The function name used to represent [JSX fragments](https://react.dev/reference/
// output
import { myjsx, MyFragment } from "react";
createElement("Box", { width: 5 }, "Hello");
myjsx(MyFragment, null, "Hello");
```
{% /table %}

View File

@@ -36,10 +36,6 @@ $ bun run react.tsx
## Text files
{% callout %}
Supported in Bun v0.6.0 canary.
{% /callout %}
Text files can be imported as strings.
{% codetabs %}
@@ -67,7 +63,11 @@ import data from "./data.toml";
## WASM
As of v0.5.2, experimental support exists for WASI, the [WebAssembly System Interface](https://github.com/WebAssembly/WASI). To run a `.wasm` binary with Bun:
{% callout %}
🚧 **Experimental**
{% /callout %}
Bun has experimental support for WASI, the [WebAssembly System Interface](https://github.com/WebAssembly/WASI). To run a `.wasm` binary with Bun:
```bash
$ bun ./my-wasm-app.wasm
@@ -77,7 +77,7 @@ $ bun run ./my-wasm-app.whatever
{% callout %}
**Note** — WASI support is based on [wasi-js](https://github.com/sagemathinc/cowasm/tree/main/packages/wasi-js). Currently, it only supports WASI binaries that use the `wasi_snapshot_preview1` or `wasi_unstable` APIs. Bun's implementation is not fully optimized for performance; this will become more of a priority as WASM grows in popularity.
**Note** — WASI support is based on [wasi-js](https://github.com/sagemathinc/cowasm/tree/main/core/wasi-js). Currently, it only supports WASI binaries that use the `wasi_snapshot_preview1` or `wasi_unstable` APIs. Bun's implementation is not fully optimized for performance; this will become more of a priority as WASM grows in popularity.
{% /callout %}
## Custom loaders

View File

@@ -31,7 +31,7 @@ $ bun index.ts
Hello world!
```
In this case, we are importing from `./hello`, a relative path with no extension. To resolve this import, Bun will check for the following files in order:
In this case, we are importing from `./hello`, a relative path with no extension. **Extensioned imports are optional but supported.** To resolve this import, Bun will check for the following files in order:
- `./hello.ts`
- `./hello.tsx`
@@ -43,7 +43,7 @@ In this case, we are importing from `./hello`, a relative path with no extension
- `./hello/index.json`
- `./hello/index.mjs`
Import paths are case-insensitive.
Import paths are case-insensitive, meaning these are all valid imports:
```ts#index.ts
import { hello } from "./hello";
@@ -58,7 +58,7 @@ import { hello } from "./hello";
import { hello } from "./hello.ts"; // this works
```
There is one exception: if you import `from "*.js{x}"`, Bun will additionally check for a matching `*.ts{x}` file, to be compatible with TypeScript's [ES module support](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#new-file-extensions).
If you import `from "*.js{x}"`, Bun will additionally check for a matching `*.ts{x}` file, to be compatible with TypeScript's [ES module support](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#new-file-extensions).
```ts#index.ts
import { hello } from "./hello";
@@ -88,7 +88,75 @@ exports.hello = hello;
That said, using CommonJS is discouraged in new projects.
## Resolution
## Module systems
Bun has native support for CommonJS and ES modules. ES Modules are the recommended module format for new projects, but CommonJS modules are still widely used in the Node.js ecosystem.
In Bun's JavaScript runtime, `require` can be used by both ES Modules and CommonJS modules. If the target module is an ES Module, `require` returns the module namespace object (equivalent to `import * as`). If the target module is a CommonJS module, `require` returns the `module.exports` object (as in Node.js).
| Module Type | `require()` | `import * as` |
| ----------- | ---------------- | ----------------------------------------------------------------------- |
| ES Module | Module Namespace | Module Namespace |
| CommonJS | module.exports | `default` is `module.exports`, keys of module.exports are named exports |
### Using `require()`
You can `require()` any file or package, even `.ts` or `.mjs` files.
```ts
const { foo } = require("./foo"); // extensions are optional
const { bar } = require("./bar.mjs");
const { baz } = require("./baz.tsx");
```
{% details summary="What is a CommonJS module?" %}
In 2016, ECMAScript added support for [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). ES Modules are the standard for JavaScript modules. However, millions of npm packages still use CommonJS modules.
CommonJS modules are modules that use `module.exports` to export values. Typically, `require` is used to import CommonJS modules.
```ts
// my-commonjs.cjs
const stuff = require("./stuff");
module.exports = { stuff };
```
The biggest difference between CommonJS and ES Modules is that CommonJS modules are synchronous, while ES Modules are asynchronous. There are other differences too.
- ES Modules support top-level `await` and CommonJS modules don't.
- ES Modules are always in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), while CommonJS modules are not.
- Browsers do not have native support for CommonJS modules, but they do have native support for ES Modules via `<script type="module">`.
- CommonJS modules are not statically analyzable, while ES Modules only allow static imports and exports.
{% /details %}
### Using `import`
You can `import` any file or package, even `.cjs` files.
```ts
const { foo } = require("./foo"); // extensions are optional
const { bar } = require("./bar.mjs");
const { baz } = require("./my-typescript.tsx");
```
### Using `import` and `require()` together
In Bun, you can use `import` or `require` in the same file—they both work, all the time.
```ts
import { stuff } from "./my-commonjs.cjs";
import Stuff from "./my-commonjs.cjs";
const myStuff = require("./my-commonjs.cjs");
```
### Top level await
The only exception to this rule is top-level await. You can't `require()` a file that uses top-level await, since the `require()` function is inherently synchronous.
Fortunately, very few libraries use top-level await, so this is rarely a problem. But if you're using top-level await in your application code, make sure that file isn't being `require()` from elsewhere in your application. Instead, you should use `import` or [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import).
## Importing packages
Bun implements the Node.js module resolution algorithm, so you can import packages from `node_modules` with a bare specifier.
@@ -107,8 +175,8 @@ Once it finds the `foo` package, Bun reads the `package.json` to determine how t
"bun": "./index.js",
"worker": "./index.js",
"node": "./index.js",
"require": "./index.js", # if importer is CommonJS
"import": "./index.mjs", # if importer is ES module
"require": "./index.js", // if importer is CommonJS
"import": "./index.mjs", // if importer is ES module
"default": "./index.js",
}
}
@@ -159,80 +227,9 @@ In the spirit of treating TypeScript as a first-class citizen, the Bun runtime w
If you aren't a TypeScript user, you can create a [`jsconfig.json`](https://code.visualstudio.com/docs/languages/jsconfig) in your project root to achieve the same behavior.
## CommonJS
{% details summary="Low-level details of CommonJS interop in Bun" %}
Bun has native support for CommonJS modules (added in Bun v0.6.5). ES Modules are the recommended module format, but CommonJS modules are still widely used in the Node.js ecosystem. Bun supports both module formats, so that existing CommonJS packages can be used.
In Bun's JavaScript runtime, `require` can be used by both ES Modules and CommonJS modules.
In Bun, you can `require()` ESM modules from CommonJS modules.
| Module Type | `require()` | `import * as` |
| ----------- | ---------------- | ----------------------------------------------------------------------- |
| ES Module | Module Namespace | Module Namespace |
| CommonJS | module.exports | `default` is `module.exports`, keys of module.exports are named exports |
If the target module is an ES Module, `require` returns the module namespace object (equivalent to `import * as`).
If the target module is a CommonJS module, `require` returns the `module.exports` object.
### What is a CommonJS module?
In 2016, ECMAScript added support for [ES Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules). ES Modules are the standard for JavaScript modules. However, millions of npm packages still use CommonJS modules.
CommonJS modules are modules that use `module.exports` to export values. Typically, `require` is used to import CommonJS modules.
```ts
// my-commonjs.cjs
const stuff = require("./stuff");
module.exports = { stuff };
```
The biggest difference between CommonJS and ES Modules is that CommonJS modules are synchronous, while ES Modules are asynchronous. There are other differences too, like ES Modules support top-level `await` and CommonJS modules don't. ES Modules are always in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), while CommonJS modules are not. Browsers do not have native support for CommonJS modules, but they do have native support for ES Modules (`<script type="module">`). CommonJS modules are not statically analyzable, while ES Modules only allow static imports and exports.
### Importing CommonJS from ESM
You can `import` or `require` CommonJS modules from ESM modules.
```ts
import { stuff } from "./my-commonjs.cjs";
import Stuff from "./my-commonjs.cjs";
const myStuff = require("./my-commonjs.cjs");
```
### Importing ESM from CommonJS
```ts
// this works in Bun v0.6.5+
// It does not work in Node.js
const { stuff } = require("./my-esm.mjs");
```
### Importing CommonJS from CommonJS
You can `require()` CommonJS modules from CommonJS modules.
```ts
const { stuff } = require("./my-commonjs.cjs");
```
#### Top-level await
If you are using top-level await, you must use `import()` to import ESM modules from CommonJS modules.
```ts
import("./my-esm.js").then(({ stuff }) => {
// ...
});
// this will throw an error if "my-esm.js" uses top-level await
const { stuff } = require("./my-esm.js");
```
#### Low-level details of CommonJS interop in Bun
Bun's JavaScript runtime has native support for CommonJS as of Bun v0.6.5.
When Bun's JavaScript transpiler detects usages of `module.exports`, it treats the file as CommonJS. The module loader will then wrap the transpiled module in a function shaped like this:
Bun's JavaScript runtime has native support for CommonJS. When Bun's JavaScript transpiler detects usages of `module.exports`, it treats the file as CommonJS. The module loader will then wrap the transpiled module in a function shaped like this:
```js
(function (module, exports, require) {
@@ -245,3 +242,5 @@ When Bun's JavaScript transpiler detects usages of `module.exports`, it treats t
Once the CommonJS module is successfully evaluated, a Synthetic Module Record is created with the `default` ES Module [export set to `module.exports`](https://github.com/oven-sh/bun/blob/9b6913e1a674ceb7f670f917fc355bb8758c6c72/src/bun.js/bindings/CommonJSModuleRecord.cpp#L212-L213) and keys of the `module.exports` object are re-exported as named exports (if the `module.exports` object is an object).
When using Bun's bundler, this works differently. The bundler will wrap the CommonJS module in a `require_${moduleName}` function which returns the `module.exports` object.
{% /details %}

View File

@@ -18,7 +18,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:child_process`](https://nodejs.org/api/child_process.html)
🟡 Missing IPC, `Stream` stdio, `proc.gid`, `proc.uid`, advanced serialization.
🟡 Missing `Stream` stdio, `proc.gid`, `proc.uid`. IPC has partial support and only current only works with other `bun` processes.
### [`node:cluster`](https://nodejs.org/api/cluster.html)
@@ -26,7 +26,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:console`](https://nodejs.org/api/console.html)
🟢 Recommended to use `console` global instead
🟡 Missing `Console` constructor.
### [`node:crypto`](https://nodejs.org/api/crypto.html)
@@ -50,11 +50,11 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:events`](https://nodejs.org/api/events.html)
🟡 Missing `on`
🟡 Missing `on`.
### [`node:fs`](https://nodejs.org/api/fs.html)
🟡 Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}` `fs.{watchFile|unwatchFile}` `fs.{cp|cpSync}`. `fs.promises.open` incorrectly returns a file descriptor instead of a `FileHandle`.
🟡 Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}`. `fs.promises.open` incorrectly returns a file descriptor instead of a `FileHandle`.
### [`node:http`](https://nodejs.org/api/http.html)
@@ -94,7 +94,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:process`](https://nodejs.org/api/process.html)
🟡 See `Globals > process`.
🟡 See [`process`](#process) Global.
### [`node:punycode`](https://nodejs.org/api/punycode.html)
@@ -122,7 +122,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:sys`](https://nodejs.org/api/util.html)
🟡 See `node:util`.
🟡 See [`node:util`](#node-util).
### [`node:timers`](https://nodejs.org/api/timers.html)
@@ -130,7 +130,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:tls`](https://nodejs.org/api/tls.html)
🟡 Missing `tls.createSecurePair`
🟡 Missing `tls.createSecurePair`.
### [`node:trace_events`](https://nodejs.org/api/tracing.html)
@@ -146,7 +146,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:util`](https://nodejs.org/api/util.html)
🟡 Missing `util.MIMEParams` `util.MIMEType` `util.formatWithOptions()` `util.getSystemErrorMap()` `util.getSystemErrorName()` `util.parseArgs()` `util.stripVTControlCharacters()` `util.transferableAbortController()` `util.transferableAbortSignal()`.
🟡 Missing `util.MIMEParams` `util.MIMEType` `util.getSystemErrorMap()` `util.getSystemErrorName()` `util.parseArgs()` `util.stripVTControlCharacters()` `util.transferableAbortController()` `util.transferableAbortSignal()`.
### [`node:v8`](https://nodejs.org/api/v8.html)
@@ -166,7 +166,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
### [`node:zlib`](https://nodejs.org/api/zlib.html)
🟡 Missing `zlib.brotli*`. Some methods are not optimized.
🟡 Missing `zlib.brotli*`. Has not been optimized.
<!-- {% block className="ScrollFrame" %}
{% table %}
@@ -250,7 +250,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
- {% anchor id="node_fs" %} [`node:fs`](https://nodejs.org/api/fs.html) {% /anchor %}
- 🟡
- Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}` `fs.{watchFile|unwatchFile}` `fs.{cp|cpSync}`. `fs.promises.open` incorrectly returns a file descriptor instead of a `FileHandle`.
- Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}`. `fs.promises.open` incorrectly returns a file descriptor instead of a `FileHandle`.
---
@@ -364,7 +364,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
- {% anchor id="node_tls" %} [`node:tls`](https://nodejs.org/api/tls.html) {% /anchor %}
- 🟡
- Missing `tls.createSecurePair`
- Missing `tls.createSecurePair`.
---
@@ -418,7 +418,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
- {% anchor id="node_zlib" %} [`node:zlib`](https://nodejs.org/api/zlib.html) {% /anchor %}
- 🟡
- Missing `zlib.brotli*`
- Missing `zlib.brotli*`.
{% /table %}
{% /block %} -->
@@ -529,7 +529,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)
🟢 Fully implemented. Added in Bun 0.5.7.
🟢 Fully implemented.
### [`global`](https://nodejs.org/api/globals.html#global)
@@ -589,7 +589,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`process`](https://nodejs.org/api/process.html)
🟡 Missing `process.allowedNodeEnvironmentFlags` `process.channel()` `process.connected` `process.constrainedMemory()` `process.disconnect()` `process.getActiveResourcesInfo/setActiveResourcesInfo()` `process.setuid/setgid/setegid/seteuid/setgroups()` `process.hasUncaughtExceptionCaptureCallback` `process.initGroups()` `process.report` `process.resourceUsage()` `process.send()`.
🟡 Missing `process.allowedNodeEnvironmentFlags` `process.channel` `process.constrainedMemory()` `process.getActiveResourcesInfo/setActiveResourcesInfo()` `process.setuid/setgid/setegid/seteuid/setgroups()` `process.hasUncaughtExceptionCaptureCallback` `process.initGroups()` `process.report` `process.resourceUsage()`.
### [`queueMicrotask()`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)
@@ -621,7 +621,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
### [`require()`](https://nodejs.org/api/globals.html#require)
🟢 Fully implemented, as well as [`require.main`](https://nodejs.org/api/modules.html#requiremain), [`require.cache`](https://nodejs.org/api/modules.html#requirecache), and [`require.resolve`](https://nodejs.org/api/modules.html#requireresolverequest-options)
🟢 Fully implemented, as well as [`require.main`](https://nodejs.org/api/modules.html#requiremain), [`require.cache`](https://nodejs.org/api/modules.html#requirecache), and [`require.resolve`](https://nodejs.org/api/modules.html#requireresolverequest-options).
### [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)
@@ -859,7 +859,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
- {% anchor id="node_formdata" %} [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) {% /anchor %}
- 🟢
- Fully implemented. Added in Bun 0.5.7.
- Fully implemented.
---

View File

@@ -1,7 +1,3 @@
{% callout %}
**Note** — Introduced in Bun v0.1.11.
{% /callout %}
Bun provides a universal plugin API that can be used to extend both the _runtime_ and [_bundler_](/docs/bundler).
Plugins intercept imports and perform custom loading logic: reading files, transpiling code, etc. They can be used to add support for additional file types, like `.scss` or `.yaml`. In the context of Bun's bundler, plugins can be used to implement framework-level features like CSS extraction, macros, and client-server code co-location.
@@ -131,7 +127,7 @@ In this case we're using `"object"`—a built-in loader (intended for use by plu
---
- `ts`
- `.ts` `.mts` `cts`
- `.ts` `.mts` `.cts`
- Transform TypeScript then transpile
---
@@ -177,7 +173,7 @@ Loading a YAML file is useful, but plugins support more than just data loading.
```ts#sveltePlugin.ts
import { plugin } from "bun";
await plugin({
plugin({
name: "svelte loader",
async setup(build) {
const { compile } = await import("svelte/compiler");

View File

@@ -32,7 +32,7 @@ The following Web APIs are partially or completely supported.
---
- WebSockets
- [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
- [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) (_not production ready_)
---

View File

@@ -24,33 +24,56 @@ Press `enter` to accept the default answer for each prompt, or pass the `-y` fla
## `bun create`
Template a new Bun project with `bun create`.
```bash
$ bun create <template> <destination>
```
{% callout %}
**Note** You dont need `bun create` to use Bun. You dont need any configuration at all. This command exists to make getting started a bit quicker and easier.
{% /callout %}
A template can take a number of forms:
Template a new Bun project with `bun create`. This is a flexible command that can be used to create a new project with a `create-<template>` npm package, a GitHub repo, or a local template.
```bash
$ bun create <template> # an official template (remote)
$ bun create <username>/<repo> # a GitHub repo (remote)
$ bun create <local-template> # a custom template (local)
### From `npm`
```sh
$ bun create <template> [<destination>]
```
Running `bun create` performs the following steps:
Assuming you don't have a [local template](#local-templates) with the same name, this command will download and execute the `create-<template>` package from npm. The following two commands will behave identically:
- Download the template (remote templates only)
- Copy all template files into the destination folder. By default Bun will _not overwrite_ any existing files. Use the `--force` flag to overwrite existing files.
```sh
$ bun create remix
$ bunx create-remix
```
Refer to the documentation of the associated `create-<template>` package for complete documentation and usage instructions.
### From GitHub
This will download the contents of the GitHub repo to disk.
```bash
$ bun create <user>/<repo>
$ bun create github.com/<user>/<repo>
```
Optionally specify a name for the destination folder. If no destination is specified, the repo name will be used.
```bash
$ bun create <user>/<repo> mydir
$ bun create github.com/<user>/<repo> mydir
```
Bun will perform the following steps:
- Download the template
- Copy all template files into the destination folder
- Install dependencies with `bun install`.
- Initialize a fresh Git repo. Opt out with the `--no-git` flag.
- Run the template's configured `start` script, if defined.
### Official templates
{% callout %}
By default Bun will _not overwrite_ any existing files. Use the `--force` flag to overwrite existing files.
{% /callout %}
<!-- ### Official templates
The following official templates are available.
@@ -73,9 +96,9 @@ Welcome to bun! Create a new project by pasting any of the following:
{% callout %}
⚡️ **Speed** — At the time of writing, `bun create react app` runs ~11x faster on a M1 Macbook Pro than `yarn create react-app app`.
{% /callout %}
{% /callout %} -->
### GitHub repos
<!-- ### GitHub repos
A template of the form `<username>/<repo>` will be downloaded from GitHub.
@@ -90,9 +113,9 @@ $ bun create github.com/ahfarmer/calculator ./myapp
$ bun create https://github.com/ahfarmer/calculator ./myapp
```
Bun installs the files as they currently exist current default branch (usually `main` or `master`). Unlike `git clone` it doesn't download the commit history or configure a remote.
Bun installs the files as they currently exist current default branch (usually `main` or `master`). Unlike `git clone` it doesn't download the commit history or configure a remote. -->
### Local templates
### From a local template
{% callout %}
**⚠️ Warning** — Unlike remote templates, running `bun create` with a local template will delete the entire destination folder if it already exists! Be careful.
@@ -124,26 +147,9 @@ Then, create a `package.json` file in that directory with the following contents
You can run `bun create foo` elsewhere on your file system to verify that Bun is correctly finding your local template.
{% table %}
#### Setup logic
---
- `postinstall`
- runs after installing dependencies
---
- `preinstall`
- runs before installing dependencies
<!-- ---
- `start`
- a command to auto-start the application -->
{% /table %}
Each of these can correspond to a string or array of strings. An array of commands will be executed in order. Here is an example:
You can specify pre- and post-install setup scripts in the `"bun-create"` section of your local template's `package.json`.
```json
{
@@ -162,11 +168,27 @@ Each of these can correspond to a string or array of strings. An array of comman
}
```
When cloning a template, `bun create` will automatically remove the `"bun-create"` section from `package.json` before writing it to the destination folder.
The following fields are supported. Each of these can correspond to a string or array of strings. An array of commands will be executed in order.
### Reference
{% table %}
#### CLI flags
---
- `postinstall`
- runs after installing dependencies
---
- `preinstall`
- runs before installing dependencies
{% /table %}
After cloning a template, `bun create` will automatically remove the `"bun-create"` section from `package.json` before writing it to the destination folder.
## Reference
### CLI flags
{% table %}
@@ -195,7 +217,7 @@ When cloning a template, `bun create` will automatically remove the `"bun-create
{% /table %}
#### Environment variables
### Environment variables
{% table %}

View File

@@ -43,10 +43,6 @@ coverageSkipTestFiles = true # default false
### Coverage thresholds
{% callout %}
**Note** — Support for coverage reporting was added in Bun v0.7.3.
{% /callout %}
It is possible to specify a coverage threshold in `bunfig.toml`. If your test suite does not meet or exceed this threshold, `bun test` will exit with a non-zero exit code to indicate the failure.
```toml

View File

@@ -55,7 +55,7 @@ Let's run this test with `bun test`:
```bash
$ bun test
bun test v0.x.y
bun test v1.x
dom.test.ts:
✓ dom test [0.82ms]

View File

@@ -44,11 +44,11 @@ To scope the hooks to a test file:
```ts
import { describe, beforeAll } from "bun:test";
describe("test group", () => {
beforeAll(() => {
// setup
});
beforeAll(() => {
// setup
});
describe("test group", () => {
// tests...
});
```

View File

@@ -1,4 +1,4 @@
`bun:test` lets you change what time it is in your tests. This was introduced in Bun v0.6.13.
`bun:test` lets you change what time it is in your tests.
This works with any of the following:

View File

@@ -109,7 +109,7 @@ $ bun test --todo
## `test.only`
To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --skip` will only execute tests/suites that have been marked with `.only()`.
To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --only` will only execute tests/suites that have been marked with `.only()`.
```ts
import { test, describe } from "bun:test";
@@ -300,12 +300,12 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
- 🟢
- [`.resolves()`](https://jestjs.io/docs/expect#resolves) (since Bun v0.6.12+)
- [`.resolves()`](https://jestjs.io/docs/expect#resolves)
---
- 🟢
- [`.rejects()`](https://jestjs.io/docs/expect#rejects) (since Bun v0.6.12+)
- [`.rejects()`](https://jestjs.io/docs/expect#rejects)
---
@@ -385,7 +385,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
- 🟢
- [`.toBeInstanceOf()`](https://jestjs.io/docs/expect#tobeinstanceofclass) (Bun v0.5.8+)
- [`.toBeInstanceOf()`](https://jestjs.io/docs/expect#tobeinstanceofclass)
---
@@ -405,7 +405,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
---
- 🟢
- [`.toMatchSnapshot()`](https://jestjs.io/docs/expect#tomatchsnapshotpropertymatchers-hint) (Bun v0.5.8+)
- [`.toMatchSnapshot()`](https://jestjs.io/docs/expect#tomatchsnapshotpropertymatchers-hint)
---

View File

@@ -18,7 +18,7 @@
"build-fallback": "esbuild --target=esnext --bundle src/fallback.ts --format=iife --platform=browser --minify > src/fallback.out.js",
"postinstall": "bash .scripts/postinstall.sh",
"typecheck": "tsc --noEmit && cd test && bun run typecheck",
"fmt": "prettier --write --cache './{src,test,bench,packages/{bun-inspector-*,bun-vscode,bun-debug-adapter-protocol}}/**/*.{mjs,ts,tsx,js,jsx}'",
"fmt": "prettier --write --cache './{src,test,bench,packages/{bun-types,bun-inspector-*,bun-vscode,bun-debug-adapter-protocol}}/**/*.{mjs,ts,tsx,js,jsx}'",
"lint": "eslint './**/*.d.ts' --cache",
"lint:fix": "eslint './**/*.d.ts' --cache --fix"
},

View File

@@ -44,7 +44,7 @@ async function loadPackage(pkg: Package, cwd?: string): Promise<void> {
}
await spawn({
cwd: dir,
cmd: ["bun", "wiptest", path],
cmd: ["bun", "test", path],
});
}
}

View File

@@ -4,15 +4,76 @@ A custom runtime layer that runs Bun on AWS Lambda.
## Setup
First, you will need to deploy the layer to your AWS account. Clone this repository and run the `publish-layer` script to get started.
First, you will need to deploy the layer to your AWS account. Clone this repository and run the `publish-layer` script to get started. Note: the `publish-layer` script also builds the layer.
```sh
git clone git@github.com:oven-sh/bun.git
cd packages/bun-lambda
cd bun/packages/bun-lambda
bun install
bun run publish-layer
```
## Usage
Once you publish the layer to your AWS account, you can create a Lambda function that uses the layer.
### Step 1: Create a Bun Lambda handler function
In addition to providing the Bun runtime itself, the Bun Lambda Layer also provides an event transformation so you can write your Bun function in a classic Bun server format. This allows you to also run your Lambda function as a local Bun server with `bun run <handler-name>.ts`. Here are some examples of how to write a Bun Lambda function:
#### HTTP Event Example
When an event is triggered from [API Gateway](https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html), the layer transforms the event payload into a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request). This means you can test your Lambda function locally using `bun run`, without any code changes.
```ts
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",
},
});
},
};
```
#### Non-HTTP Event Example
For non-HTTP events — S3, SQS, EventBridge, etc. — the event payload is the body of the [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request).
```ts
export default {
async fetch(request: Request): Promise<Response> {
const event = await request.json();
// ...
return new Response();
},
};
```
### Step 2: Build the Bun handler
The final step is to upload your Bun handler. You can technically write the handler directly in the console if you wish, but if you want a full development environment, use the Bun toolkit. There are several ways you can choose to build and manage your artifacts, but follow these steps for a simple approach:
1. Run `bun build <handler-entry>.[ts|js] --outfile /dist/handler.js`
2. Zip the `/dist` folder
### Step 3: Create the Lambda function on AWS
Once you've written your Lambda function, you need to configure a new Lambda function to use Bun. The following steps apply to configuring in the console, CloudFormation, CDK, Terraform, or any other configuration management option for AWS:
1. Create the Lambda function
2. Set the Runtime to custom with Amazon Linux 2
3. Set the handler to <handler-file-name>.fetch (e.g. if your bundled Bun handler is at `handler.js`, set the handler as `handler.fetch`)
4. Set the architecture to whichever architecture you configured when you built/deployed the Lambda Layer
5. Attach the Lambda Layer to your new function
6. Upload the zip file from step 2. You can do this in the console directly, upload to S3 and set that as the location for the handler file in Lambda, or use something like CDK to manage this for you.
## API
### `bun run build-layer`
Builds a Lambda layer for Bun and saves it to a `.zip` file.
@@ -51,42 +112,3 @@ bun run publish-layer -- \
--output /path/to/layer.zip \
--region us-east-1
```
## Usage
Once you publish the layer to your AWS account, you can create a Lambda function that uses the layer.
Here's an example function that can run on Lambda using the layer for Bun:
### HTTP events
When an event is triggered from [API Gateway](https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html), the layer transforms the event payload into a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request). This means you can test your Lambda function locally using `bun run`, without any code changes.
```ts
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",
},
});
},
};
```
### Non-HTTP events
For non-HTTP events — S3, SQS, EventBridge, etc. — the event payload is the body of the [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request).
```ts
export default {
async fetch(request: Request): Promise<Response> {
const event = await request.json();
// ...
return new Response();
},
};
```

Binary file not shown.

View File

@@ -22,11 +22,11 @@ function log(level: string, ...args: any[]): void {
if (!args.length) {
return;
}
const message = Bun.inspect(...args).replace(/\n/g, "\r");
const messages = args.map(arg => Bun.inspect(arg).replace(/\n/g, "\r"));
if (requestId === undefined) {
logger(level, message);
logger(level, ...messages);
} else {
logger(level, `RequestId: ${requestId}`, message);
logger(level, `RequestId: ${requestId}`, ...messages);
}
}
@@ -294,7 +294,6 @@ function formatBody(body?: string, isBase64Encoded?: boolean): string | null {
}
type HttpEventV1 = {
readonly version: "1.0";
readonly requestContext: {
readonly requestId: string;
readonly domainName: string;
@@ -310,15 +309,12 @@ type HttpEventV1 = {
};
function isHttpEventV1(event: any): event is HttpEventV1 {
return event.version === "1.0" && typeof event.requestContext === "object";
return !event.Records && event.version !== "2.0" && event.version !== "0" && typeof event.requestContext === "object";
}
function formatHttpEventV1(event: HttpEventV1): Request {
const request = event.requestContext;
const headers = new Headers();
for (const [name, value] of Object.entries(event.headers)) {
headers.append(name, value);
}
for (const [name, values] of Object.entries(event.multiValueHeaders ?? {})) {
for (const value of values) {
headers.append(name, value);
@@ -327,9 +323,6 @@ function formatHttpEventV1(event: HttpEventV1): Request {
const hostname = headers.get("Host") ?? request.domainName;
const proto = headers.get("X-Forwarded-Proto") ?? "http";
const url = new URL(request.path, `${proto}://${hostname}/`);
for (const [name, value] of new URLSearchParams(event.queryStringParameters)) {
url.searchParams.append(name, value);
}
for (const [name, values] of Object.entries(event.multiValueQueryStringParameters ?? {})) {
for (const value of values ?? []) {
url.searchParams.append(name, value);
@@ -360,7 +353,7 @@ type HttpEventV2 = {
};
function isHttpEventV2(event: any): event is HttpEventV2 {
return event.version === "2.0" && typeof event.requestContext === "object";
return !event.Records && event.version === "2.0" && typeof event.requestContext === "object";
}
function formatHttpEventV2(event: HttpEventV2): Request {
@@ -389,6 +382,10 @@ function formatHttpEventV2(event: HttpEventV2): Request {
});
}
function isHttpEvent(event: any): boolean {
return isHttpEventV1(event) || isHttpEventV2(event);
}
type WebSocketEvent = {
readonly headers: Record<string, string>;
readonly multiValueHeaders: Record<string, string[]>;
@@ -538,7 +535,7 @@ class LambdaServer implements Server {
statusCode: 200,
};
}
if (!request?.headers.has("Host")) {
if (!isHttpEvent(event.event)) {
return response.text();
}
return formatResponse(response);

View File

@@ -12,7 +12,7 @@ Install the `bun-types` npm package:
```bash
# yarn/npm/pnpm work too, "bun-types" is an ordinary npm package
bun add bun-types
bun add -d bun-types
```
# Usage

View File

@@ -1034,7 +1034,7 @@ declare module "bun:test" {
* expect("bar").not.toSatisfy((val) => val === "bun");
* @link https://vitest.dev/api/expect.html#tosatisfy
* @link https://jest-extended.jestcommunity.dev/docs/matchers/toSatisfy
*/
*/
toSatisfy(predicate: (value: T) => boolean): void;
/**
* Asserts that a value starts with a `string`.

View File

@@ -3767,6 +3767,24 @@ declare module "bun" {
*/
error?: Errorlike,
): void | Promise<void>;
/**
* When specified, Bun will open an IPC channel to the subprocess. The passed callback is called for
* incoming messages, and `subprocess.send` can send messages to the subprocess. Messages are serialized
* using the JSC serialize API, which allows for the same types that `postMessage`/`structuredClone` supports.
*
* The subprocess can send and recieve messages by using `process.send` and `process.on("message")`,
* respectively. This is the same API as what Node.js exposes when `child_process.fork()` is used.
*
* Currently, this is only compatible with processes that are other `bun` instances.
*/
ipc?(
message: any,
/**
* The {@link Subprocess} that sent the message
*/
subprocess: Subprocess<In, Out, Err>,
): void;
}
type OptionsToSubprocess<Opts extends OptionsObject> =
@@ -3894,6 +3912,20 @@ declare module "bun" {
* This method will tell Bun to not wait for this process to exit before shutting down.
*/
unref(): void;
/**
* Send a message to the subprocess. This is only supported if the subprocess
* was created with the `ipc` option, and is another instance of `bun`.
*
* Messages are serialized using the JSC serialize API, which allows for the same types that `postMessage`/`structuredClone` supports.
*/
send(message: any): void;
/**
* Disconnect the IPC channel to the subprocess. This is only supported if the subprocess
* was created with the `ipc` option.
*/
disconnect(): void;
}
/**

View File

@@ -447,9 +447,7 @@ declare module "bun:ffi" {
["callback"]: FFIType.pointer; // for now
}
export type FFITypeOrString =
| FFIType
| keyof FFITypeStringToType;
export type FFITypeOrString = FFIType | keyof FFITypeStringToType;
interface FFIFunction {
/**
@@ -549,7 +547,9 @@ declare module "bun:ffi" {
// */
// export function callback(ffi: FFIFunction, cb: Function): number;
export interface Library<Fns extends Readonly<Record<string, Narrow<FFIFunction>>>> {
export interface Library<
Fns extends Readonly<Record<string, Narrow<FFIFunction>>>,
> {
symbols: ConvertFns<Fns>;
/**
@@ -584,7 +584,9 @@ declare module "bun:ffi" {
[K in keyof Fns]: (
...args: Fns[K]["args"] extends infer A extends readonly FFITypeOrString[]
? { [L in keyof A]: FFITypeToArgsType[ToFFIType<A[L]>] }
: [unknown] extends [Fns[K]["args"]] ? [] : never
: [unknown] extends [Fns[K]["args"]]
? []
: never
) => [unknown] extends [Fns[K]["returns"]]
? void
: FFITypeToReturnsType[ToFFIType<NonNullable<Fns[K]["returns"]>>];
@@ -759,7 +761,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -772,7 +774,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -785,7 +787,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -798,7 +800,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -811,7 +813,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -824,7 +826,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -837,7 +839,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -850,7 +852,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -863,7 +865,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -876,7 +878,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -889,7 +891,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*
@@ -902,7 +904,7 @@ declare module "bun:ffi" {
/**
* The read function behaves similarly to DataView,
* but it's usually faster because it doesn't need to create a DataView or ArrayBuffer.
*
*
* @param ptr The memory address to read
* @param byteOffset bytes to skip before reading
*

View File

@@ -3930,7 +3930,30 @@ declare module "fs" {
*/
recursive?: boolean;
}
/**
* Class: fs.StatWatcher
* Extends `EventEmitter`
* A successful call to {@link watchFile} method will return a new fs.StatWatcher object.
*/
export interface StatWatcher extends EventEmitter {
/**
* When called, requests that the Node.js event loop _not_ exit so long as the `fs.StatWatcher` is active. Calling `watcher.ref()` multiple times will have
* no effect.
*
* By default, all `fs.StatWatcher` objects are "ref'ed", making it normally
* unnecessary to call `watcher.ref()` unless `watcher.unref()` had been
* called previously.
*/
ref(): this;
/**
* When called, the active `fs.StatWatcher` object will not require the Node.js
* event loop to remain active. If there is no other activity keeping the
* event loop running, the process may exit before the `fs.StatWatcher` object's
* callback is invoked. Calling `watcher.unref()` multiple times will have
* no effect.
*/
unref(): this;
}
export interface FSWatcher extends EventEmitter {
/**
* Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the `fs.FSWatcher` object is no longer usable.
@@ -4067,6 +4090,243 @@ declare module "fs" {
filename: PathLike,
listener?: WatchListener<string>,
): FSWatcher;
/**
* Watch for changes on `filename`. The callback `listener` will be called each
* time the file is accessed.
*
* The `options` argument may be omitted. If provided, it should be an object. The`options` object may contain a boolean named `persistent` that indicates
* whether the process should continue to run as long as files are being watched.
* The `options` object may specify an `interval` property indicating how often the
* target should be polled in milliseconds.
*
* The `listener` gets two arguments the current stat object and the previous
* stat object:
*
* ```js
* import { watchFile } from 'fs';
*
* watchFile('message.text', (curr, prev) => {
* console.log(`the current mtime is: ${curr.mtime}`);
* console.log(`the previous mtime was: ${prev.mtime}`);
* });
* ```
*
* These stat objects are instances of `fs.Stat`. If the `bigint` option is `true`,
* the numeric values in these objects are specified as `BigInt`s.
*
* To be notified when the file was modified, not just accessed, it is necessary
* to compare `curr.mtimeMs` and `prev.mtimeMs`.
*
* When an `fs.watchFile` operation results in an `ENOENT` error, it
* will invoke the listener once, with all the fields zeroed (or, for dates, the
* Unix Epoch). If the file is created later on, the listener will be called
* again, with the latest stat objects. This is a change in functionality since
* v0.10.
*
* Using {@link watch} is more efficient than `fs.watchFile` and`fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and`fs.unwatchFile` when possible.
*
* When a file being watched by `fs.watchFile()` disappears and reappears,
* then the contents of `previous` in the second callback event (the file's
* reappearance) will be the same as the contents of `previous` in the first
* callback event (its disappearance).
*
* This happens when:
*
* * the file is deleted, followed by a restore
* * the file is renamed and then renamed a second time back to its original name
* @since v0.1.31
*/
export interface WatchFileOptions {
bigint?: boolean | undefined;
persistent?: boolean | undefined;
interval?: number | undefined;
}
export type StatsListener = (current: Stats, previous: Stats) => void;
export type BigIntStatsListener = (
current: BigIntStats,
previous: BigIntStats,
) => void;
/**
* Watch for changes on `filename`. The callback `listener` will be called each
* time the file is accessed.
*
* The `options` argument may be omitted. If provided, it should be an object. The`options` object may contain a boolean named `persistent` that indicates
* whether the process should continue to run as long as files are being watched.
* The `options` object may specify an `interval` property indicating how often the
* target should be polled in milliseconds.
*
* The `listener` gets two arguments the current stat object and the previous
* stat object:
*
* ```js
* import { watchFile } from 'node:fs';
*
* watchFile('message.text', (curr, prev) => {
* console.log(`the current mtime is: ${curr.mtime}`);
* console.log(`the previous mtime was: ${prev.mtime}`);
* });
* ```
*
* These stat objects are instances of `fs.Stat`. If the `bigint` option is `true`,
* the numeric values in these objects are specified as `BigInt`s.
*
* To be notified when the file was modified, not just accessed, it is necessary
* to compare `curr.mtimeMs` and `prev.mtimeMs`.
*
* When an `fs.watchFile` operation results in an `ENOENT` error, it
* will invoke the listener once, with all the fields zeroed (or, for dates, the
* Unix Epoch). If the file is created later on, the listener will be called
* again, with the latest stat objects. This is a change in functionality since
* v0.10.
*
* Using {@link watch} is more efficient than `fs.watchFile` and`fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and`fs.unwatchFile` when possible.
*
* When a file being watched by `fs.watchFile()` disappears and reappears,
* then the contents of `previous` in the second callback event (the file's
* reappearance) will be the same as the contents of `previous` in the first
* callback event (its disappearance).
*
* This happens when:
*
* * the file is deleted, followed by a restore
* * the file is renamed and then renamed a second time back to its original name
*/
export function watchFile(
filename: PathLike,
options:
| (WatchFileOptions & {
bigint?: false | undefined;
})
| undefined,
listener: StatsListener,
): StatWatcher;
export function watchFile(
filename: PathLike,
options:
| (WatchFileOptions & {
bigint: true;
})
| undefined,
listener: BigIntStatsListener,
): StatWatcher;
/**
* Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed.
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
*/
export function watchFile(
filename: PathLike,
listener: StatsListener,
): StatWatcher;
/**
* Stop watching for changes on `filename`. If `listener` is specified, only that
* particular listener is removed. Otherwise, _all_ listeners are removed,
* effectively stopping watching of `filename`.
*
* Calling `fs.unwatchFile()` with a filename that is not being watched is a
* no-op, not an error.
*
* Using {@link watch} is more efficient than `fs.watchFile()` and`fs.unwatchFile()`. `fs.watch()` should be used instead of `fs.watchFile()`and `fs.unwatchFile()` when possible.
* @since v0.1.31
* @param listener Optional, a listener previously attached using `fs.watchFile()`
*/
export function unwatchFile(
filename: PathLike,
listener?: StatsListener,
): void;
export function unwatchFile(
filename: PathLike,
listener?: BigIntStatsListener,
): void;
interface CopyOptionsBase {
/**
* Dereference symlinks
* @default false
*/
dereference?: boolean;
/**
* When `force` is `false`, and the destination
* exists, throw an error.
* @default false
*/
errorOnExist?: boolean;
/**
* Overwrite existing file or directory. _The copy
* operation will ignore errors if you set this to false and the destination
* exists. Use the `errorOnExist` option to change this behavior.
* @default true
*/
force?: boolean;
/**
* Modifiers for copy operation. See `mode` flag of {@link copyFileSync()}
*/
mode?: number;
/**
* When `true` timestamps from `source` will
* be preserved.
* @default false
*/
preserveTimestamps?: boolean;
/**
* Copy directories recursively.
* @default false
*/
recursive?: boolean;
/**
* When true, path resolution for symlinks will be skipped
* @default false
*/
verbatimSymlinks?: boolean;
}
export interface CopyOptions extends CopyOptionsBase {
/**
* Function to filter copied files/directories. Return
* `true` to copy the item, `false` to ignore it.
*/
filter?(source: string, destination: string): boolean | Promise<boolean>;
}
export interface CopySyncOptions extends CopyOptionsBase {
/**
* Function to filter copied files/directories. Return
* `true` to copy the item, `false` to ignore it.
*/
filter?(source: string, destination: string): boolean;
}
/**
* Asynchronously copies the entire directory structure from `src` to `dest`,
* including subdirectories and files.
*
* When copying a directory to another directory, globs are not supported and
* behavior is similar to `cp dir1/ dir2/`.
*
* @param source source path to copy.
* @param destination destination path to copy to.
*/
export function cp(
source: string | URL,
destination: string | URL,
callback: (error: ErrnoException | null) => void,
): void;
export function cp(
source: string | URL,
destination: string | URL,
options: CopyOptions,
callback: (error: ErrnoException | null) => void,
): void;
/**
* Synchronously copies the entire directory structure from `src` to `dest`,
* including subdirectories and files.
*
* When copying a directory to another directory, globs are not supported and
* behavior is similar to `cp dir1/ dir2/`.
*
* @param source source path to copy.
* @param destination destination path to copy to.
*/
export function cpSync(
source: string | URL,
destination: string | URL,
options?: CopySyncOptions,
): void;
}
declare module "node:fs" {

View File

@@ -780,6 +780,22 @@ declare module "fs/promises" {
):
| AsyncIterable<FileChangeInfo<string>>
| AsyncIterable<FileChangeInfo<Buffer>>;
/**
* Asynchronously copies the entire directory structure from `source` to `destination`,
* including subdirectories and files.
*
* When copying a directory to another directory, globs are not supported and
* behavior is similar to `cp dir1/ dir2/`.
*
* @param source source path to copy.
* @param destination destination path to copy to.
* @return Fulfills with `undefined` upon success.
*/
function cp(
source: string | URL,
destination: string | URL,
options?: CopyOptions,
): Promise<void>;
}
declare module "node:fs/promises" {

View File

@@ -1,3 +1,5 @@
// import * as tls from 'node:tls';
/**
* "blob" is not supported yet
*/
@@ -1288,6 +1290,7 @@ interface RequestInit {
}
interface FetchRequestInit extends RequestInit {
/**
* Log the raw HTTP request & response to stdout. This API may be
* removed in a future version of Bun without notice.
@@ -1300,6 +1303,14 @@ interface FetchRequestInit extends RequestInit {
* This is a custom property that is not part of the Fetch API specification.
*/
proxy?: string;
/**
* Override the default TLS options
*/
tls?: {
rejectUnauthorized?: boolean | undefined; // Defaults to true
checkServerIdentity?: any | undefined; // TODO: change `any` to `checkServerIdentity`
};
}
/**

View File

@@ -4,7 +4,7 @@ declare module "node:module" {
declare module "module" {
export function createRequire(filename: string): NodeJS.Require;
export function _resolveFileName(
export function _resolveFilename(
path: string,
parent: string,
isMain: boolean,

View File

@@ -86,7 +86,6 @@ struct us_internal_ssl_socket_context_t {
/* Pointer to sni tree, created when the context is created and freed likewise when freed */
void *sni;
int pending_handshake;
void (*on_handshake)(struct us_internal_ssl_socket_t *, int success, struct us_bun_verify_error_t verify_error, void* custom_data);
void* handshake_data;
};
@@ -97,6 +96,7 @@ struct us_internal_ssl_socket_t {
SSL *ssl;
int ssl_write_wants_read; // we use this for now
int ssl_read_wants_write;
int pending_handshake;
};
int passphrase_cb(char *buf, int size, int rwflag, void *u) {
@@ -164,6 +164,7 @@ int BIO_s_custom_read(BIO *bio, char *dst, int length) {
struct us_internal_ssl_socket_t *ssl_on_open(struct us_internal_ssl_socket_t *s, int is_client, char *ip, int ip_length) {
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
@@ -186,7 +187,9 @@ struct us_internal_ssl_socket_t *ssl_on_open(struct us_internal_ssl_socket_t *s,
struct us_internal_ssl_socket_t * result = (struct us_internal_ssl_socket_t *) context->on_open(s, is_client, ip, ip_length);
// Hello Message!
if(context->pending_handshake) {
// always handshake after open if on_handshake is set
if(context->on_handshake || s->pending_handshake) {
s->pending_handshake = 1;
us_internal_ssl_handshake(s, context->on_handshake, context->handshake_data);
}
@@ -195,7 +198,6 @@ struct us_internal_ssl_socket_t *ssl_on_open(struct us_internal_ssl_socket_t *s,
void us_internal_on_ssl_handshake(struct us_internal_ssl_socket_context_t * context, void (*on_handshake)(struct us_internal_ssl_socket_t *, int success, struct us_bun_verify_error_t verify_error, void* custom_data), void* custom_data) {
context->pending_handshake = 1;
context->on_handshake = on_handshake;
context->handshake_data = custom_data;
}
@@ -206,7 +208,7 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
// will start on_open, on_writable or on_data
if(!s->ssl) {
context->pending_handshake = 1;
s->pending_handshake = 1;
context->on_handshake = on_handshake;
context->handshake_data = custom_data;
return;
@@ -218,9 +220,7 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
loop_ssl_data->ssl_socket = &s->s;
if (us_socket_is_closed(0, &s->s) || us_internal_ssl_socket_is_shut_down(s)) {
context->pending_handshake = 0;
context->on_handshake = NULL;
context->handshake_data = NULL;
s->pending_handshake = 0;
struct us_bun_verify_error_t verify_error = (struct us_bun_verify_error_t) { .error = 0, .code = NULL, .reason = NULL };
if(on_handshake != NULL) {
@@ -236,9 +236,7 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
int err = SSL_get_error(s->ssl, result);
// as far as I know these are the only errors we want to handle
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
context->pending_handshake = 0;
context->on_handshake = NULL;
context->handshake_data = NULL;
s->pending_handshake = 0;
struct us_bun_verify_error_t verify_error = us_internal_verify_error(s);
// clear per thread error queue if it may contain something
@@ -252,7 +250,7 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
}
return;
} else {
context->pending_handshake = 1;
s->pending_handshake = 1;
context->on_handshake = on_handshake;
context->handshake_data = custom_data;
// Ensure that we'll cycle through internal openssl's state
@@ -262,10 +260,7 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
}
} else {
context->pending_handshake = 0;
context->on_handshake = NULL;
context->handshake_data = NULL;
s->pending_handshake = 0;
struct us_bun_verify_error_t verify_error = us_internal_verify_error(s);
// success
@@ -283,16 +278,16 @@ void us_internal_ssl_handshake(struct us_internal_ssl_socket_t *s, void (*on_han
struct us_internal_ssl_socket_t *us_internal_ssl_socket_close(struct us_internal_ssl_socket_t *s, int code, void *reason) {
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
if (context->pending_handshake) {
context->pending_handshake = 0;
if (s->pending_handshake) {
s->pending_handshake = 0;
}
return (struct us_internal_ssl_socket_t *) us_socket_close(0, (struct us_socket_t *) s, code, reason);
}
struct us_internal_ssl_socket_t *ssl_on_close(struct us_internal_ssl_socket_t *s, int code, void *reason) {
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
if (context->pending_handshake) {
context->pending_handshake = 0;
if (s->pending_handshake) {
s->pending_handshake = 0;
}
SSL_free(s->ssl);
@@ -300,11 +295,8 @@ struct us_internal_ssl_socket_t *ssl_on_close(struct us_internal_ssl_socket_t *s
}
struct us_internal_ssl_socket_t *ssl_on_end(struct us_internal_ssl_socket_t *s) {
if(&s->s) {
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
if (context && context->pending_handshake) {
context->pending_handshake = 0;
}
if(&s->s && s->pending_handshake) {
s->pending_handshake = 0;
}
// whatever state we are in, a TCP FIN is always an answered shutdown
@@ -322,7 +314,7 @@ struct us_internal_ssl_socket_t *ssl_on_data(struct us_internal_ssl_socket_t *s,
struct us_loop_t *loop = us_socket_context_loop(0, &context->sc);
struct loop_ssl_data *loop_ssl_data = (struct loop_ssl_data *) loop->data.ssl_data;
if(context->pending_handshake) {
if(s->pending_handshake) {
us_internal_ssl_handshake(s, context->on_handshake, context->handshake_data);
}
@@ -477,7 +469,7 @@ struct us_internal_ssl_socket_t *ssl_on_writable(struct us_internal_ssl_socket_t
struct us_internal_ssl_socket_context_t *context = (struct us_internal_ssl_socket_context_t *) us_socket_context(0, &s->s);
if(context->pending_handshake) {
if(s->pending_handshake) {
us_internal_ssl_handshake(s, context->on_handshake, context->handshake_data);
}
@@ -1302,10 +1294,8 @@ struct us_internal_ssl_socket_context_t *us_internal_create_ssl_socket_context(s
context->ssl_context = ssl_context;//create_ssl_context_from_options(options);
context->is_parent = 1;
context->pending_handshake = 0;
context->on_handshake = NULL;
context->handshake_data = NULL;
/* We, as parent context, may ignore data */
context->sc.is_low_prio = (int (*)(struct us_socket_t *)) ssl_is_low_prio;
@@ -1340,10 +1330,9 @@ struct us_internal_ssl_socket_context_t *us_internal_bun_create_ssl_socket_conte
/* Then we extend its SSL parts */
context->ssl_context = ssl_context;//create_ssl_context_from_options(options);
context->is_parent = 1;
context->pending_handshake = 0;
context->on_handshake = NULL;
context->handshake_data = NULL;
/* We, as parent context, may ignore data */
context->sc.is_low_prio = (int (*)(struct us_socket_t *)) ssl_is_low_prio;

View File

@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// clang-format off
#ifndef us_malloc
#define us_malloc malloc
@@ -383,6 +384,8 @@ int us_socket_local_port(int ssl, struct us_socket_t *s);
void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length);
/* Bun extras */
struct us_socket_t *us_socket_pair(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR* fds);
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd);
struct us_socket_t *us_socket_detach(int ssl, struct us_socket_t *s);
struct us_socket_t *us_socket_attach(int ssl, LIBUS_SOCKET_DESCRIPTOR client_fd, struct us_socket_context_t *ctx, int flags, int socket_ext_size);
struct us_socket_t *us_socket_wrap_with_tls(int ssl, struct us_socket_t *s, struct us_bun_socket_context_options_t options, struct us_socket_events_t events, int socket_ext_size);

View File

@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// clang-format off
#include "libusockets.h"
#include "internal/internal.h"
@@ -192,6 +193,45 @@ struct us_socket_t *us_socket_attach(int ssl, LIBUS_SOCKET_DESCRIPTOR client_fd,
return s;
}
struct us_socket_t *us_socket_pair(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR* fds) {
#ifdef LIBUS_USE_LIBUV
return 0;
#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) {
return 0;
}
return us_socket_from_fd(ctx, socket_ext_size, fds[0]);
}
struct us_socket_t *us_socket_from_fd(struct us_socket_context_t *ctx, int socket_ext_size, LIBUS_SOCKET_DESCRIPTOR fd) {
#ifdef LIBUS_USE_LIBUV
return 0;
#endif
struct us_poll_t *p1 = us_create_poll(ctx->loop, 0, sizeof(struct us_socket_t) + socket_ext_size);
us_poll_init(p1, fd, POLL_TYPE_SOCKET);
us_poll_start(p1, ctx->loop, LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
struct us_socket_t *s = (struct us_socket_t *) p1;
s->context = ctx;
s->timeout = 0;
s->long_timeout = 0;
s->low_prio_state = 0;
/* We always use nodelay */
bsd_socket_nodelay(fd, 1);
us_internal_socket_context_link_socket(ctx, s);
if (ctx->on_open) {
ctx->on_open(s, 0, 0, 0);
}
return s;
}
/* Not shared with SSL */
void *us_socket_get_native_handle(int ssl, struct us_socket_t *s) {

Some files were not shown because too many files have changed in this diff Show More