routes option in Bun.serve().
app.ts
terminal
HTML Routes
HTML Imports as Routes
To specify entrypoints to your frontend, import HTML files into your JavaScript/TypeScript/TSX/JSX files.app.ts
Bun.serve().
app.ts
/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
Anindex.html file like this:
index.html
index.html
React Integration
To use React in your client-side code, importreact-dom/client and render your app.
Development Mode
When building locally, enable development mode by settingdevelopment: true in Bun.serve().
src/backend.ts
Development Mode Features
Whendevelopment 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
.htmlfile - Enables hot module reloading (unless
hmr: falseis set) - Echoes console logs from the browser to the terminal
Advanced Development Configuration
To echo console logs from the browser to the terminal, passconsole: true in the development object in Bun.serve().
src/backend.ts
Development vs Production
Production Mode
Hot reloading anddevelopment: true help you iterate quickly, but in production your server should be as fast as possible and have as few external dependencies as possible.
Ahead of Time Bundling (Recommended)
As of Bun v1.2.17, you can useBun.build or bun build to bundle your fullstack application ahead of time.
terminal
Bun.serve() can use to serve the assets.
src/backend.ts
Runtime Bundling
If you’d rather not add a build step, setdevelopment: false in Bun.serve().
This:
- Enables in-memory caching of bundled assets. Bun bundles assets lazily on the first request to an
.htmlfile and caches the result in memory until the server restarts. - Enables
Cache-ControlandETagheaders - Minifies JavaScript/TypeScript/TSX/JSX files
src/backend.ts
API Routes
HTTP Method Handlers
Define API endpoints with HTTP method handlers:src/backend.ts
Dynamic Routes
Use URL parameters in your routes:src/backend.ts
Request Handling
src/backend.ts
Plugins
Bun’s bundler plugins are also supported when bundling static routes. To configure plugins forBun.serve, add a plugins array in the [serve.static] section of your bunfig.toml.
TailwindCSS Plugin
To use TailwindCSS, install thetailwindcss package and the bun-plugin-tailwind plugin.
terminal
bunfig.toml
tailwindcss somewhere in your project:
index.html
style.css
index.html
Custom Plugins
Any JS file or module that exports a valid bundler plugin object (an object with aname and a setup field) can be placed in the plugins array:
bunfig.toml
my-plugin-implementation.ts
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 replaceprocess.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.How It Works
Bun usesHTMLRewriter 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
developmentis nottrueinBun.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
staticinBun.serve(). - This works similarly to how
Bun.buildprocesses HTML files.
Complete Example
server.ts
public/index.html
src/main.tsx
src/App.tsx
src/styles.css
Best Practices
Project Structure
Environment-Based Configuration
server/config.ts
Error Handling
server/middleware.ts
API Response Helpers
server/utils.ts
Type Safety
types/api.ts
Deployment
Production Build
terminal
Docker Deployment
Dockerfile
Environment Variables
.env.production
Migration from Other Frameworks
From Express + Webpack
server.ts
From Next.js API Routes
server.ts
Limitations and Future Plans
Current Limitations
bun buildCLI integration is not yet available for fullstack apps- Auto-discovery of API routes is not implemented
- Server-side rendering (SSR) is not built-in
Planned Features
- Integration with
bun buildCLI - File-based routing for API endpoints
- Built-in SSR support
- Enhanced plugin ecosystem
This is a work in progress. Features and APIs may change.