Bun overview
September 11, 2023Bun is a JavaScript runtime environment that extends JavaScriptCore engine built for Safari. Bun is designed for speed and developer experience (DX), which includes many features out of the box.
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
- Support for both ES modules and CommonJS modules, both can be used in the same file
- Native SQLite driver
Installation
Let's start by installing it with the following command
curl -fsSL https://bun.sh/install | bash
Update the current version with bun upgrade
command and check the current version with bun --version
command.
Run bun --help
to see what CLI options are available.
Initialize empty project via the bun init
command
The init command will bootstrap the "hello world" example with configured package.json, binary lock file (bun.lockb
), and tsconfig.
Bundler
Bundler can be used via CLI command (bun build
) or Bun.build()
API
await Bun.build({entrypoints: ['./index.ts'],outdir: './build',});
Below is the example for CLI command usage. Run bun build --help
to see all of the available options
bun build --target=bun ./index.ts --outdir=./build
Build a single executable using the compile
flag.
bun build ./index.js --compile
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 --dev
option (e.g., bun add zod --dev
)
Remove dependencies via the bun remove
command (e.g., bun remove zod
)
Running scripts
- Run specific script via the
bun <SCRIPT PATH>.ts
command - Auto-install and run packages locally via the
bunx
command (e.g.,bunx cowsay "Hello world"
) - Run a custom npm script from package.json via the
bun run <SCRIPT NAME>
command
Watch mode
- hot reloading mode via
bun --hot index.ts
command without restarting the process - watch mode via
bun --watch index.ts
command with restarting the process
File system
Write into the file using Bun.write
method
await Bun.write('./output.txt', 'Lorem ipsum');
Environment variables
- Access environment variables via
Bun.env
orprocess.env
objects - Store variables in
.env
files, like.env
,.env.production
,.env.local
- Print all current environment variables via
bun run env
command
HTTP server
Create a server with the following code
const server = Bun.serve({port: Bun.env.PORT,fetch (request) {return new Response('Welcome to Bun!');},});console.log(`Listening to port ${server.port}`);
Frameworks
Elysia (Bun framework)
Install packages via the bun add elysia @elysiajs/swagger
command, write the initial server, and run it via the bun server.ts
command.
// server.tsimport { Elysia } from 'elysia';import swagger from '@elysiajs/swagger';const port = Bun.env.PORT || 8081;new Elysia().use(swagger({path: '/api-docs',})).get('/posts/:id', (({ params: { id }}) => id)).listen(port);
Express
Install the express
package via the bun add express
command, write the initial server, and run it via the bun server.ts
command
// server.tsimport express from 'express';const app = express();const port = 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 the bun run <TEST SCRIPT NAME>
(e.g., bun run test:unit
) command.
Below is an example of a basic test assertion and mocking using 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 the bun test --watch
command.
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();