---
title: "createTheme"
description: "Compiles a theme from a schema tree and the token tree it describes."
url: "https://pitlane.tools/package/theme/function/createTheme"
---

# createTheme

```ts
import { createTheme } from "@pitlane/theme";
```

## Call Signature

```ts
function createTheme<schema, tokens>(init): ThemeResult<{
  schema: schema;
  tokens: tokens;
}>;
```

Compiles a theme from a schema tree and the token tree it describes.

Values are the CSS they become: a color is any CSS color, a dimension is any CSS length, and a composite is the shorthand text. The schema names each token's type, which is what the accessor's compile-time brands are read from and what `css()` enforces.

A reference to another token is a property access on the layer below, so it needs an [ThemeResult.extend](https://pitlane.tools/package/theme/interface/ThemeResult.md#extend) layer. The accessor leaf is already a `var()` string, which keeps its indirection in the emitted CSS so a mode override cascades through it. There is no string syntax for a reference; a leftover `"{a.b.c}"` raises [ThemeError](https://pitlane.tools/package/theme/class/ThemeError.md).

All validation and serialization happen eagerly: a malformed theme throws at module load rather than emitting broken CSS. Bad values raise `ValidationError` from `remix/data-schema`, carrying one issue per bad token with its path. Structural problems raise [ThemeError](https://pitlane.tools/package/theme/class/ThemeError.md).

### Type Parameters

#### schema

`schema` _extends_ `object`

#### tokens

`tokens` _extends_ `object`

### Parameters

#### init

The schema, tokens, and modes, or a `<Theme />` to re-derive from

##### modes?

`Record`\<`string`, [`ThemeMode`](https://pitlane.tools/package/theme/interface/ThemeMode.md)\<`tokens`>>

##### schema

`schema`

##### tokens

`tokens`

### Returns

[`ThemeResult`](https://pitlane.tools/package/theme/interface/ThemeResult.md)\<{ `schema`: `schema`; `tokens`: `tokens`; }>

The [ThemeResult](https://pitlane.tools/package/theme/interface/ThemeResult.md)

### Throws

ThemeError on a structural failure

### Throws

ValidationError on one or more invalid values

### See

- [ThemeInit](https://pitlane.tools/package/theme/interface/ThemeInit.md) for the accepted shape.
- [Theme guide: Define a theme](https://pitlane.tools/guides/theme.md#define-a-theme)

### Example

```ts
import { createTheme } from "@pitlane/theme";
import * as s from "@pitlane/theme/schema";

export let { token: t, raw, Theme } = createTheme({
    schema: { color: s.color(), spacing: s.scale() },
    tokens: { color: { white: "#fff" }, spacing: "0.25rem" },
}).extend(base => ({
    schema: { color: s.color() },
    tokens: { color: { page: base.color.white } },
}));

t.color.page; // "var(--color-page)"
raw(t.color.page); // "#fff"
t.spacing(4); // "calc(var(--spacing) * 4)"
```

## Call Signature

```ts
function createTheme<T>(theme): ThemeResult<T>;
```

Compiles a theme from a schema tree and the token tree it describes.

Values are the CSS they become: a color is any CSS color, a dimension is any CSS length, and a composite is the shorthand text. The schema names each token's type, which is what the accessor's compile-time brands are read from and what `css()` enforces.

A reference to another token is a property access on the layer below, so it needs an [ThemeResult.extend](https://pitlane.tools/package/theme/interface/ThemeResult.md#extend) layer. The accessor leaf is already a `var()` string, which keeps its indirection in the emitted CSS so a mode override cascades through it. There is no string syntax for a reference; a leftover `"{a.b.c}"` raises [ThemeError](https://pitlane.tools/package/theme/class/ThemeError.md).

All validation and serialization happen eagerly: a malformed theme throws at module load rather than emitting broken CSS. Bad values raise `ValidationError` from `remix/data-schema`, carrying one issue per bad token with its path. Structural problems raise [ThemeError](https://pitlane.tools/package/theme/class/ThemeError.md).

### Type Parameters

#### T

`T`

### Parameters

#### theme

[`ThemeComponent`](https://pitlane.tools/package/theme/interface/ThemeComponent.md)\<`T`>

### Returns

[`ThemeResult`](https://pitlane.tools/package/theme/interface/ThemeResult.md)\<`T`>

The [ThemeResult](https://pitlane.tools/package/theme/interface/ThemeResult.md)

### Throws

ThemeError on a structural failure

### Throws

ValidationError on one or more invalid values

### See

- [ThemeInit](https://pitlane.tools/package/theme/interface/ThemeInit.md) for the accepted shape.
- [Theme guide: Define a theme](https://pitlane.tools/guides/theme.md#define-a-theme)

### Example

```ts
import { createTheme } from "@pitlane/theme";
import * as s from "@pitlane/theme/schema";

export let { token: t, raw, Theme } = createTheme({
    schema: { color: s.color(), spacing: s.scale() },
    tokens: { color: { white: "#fff" }, spacing: "0.25rem" },
}).extend(base => ({
    schema: { color: s.color() },
    tokens: { color: { page: base.color.white } },
}));

t.color.page; // "var(--color-page)"
raw(t.color.page); // "#fff"
t.spacing(4); // "calc(var(--spacing) * 4)"
```
