# Server Options

> Provide additional options to customize listening server.

When starting a new server, in addition to main `fetch` handler, you can provide additional options to customize listening server.

```js
import { serve } from "srvx";

serve({
  // Generic options
  port: 3000,
  hostname: "localhost",

  // Runtime specific options
  node: {},
  bun: {},
  deno: {},

  // Main server handler
  fetch: () => new Response("👋 Hello there!"),
});
```

There are two kind of options:

- Generic options: Top level options are intended to have exactly same functionality regardless of runtime
- Runtime specific: Allow customizing more runtime specific options

## Generic Options

### `port`

The port server should be listening to.

Default is value of `PORT` environment variable or `3000`.

<tip>

You can set the port to `0` to use a random port.

</tip>

### `hostname`

The hostname (IP or resolvable host) server listener should bound to.

When not provided, server will **listen to all network interfaces** by default.

<important>

If you are running a server that should not be exposed to the network, use `localhost`.

</important>

### `reusePort`

Enabling this option allows multiple processes to bind to the same port, which is useful for load balancing.

<note>

Despite Node.js built-in behavior that has `exclusive` flag enabled by default, srvx uses non-exclusive mode for consistency.

</note>

### `silent`

If enabled, no server listening message will be printed (enabled by default when `TEST` environment variable is set).

### `protocol`

The protocol to use for the server.

Possible values are `http` or `https`.

If `protocol` is not set, Server will use `http` as the default protocol or `https` if both `tls.cert` and `tls.key` options are provided.

### `tls`

TLS server options.

**Example:**

```js
import { serve } from "srvx";

serve({
  tls: { cert: "./server.crt", key: "./server.key" },
  fetch: () => new Response("👋 Hello there!"),
});
```

**Options:**

- `cert`: Path or inline content for the certificate in PEM format (required).
- `key`: Path or inline content for the private key in PEM format (required).
- `passphrase`: Passphrase for the private key (optional).

<tip>

You can pass inline `cert` and `key` values in PEM format starting with `-----BEGIN `.

</tip>

<important>

- Always keep your SSL private keys secure and never commit them to version control
- Use environment variables or secure secret management for production deployments
- Consider using automatic certificate management (e.g., Let's Encrypt) for production

</important>

### `onError`

Runtime agnostic error handler.

<note>

This handler will take over the built-in error handlers of Deno and Bun.

</note>

**Example:**

```js
import { serve } from "srvx";

serve({
  fetch: () => new Response("👋 Hello there!"),
  onError(error) {
    return new Response(`<pre>${error}\n${error.stack}</pre>`, {
      headers: { "Content-Type": "text/html" },
    });
  },
});
```

## Runtime Specific Options

### Node.js

**Example:**

```js
import { serve } from "srvx";

serve({
  node: {
    maxHeadersize: 16384 * 2, // Double default
    ipv6Only: true, // Disable dual-stack support
    // http2: false // Disable http2 support (enabled by default in TLS mode)
  },
  fetch: () => new Response("👋 Hello there!"),
});
```

<read-more>

See Node.js documentation for [ServerOptions](https://nodejs.org/api/http.html#httpcreateserveroptions-requestlistener) and [ListenOptions](https://nodejs.org/api/net.html#serverlistenoptions-callback) for all available options.

</read-more>

### Bun

**Example:**

```js
import { serve } from "srvx";

serve({
  bun: {
    error(error) {
      return new Response(`<pre>${error}\n${error.stack}</pre>`, {
        headers: { "Content-Type": "text/html" },
      });
    },
  },
  fetch: () => new Response("👋 Hello there!"),
});
```

<read-more to="https://bun.sh/docs/api/http">

See Bun HTTP documentation for all available options.

</read-more>

### Deno

**Example:**

```js
import { serve } from "srvx";

serve({
  deno: {
    onError(error) {
      return new Response(`<pre>${error}\n${error.stack}</pre>`, {
        headers: { "Content-Type": "text/html" },
      });
    },
  },
  fetch: () => new Response("👋 Hello there!"),
});
```

<read-more to="https://docs.deno.com/api/deno/~/Deno.ServeOptions">

See Deno serve documentation for all available options.

</read-more>
