> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nanoforge.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration file

> The nanoforge.config.ts (or .js) file consumed by the CLI

## Overview

Every NanoForge workspace, project, or lib has a `nanoforge.config.ts` (or `.js`) at its root,
exporting its configuration wrapped in `defineConfig` from `@nanoforge-dev/config`. The CLI reads
this file to know how to build and start your game, and — for a workspace root — to discover the
projects and libs it contains.

Commands accept `-c, --config <directory>` to point at a different directory to read the config
from (default: the current directory). The CLI looks for `nanoforge.config.ts` in that directory
first, falls back to `nanoforge.config.js` when no `.ts` file exists, and fails if neither is
present.

## `type`

A config's `type` field discriminates between four shapes:

* `workspace` — a monorepo root listing its `packages`.
* `lib` — a shared library consumed by clients/servers.
* `client` — a browser-side NanoForge app.
* `server` — a server-side NanoForge app.

The config at the root directory the CLI is pointed at must be a `workspace` or a `client`/`server`
project — a bare `lib` config is not valid there. Inside a `workspace`, none of the packages it
resolves may themselves be of type `workspace`; nesting workspaces isn't supported.

## Defining a config

Wrap your config in `defineConfig` to get type-checking and editor autocompletion on its fields:

```ts theme={null}
import { defineConfig } from "@nanoforge-dev/config";

export default defineConfig({
  type: "client",
  entryFile: "src/main.ts",
  libs: ["../../libs/my-lib"],
});
```

`defineConfig` is an identity function — it returns its argument unchanged.

## `workspace`

| Field | Type | Default | Description |
| - | - | - | - |
| `packages` | `string[]` | `[]` | Glob patterns matched against directories relative to the workspace root (e.g. apps/\*, apps/\*\*/client, or a literal path like apps/client.), each expected to hold its own `client`, `server`, or `lib` config. |
| `network` | `"dedicated" \| "p2p"` | `"dedicated"` | Where the server app runs. `"p2p"` runs it in the browser of the first player who opens the game, the others joining that player over WebRTC: see [Peer-to-peer](#peer-to-peer). |

A directory matched by a pattern but missing a `nanoforge.config.ts`/`.js` is skipped without
error. A pattern that matches no project or lib at all only logs a warning, rather than failing
the whole resolution. A matched directory whose config is itself of type `workspace` throws.

### Example

```ts theme={null}
import { defineConfig } from "@nanoforge-dev/config";

export default defineConfig({
  type: "workspace",
  packages: ["apps/*", "libs/*"],
});
```

### Peer-to-peer

With `network: "p2p"`, the same client and server apps run without a game server:

* `nf build` also builds each server app for the browser, into the client's output (`server/`).
* `nf start` sets `NANOFORGE_NETWORK_MODE=p2p` for both apps. The server process then only pairs
  players (WebRTC signaling) on its `LISTENING_TCP_PORT`, and the environment stays the same as
  with a dedicated server.
* A player who opens the game without `?room=` hosts it in their tab, and the game can show its
  invite link (`ctx.network.inviteLink`).

```ts theme={null}
import { defineConfig } from "@nanoforge-dev/config";

export default defineConfig({
  type: "workspace",
  packages: ["apps/*"],
  network: "p2p",
});
```

## `lib`

| Field | Type | Default | Description |
| - | - | - | - |
| `dir.assets` | `string` | `assets` | Where assets live. |
| `dir.shared` | `string` | `shared` | Where shared code lives. |
| `dir.components` | `string` | `shared/components` | Used by the editor only. |
| `dir.systems` | `string` | `shared/systems` | Used by the editor only. |
| `dir.scenes` | `string` | `shared/scenes` | Used by the editor only. |

### Example

```ts theme={null}
import { defineConfig } from "@nanoforge-dev/config";

export default defineConfig({ type: "lib" });
```

## `client` / `server`

`client` and `server` share the exact same fields and defaults — `type` is the only thing that
tells them apart.

| Field | Type | Default | Description |
| - | - | - | - |
| `entryFile` | `string` | `src/main.ts` | Entry file. |
| `out.dir` | `string` | `dist` | Build output directory. |
| `out.mainFile` | `string` | `main.js` | Build output entry file name. |
| `dir.assets` | `string` | `assets` | Where assets live. |
| `dir.packages` | `string` | `nf_modules` | Where downloaded package dependencies are installed. |
| `dir.components` | `string` | `src/components` | Used by the editor only. |
| `dir.systems` | `string` | `src/systems` | Used by the editor only. |
| `dir.scenes` | `string` | `src/scenes` | Used by the editor only. |
| `libs` | `string[]` | `[]` | Relative paths to shared libs this project depends on. |

### Example

```ts theme={null}
import { defineConfig } from "@nanoforge-dev/config";

export default defineConfig({
  type: "server",
  entryFile: "src/main.ts",
  dir: { assets: "static" },
  libs: ["../../libs/shared"],
});
```

## Resolving defaults

Missing fields are filled in with the defaults for the config's `type`, deep-merging nested
objects like `dir` and `out`:

```ts theme={null}
import { resolveConfig } from "@nanoforge-dev/config";

const resolved = resolveConfig({ type: "client", dir: { assets: "static" } });
// resolved.dir.assets === "static"
// resolved.dir.packages === "nf_modules" (default, not overridden)
```

Array fields (`packages`, `libs`) are replaced wholesale by an override rather than concatenated
with the defaults.

## Errors

* `ConfigNotFoundError` — thrown by the CLI when neither `nanoforge.config.ts` nor
  `nanoforge.config.js` exists in the directory it was pointed at.
* `ConfigParseError` (from `@nanoforge-dev/config`) — thrown while loading or validating a config
  file's default export. Its `code` identifies the failure: `not-found`, `load-failed`,
  `no-default-export`, or `invalid-type`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.