# Headless builds and modules

Decode, validate, export, and compare builds without mounting a calculator.

Source: https://warcraftforever.com/developers/headless/

Use the same rules as the interactive calculator from a browser or Node process. The headless module has no React or DOM dependency:

```js
import { createClient } from 'https://warcraftforever.com/talents/headless.mjs';

const talents = createClient();
const layout = await talents.definition({ class: 'paladin' });
const result = await talents.validate({
  class: 'paladin',
  revision: layout.revision,
  maxLevel: 30,
  allocation: { 'paladin-holy-divine-strength': 5 }
});
console.log(result.valid, result.complete, result.pointsRemaining);

const encoded = await talents.encode({
  class: 'paladin',
  revision: layout.revision,
  maxLevel: 30,
  allocation: result.allocation,
  format: 'blizzard'
});
const decoded = await talents.decode({ class: 'paladin', maxLevel: 30, code: encoded.code });
const difference = await talents.diff({
  class: 'paladin',
  maxLevel: 30,
  before: {},
  after: decoded.allocation
});
console.log(difference.pointDelta, difference.changes);
```

`validate` takes exactly one of `code` or `allocation`. Invalid builds return `valid: false` and structured `issues`. `encode` and `diff` reject invalid allocations with `SdkError.code === 'invalid-build'`. Legality and completeness are distinct: a partial allocation may be valid. `definition` and result objects are detached from the client's cache.

`encode` supports `blizzard` (the default for talents), deprecated `compact`, and `structured`. String exports have a `code`; structured exports have a `build`. See [build exports](https://warcraftforever.com/developers/talents/exports/) for the native-format verification boundary and compatibility rules. `diff` accepts allocations or strings for both sides, interprets both against one class and revision, and returns changed ranks and a point delta.

## Dataset pins

Use [discovery](https://warcraftforever.com/developers/data/#pin-a-dataset) to obtain the `talents` dataset ID, then call `createClient({ dataset })`. The descriptor fixes the definition and revision registry. Store the dataset, class and revision beside saved strings when you need reproducible interpretation. SDK release IDs, dataset IDs, and layout revisions are separate contracts.

## Module and TypeScript entry points

Every capability has `/latest.js` for script tags and `/latest.mjs` for ES modules: `talents`, `legacy`, `tooltips`, `catalog`, and `data`. ES modules do not create `WarcraftForever` or `$WF` globals. Talents and Legacy also have `/headless.mjs` for environments without a DOM.

Browser imports use the serving module's origin for assets and API reads. Native Node does not load HTTPS modules by default: download a pinned headless module and import the local `.mjs` file, or bundle the module as part of your application. A downloaded module defaults to `https://warcraftforever.com`; `createClient({ origin })` selects another deployment. No npm package is published by this interface.

Adjacent `.d.mts` files provide TypeScript declarations. For a local download, preserve the declaration's relative dependency tree under `releases/<version>/types/`; copying only the root declaration is insufficient. `/types.d.ts` is the script-type entry; include each loaded capability's entry to compose its `WarcraftForever` and `$WF` declarations, or use the matching `/releases/<version>.d.ts` for a pinned script. Module and headless declarations do not declare these globals. The portal's [type reference](https://warcraftforever.com/developers/reference/types/) is generated from the same source.

## Errors

Check `error.code` rather than parsing messages. Headless errors distinguish invalid options, unknown classes, unsupported revisions/formats, invalid builds, and unavailable or inconsistent data. Build errors can carry `details` with validation issues. Data API failures use the same `SdkError` shape; HTTP errors return `{ error: { code, message } }` and are never cached as successful data.
