Skip to main content
To get started, import HTML files and pass them to the routes option in Bun.serve().
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bapp.ts
terminal

HTML Routes

HTML Imports as Routes

To specify entrypoints to your frontend, import HTML files into your JavaScript/TypeScript/TSX/JSX files.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bapp.ts
Pass the imported HTML files as routes to Bun.serve().
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bapp.ts
When you make a request to /dashboard or /, Bun automatically bundles the <script> and <link> tags in the HTML files, exposes them as static routes, and serves the result.

HTML Processing Example

An index.html file like this:
index.html
Becomes something like this:
index.html

React Integration

To use React in your client-side code, import react-dom/client and render your app.

Development Mode

When building locally, enable development mode by setting development: true in Bun.serve().
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

Development Mode Features

When development is true, Bun:
  • Includes the SourceMap header in the response so that devtools can show the original source code
  • Disables minification
  • Re-bundles assets on each request to a .html file
  • Enables hot module reloading (unless hmr: false is set)

Advanced Development Configuration

To echo console logs from the browser to the terminal, pass console: true in the development object in Bun.serve().
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts
Bun sends the logs over the existing HMR WebSocket connection.

Development vs Production

FeatureDevelopmentProduction
Source maps✅ Enabled❌ Disabled
Minification❌ Disabled✅ Enabled
Hot reloading✅ Enabled❌ Disabled
Asset bundling🔄 On each request💾 Cached
Console logging🖥️ Browser → Terminal❌ Disabled
Error details📝 Detailed🔒 Minimal

Production Mode

Hot reloading and development: true help you iterate quickly, but in production your server should be as fast as possible and have as few external dependencies as possible. As of Bun v1.2.17, you can use Bun.build or bun build to bundle your fullstack application ahead of time.
terminal
When Bun’s bundler sees an HTML import from server-side code, it bundles the referenced JavaScript/TypeScript/TSX/JSX and CSS files into a manifest object that Bun.serve() can use to serve the assets.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

Runtime Bundling

If you’d rather not add a build step, set development: false in Bun.serve(). This:
  • Enables in-memory caching of bundled assets. Bun bundles assets lazily on the first request to an .html file and caches the result in memory until the server restarts.
  • Enables Cache-Control and ETag headers
  • Minifies JavaScript/TypeScript/TSX/JSX files
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

API Routes

HTTP Method Handlers

Define API endpoints with HTTP method handlers:
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

Dynamic Routes

Use URL parameters in your routes:
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

Request Handling

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bsrc/backend.ts

Plugins

Bun’s bundler plugins are also supported when bundling static routes. To configure plugins for Bun.serve, add a plugins array in the [serve.static] section of your bunfig.toml.

TailwindCSS Plugin

To use TailwindCSS, install the tailwindcss package and the bun-plugin-tailwind plugin.
terminal
bunfig.toml
You can now use TailwindCSS utility classes in your HTML and CSS files. Import tailwindcss somewhere in your project:
index.html
Alternatively, you can import TailwindCSS in your CSS file:
style.css
index.html

Custom Plugins

Any JS file or module that exports a valid bundler plugin object (an object with a name and a setup field) can be placed in the plugins array:
bunfig.toml
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bmy-plugin-implementation.ts
Bun lazily resolves and loads each plugin and uses them to bundle your routes.
Plugins live in bunfig.toml so that the bun build CLI, once it supports them, can know statically which plugins are in use. These plugins work in Bun.build()’s JS API, but not yet in the CLI.

Inline Environment Variables

Bun can replace process.env.* references in your frontend JavaScript and TypeScript with their values at build time. Configure the env option in your bunfig.toml:
bunfig.toml
This only works with literal process.env.FOO references, not import.meta.env or indirect access like const env = process.env; env.FOO.If an environment variable is not set, you may see runtime errors like ReferenceError: process is not defined in the browser.
See HTML & static sites for build-time configuration and examples.

How It Works

Bun uses HTMLRewriter to scan for <script> and <link> tags in HTML files, uses them as entrypoints for Bun’s bundler, generates an optimized bundle for the JavaScript/TypeScript/TSX/JSX and CSS files, and serves the result.

Processing Pipeline

1

1. <script> Processing

  • Transpiles TypeScript, JSX, and TSX in <script> tags
  • Bundles imported dependencies
  • Generates sourcemaps for debugging
  • Minifies when development is not true in Bun.serve()
index.html
2

2. <link> Processing

  • Processes CSS imports and <link> tags
  • Concatenates CSS files
  • Rewrites url and asset paths to include content-addressable hashes in URLs
index.html
3

3. <img> & Asset Processing

  • Links to assets are rewritten to include content-addressable hashes in URLs
  • Small assets in CSS files are inlined into data: URLs, reducing the total number of HTTP requests sent over the wire
4

4. HTML Rewriting

  • Combines all <script> tags into a single <script> tag with a content-addressable hash in the URL
  • Combines all <link> tags into a single <link> tag with a content-addressable hash in the URL
  • Outputs a new HTML file
5

5. Serving

  • All the output files from the bundler are exposed as static routes, using the same mechanism internally as when you pass a Response object to static in Bun.serve().
  • This works similarly to how Bun.build processes HTML files.

Complete Example

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver.ts
public/index.html
src/main.tsx
src/App.tsx
src/styles.css

Best Practices

Project Structure

Environment-Based Configuration

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver/config.ts

Error Handling

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver/middleware.ts

API Response Helpers

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver/utils.ts

Type Safety

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35btypes/api.ts

Deployment

Production Build

terminal

Docker Deployment

Dockerfile

Environment Variables

.env.production

Migration from Other Frameworks

From Express + Webpack

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver.ts

From Next.js API Routes

https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bserver.ts

Limitations and Future Plans

Current Limitations

  • Auto-discovery of API routes is not implemented
  • Server-side rendering (SSR) is not built-in

Planned Features

  • File-based routing for API endpoints
  • Built-in SSR support
  • Enhanced plugin ecosystem
This is a work in progress. Features and APIs may change.