| Field | Value |
| --- | --- |
| Version | `3.0.0` |
| Packages | `asheeui` `3.0.0`, `@asheeui/core` `3.0.0`, `@asheeui/web` `2.8.0`, `@asheeui/native` `2.8.0`, `@asheeui/puck` `2.3.1`, `@asheeui/cli` `1.0.1` |
| Previous release | the `2.7` line (`@asheeui/web` and `@asheeui/native` `2.7.0`, core `2.5.0`) |
| Breaking changes for an existing application | **Yes.** This is the major where core stops rendering and the umbrella stops being `export *` over the renderers. |

AsheeUI 3.0 is the release where the **contract stopped being an engine**. `@asheeui/core` keeps the
tokens, the rules, the types and the configuration cascade — the part that is true on both platforms.
Every pixel decision moved to the renderer that compiles it. The umbrella stopped re-exporting both
renderers and became the list of names that are actually portable.

The result is a smaller core, two renderers that own their implementations, and one import a shared
screen can use without learning which platform it is on.

## What changed

### Core is the contract, not the engine

- Both class dictionaries left core: the web's constants moved to `@asheeui/web`, the platform's to
  `@asheeui/native`. `@asheeui/core` now declares **no dependencies** and contains **no class string**.
- Core keeps the tokens, the typography role table, the palette model, the cascade, the shared rules
  (`isFieldInvalid`, `resolveFieldStatusColor`, `UnderlineRadius`, `selectTheme`, the breakpoint
  resolver) and the configuration types.
- The compatibility matrix moved to **`@asheeui/core/dev`**. It is data for tooling — the parity guard,
  the umbrella guard, the CLI, this documentation — not something a component renders.
- `pnpm check:core-charter` is the ratchet: no class string, no dependency, no renderer import, and
  every export has a reader. It is a blocking CI step.

### The umbrella is the intersection

`asheeui` publishes **182 names** (90 from core, 92 from the branch renderer) plus `AsheeConfig`. A name
is on it only when both renderers publish it under the same name and contract.

- The list is declared once, as `PORTABLE_API` in `@asheeui/core`, and both umbrella entries are
  generated from it. The branches cannot drift.
- Renderer-only names stay with their renderer: `Breadcrumb`, `ResizableScreen`, `SkipLink` and the
  keyboard family on the web; `RowList` and `TabBar` on a device.
- The umbrella owns three subpaths: `asheeui/styles` (the web stylesheet), `asheeui/tailwind-preset`
  (the native preset) and `asheeui/section-kit` (the composition vocabulary).
- The renderers are optional peers; an application installs the one it builds for.

### The native contract is complete

Every component the matrix promises for native is implemented and tested with the platform's own
tooling. The native parity guard reads what the package **publishes**, not what its file names suggest,
and fails when the matrix, the exports and the queue disagree. The queue is empty.

The provider names align with the web renderer: `AsheeUIProvider` is the current name, and
`AsheeNativeProvider` is an alias that warns once per process.

### Puck is one document, two renderers

`@asheeui/puck` keeps one set of block specs and two renderings. The editor is a web concern; a device
bundle imports the native renderer and never `@puckeditor/core`. The editor is an optional peer of the
web half alone. See [Puck](/platforms/puck).

### Two reference applications

The repository ships a fitness tracker as one shared kit and two applications: TanStack Start on the
web with a top `Navbar`, Expo on a device with a header and a bottom `TabBar`, and a Puck studio on
both. It is the layout [the monorepo blueprint](/guides/monorepo) describes, with seven screens.

## Breaking changes

| Change | What to do |
| --- | --- |
| Class dictionaries and `cn` are no longer published by `@asheeui/core` | Import the renderer's own utility, or stay on the portable surface |
| The compatibility matrix moved | Change `@asheeui/core` to `@asheeui/core/dev` |
| `ExternalColorVariant` is no longer a root export | Type a palette as `ExternalColorConfig`; the variant is its internal shape |
| The umbrella is no longer `export *` | A name only one renderer has must be imported from that renderer |
| `asheeui/styles` and `asheeui/tailwind-preset` are the umbrella paths | The renderer paths still work; the umbrella path is the default |
| `RowList` and `TabBar` are native-only | Keep them in the native shell, not in a shared screen |
| The native provider names changed | `AsheeUIProvider`, `AsheeUIProviderProps`, `AsheeConfigContext`, `useAsheeConfig`; the old names warn and are removed in the next major |

The detailed paths are [Migrating the umbrella](/guides/migration-umbrella) and
[Migrating the core layer](/guides/migration-core). The target layout is
[the monorepo blueprint](/guides/monorepo).

## What was deliberately not done

| Not done | Why |
| --- | --- |
| Per-component subpaths | The umbrella is one entry and three subpaths; a page imports the name, not a door per component |
| A native Puck editor | Composing is a web authoring concern; the device renders the document |
| One Tailwind version for both | The web is Tailwind 4 and NativeWind is Tailwind 3; the umbrella spans both rather than pretending they are one compiler |
| Sharing renderer source | Sharing source would give one platform the other's behaviour, which is what the contract split exists to avoid |

## The release set

| Package | Version | What it contains |
| --- | --- | --- |
| `asheeui` | `3.0.0` | The portable surface, generated from `PORTABLE_API` |
| `@asheeui/core` | `3.0.0` | Tokens, rules, types, cascade; no classes, no dependencies |
| `@asheeui/web` | `2.8.0` | The DOM renderer and its dictionaries |
| `@asheeui/native` | `2.8.0` | The React Native renderer and its dictionaries |
| `@asheeui/puck` | `2.3.1` | The shared block specs and the two renderings |
| `@asheeui/cli` | `1.0.1` | `asheeui list` and `asheeui check` against the published matrix |

The packages version independently. The [current release](/releases/latest) keeps the table and the
short form; [the migration hub](/migration) records every breaking change.
