1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# Bun: a fast bundler & transpiler for developing web software
Bun is a new:
- JavaScript/TypeScript/JSX transpiler (`bun ./file.tsx`)
- JavaScript bundler (run `bun bun ./file1.ts ./file2.jsx` and it will flatten node_module imports into one `.bun`)
- Development server with 60fps Hot Module Reloading (& WIP support for React Fast Refresh) (run `bun dev`)
- CSS bundler `bun ./file.css` (it flattens `@import` into one file)
- JavaScript Runtime Environment (powered by JavaScriptCore, what WebKit/Safari uses)
All in one simple tool.
Most of Bun is written in [Zig](https://), a fast low-level programming language with manual memory management.
## Install:
```
# Global install is recommended so bun appears in your $PATH
npm install -g bun-cli
```
# Getting started
## Using Bun with Next.js
In your project folder root (where `package.json` is):
```bash
npm install bun-framework-next path buffer
bun bun --use next
open http://localhost:3000; bun dev --origin "http://localhost:3000"
```
Here are some features of Next.js that **aren't supported** yet:
- `getStaticProps`,`getServerSideProps`, `getInitialProps`, `getStaticPaths`. These functions will not be called.
- locales, zones, `assetPrefix` (workaround: change `--origin \"http://localhsot:3000/assetPrefixInhere\"`)
- `next/image` - `<Image />` component
Currently, any time you import new dependencies from `node_modules`, you will need to re-run `bun bun --use next`. This will eventually be automatic.
## Using Bun without a framework or with Create React App
In your project folder root (where `package.json` is):
```bash
bun bun ./entry-point-1.js ./entry-point-2.jsx
bun dev ./entry-point-1.js ./entry-point-2.jsx --origin https://localhost:3000
```
By default, `bun dev` will look for any HTML files in the `public` directory and serve that. For browsers navigating to the page, the `.html` file extension is optional in the URL, and `index.html` will automatically rewrite for the directory.
Here are examples of routing from `public/` and how they're matched:
| File Path | Dev Server URL |
| --------- | ------------- |
| public/dir/index.html | /dir |
| public/index.html | / |
| public/hi.html | /hi |
| public/file.html | /file |
| public/font/Inter.woff2 | /font/Inter.woff2 |
For **Create React App** users, note that Bun does not transpile HTML yet, so `%PUBLIC_URL%` will need to be replaced with '/'`.
From there, Bun relies on the filesystem for mapping dev server paths to source files. All URL paths are relative to the project root (where `package.json` is).
Here are examples of routing source code file paths:
| File Path | Dev Server URL |
| ------------------------- | -------------------------- |
| src/components/Button.tsx | /src/components/Button.tsx |
| src/index.tsx | /src/index.tsx |
| pages/index.js | /pages/index.js |
## Using Bun without `bun dev`
`bun dev` is the recommended way to use Bun. Today, Bun is primarily intended to speed up your frontend development iteration cycle. `bun` does not implement a JavaScript minifier yet, and does not implement all the optimizations other tools do for shrinking bundle size. That means you probably should look to other tools for bundling in production. To make this split smoother, Bun strives for ecosystem compatibility (e.g. by integrating with Next.js)
```
bun bun ./entry-point-1.js ./entry-point-2.jsx
bun build ./entry-point-1.js ./entry-point-2.jsx --origin https://localhost:3000 --outdir=./out
```
You can also pass Bun a folder, and it will assume all JavaScript-like files are entry-points. This lets you use Bun's native filesystem router without a framework.
For a `routes` directory with these files:
- `routes/index.js`
- `routes/hello/bar.js`
- `routes/hello/baz.jsx`
- `routes/wut/wat.jsx`
This would be the corresponding command:
```bash
bun bun ./routes
bun build ./routes --outdir=./out
```
# The Bun Bundling Format
`bun bun` generates a `node_modules.bun` and (optionally) a `node_modules.server.bun`. This is a new binary file format that makes it very efficient to serialize/deserialize `node_modules`. With a 2.4 GHz 8-Core Intel Core i9, metadata for
Unlike many other bundlers, `Bun` only bundles `node_modules`. This is great for development, where most people add/update packages much less frequently than app code (which is also great for caching in browsers). To make that distinction clear, the filename defaults to `node_modules.bun`. We recommend storing `node_modules.bun` in your git repository. Since it's a binary file, it shouldn't clutter your git history and it will make your entire frontend development team move faster if they don't have to re-bundle dependencies.
# Building from source
Estimated: 30-60 minutes :(
You'll want to start downloading two things at once:
```bash
git clone https://github.com/jarred-sumner/zig && git checkout jarred/zig-sloppy-with-small-structs
```
```bash
git submodule update --init --recursive --progress --depth=1
```
Next, compile Zig.
On a Mac, that looks like this:
```bash
cmake . -DCMAKE_PREFIX_PATH=$(brew --prefix llvm) -DZIG_STATIC_LLVM=ON -DCMAKE_BUILD_TYPE=Release && make -j 16
```
Note that `brew install zig` won't work. Bun uses a build of Zig with a couple patches.
You'll want to make sure `zig` is in `$PATH`. The `zig` binary wil be in the same folder as the newly-cloned `zig` repo. If you use fish, you can run `fish_add_path (pwd)`.
Now go back to the folder with `Bun`'s repository.
Run:
```
zig build headers
zig build
```
# Credits
- While written in Zig instead of Go, Bun's JS transpiler & CSS lexer source code is based off of @evanw's esbuild project. @evanw did a fantastic job with esbuild.
# License
Bun itself is MIT-licensed.
However, JavaScriptCore (and WebKit) is LGPL-2 and Bun statically links it.
Per LGPL2:
> (1) If you statically link against an LGPL'd library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
You can find the patched version of WebKit used by Bun here: https://github.com/jarred-sumner/webkit. If you would like to relink Bun with changes:
- `git submodule update --init --recursive`
- `make jsc`
- `zig build`
This compiles JavaScriptCore, compiles Bun's `.cpp` bindings for JavaScriptCore (which are the object files using JavaScriptCore) and outputs a new `bun` binary with your changes.
To successfully run `zig build`, you will need to install a fork of Zig you can find here: https://github.com/jarred-sumner/zig/tree/jarred/zig-sloppy.
Bun also statically links:
- `libicu`, which can be found here: https://github.com/unicode-org/icu/blob/main/icu4c/LICENSE
- [`picohttp`](https://github.com/h2o/picohttpparser), which is dual-licensed under the Perl License or the MIT License
|