# Migrating to @godxjp/ui v32

v32 turns `@godxjp/ui` from a framework tuned for GoDX products into a framework any team can adopt:
neutral defaults, open localization, an inert install, styles that work without Tailwind, and a
smaller, more honest component surface. GoDX products keep their exact look through the GoDX preset.
All six packages (`@godxjp/ui`, `@godxjp/ui-mcp`, `@godxjp/markdown`, `@godxjp/editor`,
`@godxjp/block-editor` and the new `@godxjp/chat`) move to 32.0.0 together.

Most of the upgrade is mechanical. Run the codemod first, then read the list below for what it
reports but cannot decide.

```sh
npx godxjp-ui codemod v32 src --dry-run   # preview
npx godxjp-ui codemod v32 src --godx      # a GoDX product: keep today's look
npx godxjp-ui codemod v32 src             # any other app
```

Off-cycle approved: owner, 2026-10-09 — the single v32 batch decided on godx-jp/godxjp-ui#1205
(recorded by Claude from the owner's instruction "do it all in one batch, one major, one CD run").

## Breaking changes

### Neutral identity; GoDX is a preset (#1220)

- The default `--primary` and `--brand` are a neutral ink (`240 6% 10%` light, `0 0% 98%` dark), not
  the GoDX violet. Hover and pressed steps stay visible at both ends of the lightness ramp.
- `AuthIdentity` renders no mark when `brand` is omitted, unless a preset provides one. `null` always
  renders none.
- The email brand mark has no default label.
- The GoDX look ships as `godxPreset` (`@godxjp/ui/themes/godx`) plus `@godxjp/ui/themes/godx.css`.
- Since 32.0.1, `@godxjp/ui/themes/godx-tokens.css` holds the GoDX colours without the fonts.
  `godx.css` is `fonts.css` (which imports `@fontsource/noto-sans-jp` and `@fontsource/m-plus-2`)
  plus `godx-tokens.css`. Import `godx-tokens.css` instead of `godx.css` when the app bundles or
  hosts its own fonts, and in a shadow root that embeds `@godxjp/ui/styles/core` (`@font-face`
  only works in the document). Never import both. Put it after the base stylesheet.
- A script that READS the GoDX colours from `themes/godx.css` (a token sync, a design-system
  export) must read `themes/godx-tokens.css` instead: since 32.0.1, `godx.css` holds only two
  `@import` lines.
- Emails: `EMAIL_TOKENS_GODX` / `EMAIL_TOKENS_GODX_JSON` from `@godxjp/ui/email` keep the GoDX
  violet and a prebuilt GoDX mark (`EMAIL_BRAND_MARK_GODX`, labelled "GoDX", identical to the 31.x
  default mark). The parts are exported too: `EMAIL_COLORS_GODX`, `EMAIL_COLORS_GODX_DARK`,
  `EMAIL_BRAND_LABEL_GODX`. The mark is complete since 32.0.2.

### Locale defaults and open localization (#1219)

- `AppProvider`'s `defaultLocale` now defaults to `<html lang>` when it names a registered locale, then
  the preset's locale, then `en`. It used to be `vi`.
- `AppLocale` is `string` (any BCP-47 tag). The three built-in packs are `BuiltInLocale`.
- Register another locale with `registerLocale({ code, messages, dateFns, dayPicker })`. Date order,
  separators and the first day of the week come from `Intl`.
- `registerMessages` throws for an unregistered locale.
- Server rendering: pass `defaultLocale` explicitly and wrap each request in
  `runWithAppSettings(settings, render)`, so concurrent requests cannot read each other's locale,
  timezone or formats.

### Fonts are opt-in; styles work without Tailwind (#1221)

- `@godxjp/ui/styles` no longer imports the Japanese fonts. Add
  `@godxjp/ui/styles/fonts.css` after it (the codemod does), and install `@fontsource/noto-sans-jp`
  and `@fontsource/m-plus-2`, which are now optional peers.
- New: `@godxjp/ui/styles.css`, a precompiled stylesheet for apps without Tailwind.

### Install and package (#1215, #1216, #1222)

- Installing writes nothing into your project. Run `npx godxjp-ui sync-rules` (preview with
  `--dry-run`) after installing and after each upgrade to refresh the agent files.
- `sideEffects` now lists CSS, so bundlers keep `@godxjp/ui/styles`.
- `react-aria-components`, `react-aria` and `react-stately` are pinned in lockstep (1.22.0 / 3.53.0 /
  3.51.0), so an install resolves one copy of each. `engines.node` is `>=22`.

### Component surface (#1223)

The catalog goes from 185 entries to 161: 134 in core, 15 in `@godxjp/ui/lab`, 12 in sibling
packages. The codemod rewrites every import below; the "you finish" column is printed as a `note`.

| v31                                                                                                                                                                                                                | v32                               | You finish                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- | ---------------------------------------------------------------------- |
| `Banner`                                                                                                                                                                                                           | `Alert`                           | add `variant="banner"`                                                 |
| `Callout`                                                                                                                                                                                                          | `Alert`                           | add `variant="callout"`; it keeps `role="note"`                        |
| `TagInput`                                                                                                                                                                                                         | `Select`                          | add `mode="tags" open={false}`; `Select` takes no `ref`                |
| `Thumbnail`                                                                                                                                                                                                        | `Image`                           | add `fit="intrinsic" preview={false}`                                  |
| `HoverCard` (+ Trigger, Content)                                                                                                                                                                                   | `Popover` (+ Trigger, Content)    | add `openOn="hover"`; `openDelay` / `closeDelay` keep working          |
| `AuthShell`                                                                                                                                                                                                        | `CenteredShell`                   | add `variant="auth"`; `variant="canonical"` becomes `"auth-canonical"` |
| `SpaceCompact`                                                                                                                                                                                                     | `Flex`                            | add `attached`; `orientation`/`vertical` become `direction="col"`      |
| `AppSettingToggle`                                                                                                                                                                                                 | `AppSettingPicker`                | add `menu={false}`                                                     |
| `Title`, `Paragraph`, `Typography`                                                                                                                                                                                 | `Heading`, `Text as="p"`, `Prose` | the antd compatibility shims are removed                               |
| `SkeletonAvatar`, `SkeletonButton`, `SkeletonImage`, `SkeletonNode`                                                                                                                                                | —                                 | removed: use `SkeletonArticle avatar` or a sized `Skeleton`            |
| `FloatButton`, `DraggablePanel`, `PageCover`, `Masonry`, `LegalDocumentShell`, `Marquee`, `TextDiff`, `OrgChart`, `Carousel`, `TimelineGrid`, `RangeTimeline`, `EmojiPicker`, `SortableList`, `MegaMenu`, `Anchor` | same names from `@godxjp/ui/lab`  | nothing: same API, opt-in subpath                                      |
| `ChatBubble`, `ChatBubbleList`, `ChatComposer`, `ChatSuggestion`, `Conversations`, `ThoughtChain`, `Welcome`, `Attachments`                                                                                        | same names from `@godxjp/chat`    | add `@godxjp/chat` as a NEW dependency, same version as `@godxjp/ui`   |

Unchanged: `SplitPane` stays (its merge into `MasterDetail` failed the parity test), `Actions` stays
in `@godxjp/ui/general`, and `FilterBar` stays an alias of `Toolbar`. The `./ui/*` subpaths are
deprecated re-exports and will be removed in a later major.

## How to upgrade

1. Upgrade all six packages to the latest 32.0.x together. An app that imports `ChatSuggestion` or
   any other chat component from `@godxjp/ui` must ADD `@godxjp/chat` to its `package.json` — it
   is a new dependency, not a rename — at the same version as `@godxjp/ui` (the packages release
   in lockstep). Without it the build fails on the first chat import.
2. Run `npx godxjp-ui codemod v32 <src> --dry-run`, review, then run it without `--dry-run`. Use
   `--godx` for GoDX products.
   The 32.0.0 codemod imported the fonts twice under `--godx` (`fonts.css` and `godx.css`, which
   already imports them). Re-running the 32.0.1 codemod removes the extra `fonts.css` import.
3. Finish every `note` the codemod printed (a component move that changes props, an `AppProvider`
   that relied on the old `vi` default).
4. Install the font packages if you keep the Japanese fonts.
5. Run `npx godxjp-ui sync-rules` and restart your coding agent.
6. Build, then compare a few screens: with the GoDX preset they should be pixel-identical to 31.x.

## Support

v31 receives no further releases. A security fix for v31 is an owner exception, decided case by case.
From v32 on, a new major ships at most once per quarter, and the publish job refuses a major whose
migration note is missing or incomplete.
