---
title: "Dev"
description: "createCac's building block: h3 + WebSocket RPC + the SPA at the resolved base path."
canonical_url: "https://devfra.me/adapters/dev"
---
# Dev

> createCac's building block: h3 + WebSocket RPC + the SPA at the resolved base path.

`createCac`'s building block: h3 + WebSocket RPC + the SPA at the resolved base path.

```ts
import { createDevServer } from 'devframe/adapters/dev'
import myDevframe from './my-tool'

const handle = await createDevServer(myDevframe, {
  port: 7777,
  onReady: ({ origin }) => console.log(`Ready at ${origin}`),
})

// graceful shutdown: SIGINT, hot reload, test teardown
process.on('SIGINT', () => handle.close().then(() => process.exit(0)))
```

Returns a `StartedServer`: origin, port, h3 app, WS server, RPC group, `close()`.

| Option        | Default                                      | Description                       |
| ------------- | -------------------------------------------- | --------------------------------- |
| `host`        | `def.cli?.host ?? 'localhost'`               | Bind host.                        |
| `port`        | resolved via `resolveDevServerPort`          | Listen port.                      |
| `flags`       | `{}`                                         | To `setup(ctx, { flags })`.       |
| `distDir`     | `def.clientAssets`                           | SPA dist; unset = bridge mode.    |
| `basePath`    | `resolveBasePath(def, 'standalone')`         | Mount override.                   |
| `app`         | fresh h3 app                                 | Mount onto.                       |
| `openBrowser` | resolves from `flags.open` / `def.cli?.open` | `false` off; string opens a path. |
| `ws`          | `def.cli?.ws`                                | RPC WebSocket; see below.         |
| `onReady`     | none                                         | WS-bind callback.                 |

## WebSocket endpoint

The RPC socket shares the HTTP port at `__ws`, advertised *relative*. Configure `def.cli.ws`:

| Field   | Scenario                 | Advertised `websocket`    |
| ------- | ------------------------ | ------------------------- |
| `route` | same server, other route | `{ path: <route> }`       |
| `port`  | different port           | `{ port, path: <route> }` |
| `url`   | remote origin            | URL verbatim              |

Precedence `url` > `port` > `route`; `url` keeps the socket local on `route`.

## Port resolution

`resolveDevServerPort(def, opts?)` resolves a port before start.

```ts
import { resolveDevServerPort } from 'devframe/adapters/dev'

const port = await resolveDevServerPort(myDevframe, { host: '127.0.0.1' })
// honors def.cli?.port / portRange / random
```

| Option        | Default                        | Description                              |
| ------------- | ------------------------------ | ---------------------------------------- |
| `host`        | `def.cli?.host ?? 'localhost'` | Bind host (`get-port-please` detection). |
| `defaultPort` | `def.cli?.port ?? 9999`        | Preferred-port override.                 |


## Sitemap

See the full [sitemap](https://devfra.me/sitemap.md) for all pages.
