# 27.x → 28.0.0, entry by entry

**Two entries** — `CHANGELOG.md`'s 28.0.0 breaking entries in their order, grouped by
package, lowest tier first. No legacy path, no codemod, no shim. **Entry 1 is the whole upgrade for
almost every app**: Bun 1.4.3 everywhere your app runs — laptop, CI, image. A later slice appends
its rows below the last one and never renumbers; each row's `CHANGELOG.md` line names it as `(#N)`
after the dash.

Why 1.4.3 is a floor: it changed what Bun's own transform makes of a `.tsx`. Under the scaffold's
`jsx: "preserve"` + `jsxImportSource: "solid-js"`, 1.4.2 compiled `<div/>` to
`React.createElement` and 1.4.3 to `import { jsxDEV } from "solid-js/jsx-dev-runtime"`, which
solid-js does not export — a link-time `SyntaxError: Export named 'jsxDEV' not found` in any file
that imports a component, before a line of it runs (issue #883). Every framework path installs its
own transform first; a path your app built itself must too (step 4).

### The upgrade, top to bottom

| # | Do | What you see until you do | Entries |
|---|---|---|---|
| 1 | install Bun 1.4.3 (`bun upgrade`, or `curl -fsSL https://bun.sh/install \| bash -s bun-v1.4.3`) and pin it where your app pins Bun: `.bun-version`, `packageManager`, `engines.bun` (`>=1.4.3`), CI's `setup-bun` `bun-version`, every `oven/bun:` base image (`1.4.3-alpine` / `1.4.3-slim`, by digest) | `X_BUN_VERSION` from `x` and `x doctor` on 1.4.0–1.4.2 | 1 |
| 2 | pin every `@ultimat3/*` to the one new version, `bun install` | nothing yet — a mixed install is untested | — |
| 3 | delete a hand-written test preload whose only job was `import '@ultimat3/render'` / `'@ultimat3/render/server'` — `@ultimat3/testing/preload` now installs the render loader in every test process, an app root or a package below it | nothing — it is redundant, and harmless while it stays | — |
| 4 | `grep -rnE "Bun\.build\(\|bun build" apps packages scripts` — a bundle YOUR app builds that reaches a `.tsx` (a server `--compile`, a byte measurement) adds `plugins: [serverTsxBuildPlugin]` from `@ultimat3/render/server` (server code) or builds it as an island (`x build`); the CLI's `bun build` takes no plugin, so use `Bun.build` | `No matching export in "…/solid-js/dist/solid.js" for import "jsxDEV"` | 1 |
| 5 | `x verify` | green, or a finding whose `fix:` is the edit | — |

### Entry by entry

Every package (1). Tier 4 — `@ultimat3/ui` (2).

| # | Surface | Costs you an edit if |
|---|---|---|
| 1 | `engines.bun` `>=1.4.3`, `REQUIRED_BUN`, the scaffold's images | you run any Bun below 1.4.3 anywhere: `x` and `x doctor` refuse it with `X_BUN_VERSION`. Steps 1 and 4 |
| 2 | `@ultimat3/ui/jsx-probe`, `probe`, `unprobe` | you imported them. They set a `globalThis.React` nothing reads from Bun 1.4.3 on; delete the import and the `beforeAll(probe)` / `afterAll(unprobe)` calls |
