
# `start()`

Start a server from a configuration object. Returns a [`SimpleServer`](/en/docs/typescript-types#simpleserver) carrying the resolved URL and a `stop()` method.

```typescript
import { start } from 'sovrium'

const server = await start({ name: 'my-app' })

console.log(`Server running at ${server.url}`)
```

`start` validates the config against `AppSchema` before binding anything. An invalid config rejects with a `Sovrium failed to start:` error naming the failing path — it never starts a half-configured server.

## `StartOptions`

The optional second argument. Every property has a working default, so `start(app)` alone is valid.

| Property     | Description                                                                    |
| ------------ | ------------------------------------------------------------------------------ |
| `port`       | Port number, `0`–`65535`. `0` binds an available port. Default: `3000`.        |
| `hostname`   | Interface to bind. Default: `localhost`.                                       |
| `publicDir`  | Static file directory. Files are served at their relative path.                |
| `configPath` | Path to the config file, recorded in the lock file for `restart` and `reload`. |
| `configHash` | Hash of the config content, used to detect changes on reload.                  |

The last two exist for the CLI's own lifecycle commands. Set them only if you are reimplementing `restart`/`reload` yourself; otherwise leave them alone.

```typescript
import { start } from 'sovrium'

const server = await start(
  {
    name: 'my-app',
    tables: [
      {
        id: 1,
        name: 'tasks',
        fields: [
          { id: 1, name: 'title', type: 'single-line-text', required: true },
          { id: 2, name: 'done', type: 'checkbox' },
        ],
      },
    ],
  },
  {
    port: 8080,
    hostname: '0.0.0.0',
    publicDir: './public',
  }
)
```

## Binding to a free port

Passing `port: 0` lets the OS pick. This is the reliable pattern for tests and for several instances on one machine — read the real port back off `server.url` rather than assuming one:

```typescript
const server = await start({ name: 'test-app' }, { port: 0 })

const response = await fetch(`${server.url}/api/health`)
console.log(response.status) // 200

await server.stop()
```

## Shutting down

`stop()` resolves once shutdown is complete, so an `await` is enough to sequence teardown:

```typescript
const server = await start({ name: 'my-app' })

process.on('SIGTERM', async () => {
  await server.stop()
  process.exit(0)
})
```

:::callout
**One server per process.** `start()` installs graceful-shutdown handlers on the process. Calling it twice in one process gives you two servers competing over the same signals — run separate processes instead.
:::

## Related Pages

- [TypeScript API Overview](/en/docs/typescript) — `AppConfig` and the other functions.
- [Type Reference](/en/docs/typescript-types) — `SimpleServer` and the config types.
- [Lifecycle Commands](/en/docs/cli-lifecycle) — the same behaviour from the CLI.
- [Environment Variables](/en/docs/env-vars) — `PORT` and the rest of the runtime inputs.
