Bun is a JavaScript runtime built on JavaScriptCore (the engine behind Safari). It is designed for speed and developer experience (DX), bundling many tools into a single binary.
Some of the features include
- Built-in bundler
- Built-in test runner
- Node.js-compatible package manager, compatible with existing npm packages
- Compatibility with Node.js native modules like
fs,path, etc. - TypeScript support, run TypeScript files with no extra configuration
- Built-in watch mode and hot reloading
- Support for both ES modules and CommonJS modules, both can be used in the same file
- Native SQLite driver
- Built-in PostgreSQL, MySQL, and Redis clients
Installation
Install on macOS and Linux:
curl -fsSL https://bun.com/install | bash
Install on Windows (PowerShell):
powershell -c "irm bun.com/install.ps1|iex"
Other options include npm install -g bun, Homebrew, Scoop, and Docker. See the installation docs for details.
Update the current version with the bun upgrade command and check the current version with bun --version.
Run bun --help to see what CLI options are available.
Initialize an empty project via the bun init command.
The init command bootstraps a "hello world" example with package.json, a text lock file (bun.lock), and tsconfig.json.
Bundler
The bundler can be used via the CLI (bun build) or the Bun.build() API.
await Bun.build({
entrypoints: ['./index.ts'],
outdir: './build'
});
Below is an example for CLI usage. Run bun build --help to see all available options.
bun build --target=bun ./index.ts --outdir=./build
Build a single executable using the --compile flag.
bun build ./index.ts --compile --outfile myapp
Bun can also bundle full-stack apps by importing HTML from server code and embed frontend assets into a standalone binary.
Package manager
Install packages from package.json via the bun install command.
Install additional npm packages via the bun add command (e.g., bun add zod). To install dev dependencies, run bun add with the --dev option (e.g., bun add zod --dev).
Remove dependencies via the bun remove command (e.g., bun remove zod).
Running scripts
- Run a specific script via the
bun <SCRIPT PATH>.tscommand - Auto-install and run packages locally via the
bunxcommand (e.g.,bunx cowsay "Hello world") - Run a custom npm script from
package.jsonvia thebun run <SCRIPT NAME>command
Watch mode
- Hot reloading via
bun --hot index.tswithout restarting the process - Watch mode via
bun --watch index.tswith restarting the process
File system
Write into a file using the Bun.write method.
await Bun.write('./output.txt', 'Lorem ipsum');
Environment variables
- Access environment variables via
Bun.env,process.env, orimport.meta.env - Store variables in
.envfiles, like.env,.env.production,.env.local - Print all current environment variables (including values loaded from
.env) viabun --print process.env
HTTP server
Create a server with the following code.
const port = Number(Bun.env.PORT) || 3000;
const server = Bun.serve({
port,
fetch() {
return new Response('Welcome to Bun!');
}
});
console.log(`Listening on port ${server.port}`);
Frameworks
Elysia (Bun framework)
Install packages via bun add elysia @elysiajs/openapi, write the initial server, and run it via bun server.ts.
// server.ts
import { Elysia } from 'elysia';
import { openapi } from '@elysiajs/openapi';
const port = Number(Bun.env.PORT) || 8081;
new Elysia()
.use(openapi())
.get('/posts/:id', ({ params: { id } }) => id)
.listen(port);
OpenAPI docs are served at /openapi by default.
Express
Install the express package via bun add express, write the initial server, and run it via bun server.ts.
// server.ts
import express from 'express';
const app = express();
const port = Number(Bun.env.PORT) || 3001;
app.get('/', (req, res) => {
res.send('Hello world');
});
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
Debugging
Install the extension Bun for Visual Studio Code by Oven and run the Bun: Debug file command from the command palette. Execution will pause at the breakpoint.
Testing
Bun supports basic mocking and assertion functions. Run existing tests via bun run <TEST SCRIPT NAME> (e.g., bun run test:unit).
Below is an example of a basic test assertion and mocking using the bun:test module.
import { describe, expect, it, mock } from 'bun:test';
import { add } from './addition-service';
import { calculate } from './calculation-service';
describe('Calculation service', () => {
it('should return calculated value', async () => {
const result = calculate();
expect(result).toEqual(5);
});
it('should return mocked value', async () => {
mock.module('./addition-service', () => {
return {
add: () => 3
};
});
const result = add();
expect(result).toEqual(3);
});
});
Run unit tests via the bun test command. Re-run tests when files change via bun test --watch.
SQLite database
Below is a basic example of SQLite driver usage.
import { Database } from 'bun:sqlite';
const database = new Database('database.sqlite');
const query = database.query("SELECT 'hello world' as message;");
console.log(query.get());
database.close();
Demo
Runnable Bun scripts for this post live in the bun-overview-demo folder. Get access via code demos.
Top comments (0)