# How to Set Up Bun.serve with TLS/SSL Configuration for Secure HTTPS Servers

> Secure your Bun.serve with TLS/SSL configuration. Learn to set up HTTPS, handle multi-domain SNI, and protect your web servers efficiently.

- Repository: [Bun/bun](https://github.com/oven-sh/bun)
- Tags: how-to-guide
- Published: 2026-02-28

---

**To enable HTTPS in `Bun.serve`, pass a `tls` property in the server options object containing `cert` and `key` fields, or provide an array of TLS configurations for multi-domain SNI support.**

`Bun.serve` creates a high-performance HTTP server in the oven-sh/bun runtime. Adding **TLS/SSL configuration** transforms it into a secure HTTPS server capable of handling encrypted traffic, client certificate authentication, and Server Name Indication (SNI) for multi-domain hosting. The implementation relies on native OpenSSL bindings and exposes these features through the `tls` option defined in [`packages/bun-types/serve.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/serve.d.ts).

## Basic HTTPS Configuration

The minimal configuration requires two fields: `cert` for the PEM-encoded certificate chain and `key` for the private key. According to the TypeScript definitions in [`packages/bun-types/bun.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts), these accept `BunFile` objects, strings, or `BufferSource` instances.

```typescript
const server = Bun.serve({
  fetch(req) {
    return new Response("🔒 Secure connection established");
  },
  
  tls: {
    cert: Bun.file("server.crt"),
    key: Bun.file("server.key"),
  }
});

console.log(`Listening on https://${server.hostname}:${server.port}`);

```

The underlying implementation in [`src/js/node/_http_server.ts`](https://github.com/oven-sh/bun/blob/main/src/js/node/_http_server.ts) handles the creation of the TLS listener when this configuration is present.

## Multi-Domain SNI Support

For servers hosting multiple domains on a single IP address, supply an **array of `TLSOptions`** objects. Each configuration must include a `serverName` field to match the client's SNI request, as implemented in [`src/bun.js/api/server/SSLConfig.bindv2.ts`](https://github.com/oven-sh/bun/blob/main/src/bun.js/api/server/SSLConfig.bindv2.ts).

```typescript
const server = Bun.serve({
  fetch(req) {
    return new Response(`Hello from ${new URL(req.url).hostname}`);
  },
  
  tls: [
    {
      serverName: "example.com",
      cert: Bun.file("example.com.crt"),
      key: Bun.file("example.com.key"),
    },
    {
      serverName: "api.example.org",
      cert: Bun.file("api.example.org.crt"),
      key: Bun.file("api.example.org.key"),
      ca: [Bun.file("intermediate.pem"), Bun.file("root.pem")],
    }
  ]
});

```

When the array format is used, Bun automatically selects the appropriate certificate based on the hostname provided in the ClientHello message.

## Advanced TLS Options

The `tls` object supports several advanced security parameters defined in [`packages/bun-types/bun.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts) (lines 373-455):

- **`ca`** – Overrides the default Mozilla CA bundle with custom trusted certificates
- **`requestCert`** – Enables mutual TLS by requesting client certificates
- **`rejectUnauthorized`** – When `false`, accepts self-signed or invalid client certificates (default: `true`)
- **`dhParamsFile`** – Specifies custom Diffie-Hellman parameters for key exchange
- **`passphrase`** – Decrypts password-protected private keys
- **`lowMemoryMode`** – Reduces OpenSSL memory usage at the cost of performance

```typescript
tls: {
  cert: Bun.file("server.crt"),
  key: Bun.file("server.key"),
  ca: Bun.file("custom-ca.pem"),
  requestCert: true,
  rejectUnauthorized: false, // Allow self-signed certs for testing
  dhParamsFile: Bun.file("dhparams.pem"),
  passphrase: "secret-key-password"
}

```

## Common Configuration Pitfalls

**Missing `serverName` in SNI arrays** – When providing an array of TLS configurations, omitting the `serverName` field causes Bun to fall back to the first certificate for all connections.

**Certificate chain ordering** – The `cert` field must include the server certificate followed by intermediate certificates in the correct order. Mismatched `cert`/`key` pairs when using multiple entries will cause handshake failures.

**CA bundle replacement** – Supplying the `ca` option completely replaces the built-in Mozilla certificate store. You must explicitly include all necessary root and intermediate certificates.

**Port assignment** – `Bun.serve` defaults to port `0` (OS-assigned). For HTTPS servers, explicitly set `port: 443` or your desired port to avoid confusion.

## Summary

- Add a `tls` object to `Bun.serve` options containing `cert` and `key` to enable HTTPS
- Use an array of TLS configurations with `serverName` fields for multi-domain SNI support
- Reference implementation files: [`packages/bun-types/serve.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/serve.d.ts) (API), [`packages/bun-types/bun.d.ts`](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts) (TLSOptions), and [`src/bun.js/api/server/SSLConfig.bindv2.ts`](https://github.com/oven-sh/bun/blob/main/src/bun.js/api/server/SSLConfig.bindv2.ts) (native bindings)
- Enable mutual TLS with `requestCert: true` and control client validation with `rejectUnauthorized`
- Override default CA trust stores using the `ca` field, but include all required certificates

## Frequently Asked Questions

### How do I enable HTTPS in Bun.serve?

Pass a `tls` configuration object in the `Bun.serve` options containing your `cert` (certificate chain) and `key` (private key). Both fields accept `Bun.file()` references, strings, or buffers. The server automatically starts in HTTPS mode when this property is present.

### Can I host multiple domains with different SSL certificates on one Bun server?

Yes. Provide an array of TLS configuration objects instead of a single object. Each element must include a `serverName` field matching the domain name. Bun uses the Server Name Indication (SNI) extension to select the appropriate certificate during the TLS handshake.

### What file formats does Bun.serve support for TLS certificates?

Bun accepts standard PEM-encoded certificates and keys. You can load these using `Bun.file("path/to/cert.pem")`, provide them as strings containing the PEM content, or pass `BufferSource` objects. Encrypted private keys are supported when you provide the `passphrase` option.

### How do I configure mutual TLS (mTLS) authentication?

Set `requestCert: true` in your TLS options to require clients to present certificates. Combine this with `rejectUnauthorized: true` (the default) to validate client certificates against your specified `ca` bundle. This enforces bidirectional authentication between client and server.