# Installation

> Install @dirtytalk/engine, structural and spatial with pnpm, plus module formats, TypeScript, runtime requirements and version pinning.

Source: https://dirtytalk.42.dog/docs/installation/

Each package is published to npm separately. Install `@dirtytalk/engine` on its own, or install `structural` or `spatial` together with `engine`.

## Install

### Engine

```sh
pnpm add @dirtytalk/engine
```

### Structural

```sh
pnpm add @dirtytalk/structural @dirtytalk/engine
```

`@dirtytalk/structural` depends on `@dirtytalk/engine` (listed under `dependencies`). Installing `engine` explicitly is recommended when your code imports from it directly, for example to construct a `DirtyChannel` or a scheduler.

### Spatial

```sh
pnpm add @dirtytalk/spatial @dirtytalk/engine
```

`@dirtytalk/spatial` depends on `@dirtytalk/engine` in the same way.

## React entry point

React bindings for `structural` live in a subpath export:

```ts
import { useStructural } from '@dirtytalk/structural/react';
```

The core entry point `@dirtytalk/structural` has no React dependency. The `react` subpath requires `react` version 18 or later. It is declared as an optional peer dependency (`react: >=18`), so install it yourself if your project does not already have it:

```sh
pnpm add react
```

See [Structural: React](/docs/structural/react/).

## Module formats

All packages ship ESM and CommonJS builds with type declarations for each, selected through the `exports` map.

```ts
// ESM
import { DirtyChannel } from '@dirtytalk/engine';
```

```js
// CommonJS
const { DirtyChannel } = require('@dirtytalk/engine');
```

The packages are marked `sideEffects: false`, so bundlers can tree-shake unused exports.

## TypeScript

Types are bundled. No `@types/*` package is needed. For `@dirtytalk/structural/react`, resolve the subpath with a `moduleResolution` that honors `exports` (`node16`, `nodenext` or `bundler`). The package also provides a `typesVersions` entry for older resolution modes.

## Runtime requirements

- The published packages do not declare an `engines` field. The Node range in the repository root (`^22.18.0 || >=24.11.0`) applies to developing the monorepo, not to using the packages.
- The code uses ES2022 features (private class fields) and `AggregateError`, so the target runtime must support them.
- `MicrotaskScheduler` calls `queueMicrotask`.
- `RAFScheduler` uses `requestAnimationFrame` when `globalThis.requestAnimationFrame` is a function. Otherwise it falls back to `setTimeout` with a 16 ms delay, so it also works in Node and test environments.
- `SyncScheduler` and `ManualScheduler` need no platform APIs.

See [Schedulers](/docs/engine/schedulers/).

## Versioning

> **Warning:** All packages are 0.x and pre-1.0. Breaking changes can ship in minor and patch releases.

- Pin exact versions in `package.json` (no `^` or `~`):

  ```sh
  pnpm add --save-exact @dirtytalk/engine
  ```

- Read the changelog before upgrading: `packages/engine/CHANGELOG.md`, `packages/structural/CHANGELOG.md` and `packages/spatial/CHANGELOG.md` in the [repository](https://github.com/jsnanigans/dirtytalk).
- Keep `engine` compatible with the `engine` range required by `structural` and `spatial`, so that a single copy of `@dirtytalk/engine` is installed.
