DEV Community

Željko Šević
Željko Šević

Posted on • Originally published at sevic.dev on

Bun overview

Bun 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
Enter fullscreen mode Exit fullscreen mode

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',
});
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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');
Enter fullscreen mode Exit fullscreen mode

Environment variables

  • Access environment variables via Bun.env or process.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}`);
Enter fullscreen mode Exit fullscreen mode

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.ts
import { 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);
Enter fullscreen mode Exit fullscreen mode

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.ts
import 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}`);
});
Enter fullscreen mode Exit fullscreen mode

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);
  });
});
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

Boilerplate

Here is the link to the boilerplate I use for the development.

Top comments (0)