upgrade-pracht
Upgrade the `@pracht/*` packages safely: inventory installed versions, read the changelogs between installed and target, map breaking changes to real usage, apply, then walk the verification ladder (d
SKILL.mdskills/upgrade-pracht/SKILL.md
GitHubPracht Upgrade
Upgrade @pracht/* dependencies with the changelog read before the install,
not after the build breaks.
Step 1: Inventory
List every installed pracht package and its resolved version:
pnpm list --depth 1 --json | grep -A2 '@pracht/' # or read package.json + lockfile
The family, in full: @pracht/core, @pracht/cli, @pracht/vite-plugin,
@pracht/adapter-node, @pracht/adapter-cloudflare,
@pracht/adapter-netlify, @pracht/adapter-vercel,
@pracht/adapter-static, @pracht/preact-ssr-precompile,
@pracht/capabilities, @pracht/content, @pracht/markdown,
@pracht/openapi, @pracht/image, @pracht/i18n, @pracht/session,
@pracht/test, plus the create-pracht scaffolder (which is not a runtime
dependency and does not need to move with the rest). Get the latest published
versions with npm view <pkg> version.
Step 2: Understand the versioning model
@pracht/core, @pracht/capabilities and @pracht/vite-plugin always
release together at one version (a Changesets fixed group): upgrade them to
the same version. Every other package is independently versioned —
@pracht/cli is on 1.x while core is on 0.x — so there is no "one framework
version". Two consequences:
- Internal ranges stop at the minor. Published packages depend on their
siblings with caret ranges on 0.x (e.g.
@pracht/core: ^0.20.0), and a 0.x caret never crosses a minor.@pracht/vite-plugin, the adapters,@pracht/session,@pracht/i18n,@pracht/query, and@pracht/testtake@pracht/coreas a peer, so upgrading core past their range fails withERESOLVEunder npm and warns under pnpm; forcing it through (--legacy-peer-deps,--force) can install a second core that splits the runtime. Upgrade the whole family in one move. - Most packages are 0.x, so under semver a minor bump may be breaking —
treat
### Minor Changesentries on 0.x packages with the same care as majors.
After any upgrade, confirm a single core resolution:
pnpm why @pracht/core # exactly one version may appear
Step 3: Read the changelogs between installed and target
Only @pracht/cli ships CHANGELOG.md in its npm tarball
(node_modules/@pracht/cli/CHANGELOG.md); the other packages publish dist/
only. Fetch their changelogs from the repo instead:
https://raw.githubusercontent.com/JoviDeCroock/pracht/main/packages/<dir>/CHANGELOG.md
| Package | Repo directory |
|---|---|
@pracht/core |
packages/framework |
@pracht/cli |
packages/cli |
@pracht/vite-plugin |
packages/vite-plugin |
@pracht/adapter-node / -cloudflare / -netlify / -vercel / -static |
packages/adapter-* |
@pracht/preact-ssr-precompile |
packages/preact-ssr-precompile |
@pracht/capabilities |
packages/capabilities |
@pracht/content |
packages/content |
@pracht/markdown |
packages/markdown |
@pracht/openapi |
packages/openapi |
@pracht/image |
packages/image |
@pracht/i18n |
packages/i18n |
@pracht/session |
packages/session |
@pracht/test |
packages/test |
create-pracht |
packages/start |
Changelogs are changesets-generated: ## X.Y.Z sections containing
### Major Changes / ### Minor Changes / ### Patch Changes. Read every
section between the installed and target version of every installed package.
Step 4: Map changes onto this app
Classify each entry as breaking / feature / fix. For each breaking
(or 0.x minor) entry, grep the app for the APIs, exports, config options, and
generated-file shapes it names, and record: affected files, the migration the
changelog prescribes, and whether it can be applied mechanically. Also
re-check peer ranges after a major target bump — @pracht/vite-plugin
requires vite (^8), @pracht/adapter-cloudflare requires vite and
wrangler (^4.81), @pracht/core requires preact (^10) and
preact-render-to-string (^6.7).
Present the plan as a table:
| Package | Installed → Target | Breaking entries | App impact | Migration |
|---|
Step 5: Confirm, then apply
Use AskUserQuestion before touching anything when breaking migrations are
required: confirm the target versions and which migrations to apply. Then:
pnpm up '@pracht/core@<v>' '@pracht/cli@<v>' '@pracht/vite-plugin@<v>' <adapters...>
Upgrade every installed @pracht/* package in the same command. Apply the
agreed code migrations with minimal diffs, one changelog entry at a time.
Then read the page behind each changed API with pracht docs <topic>, which
serves the docs bundled with the newly installed CLI. A CLI without that
command predates it; use https://pracht.resynapse.dev/llms.txt instead.
Step 6: Verification ladder
Run in order; stop and fix at the first failure:
pracht doctor --json # wiring still valid
pracht typegen --check # generated route types up to date?
pracht typegen # regenerate if --check failed or routes changed
pracht verify --json # framework-aware checks
pnpm typecheck # both tsconfig programs, if the app has the script
pracht build # full production build (budgets included)
pnpm test # the app's own suite
pracht doctor, verify, and typegen --check exit non-zero on failure, so
they gate CI cleanly. Act on doctor warnings too: pnpm up never touches
files create-pracht wrote, so a warning is how an older scaffold learns it
needs a config change — for example adding "src/**/*.d.ts" to the
include of tsconfig.client.json, without which typed route hooks are
unknown in client code and <Link route> accepts any string.
Step 7: Rollback note
If the ladder cannot be made green, roll back rather than shipping a half-upgrade:
git restore package.json pnpm-lock.yaml && pnpm install
git checkout -- <migrated files> # or revert the upgrade commit
Because internal ranges stop at the minor, a partial rollback (one package back, the rest forward) hits the peer conflicts or duplicate core from Step 2 — roll the whole family back together.
Rules
- Never mix
@pracht/*versions from different release waves — upgrade and roll back the family as a unit, and verify withpnpm why @pracht/core. - Read changelogs before installing, not after something breaks.
- Never apply a breaking-change migration without explicit user confirmation
via
AskUserQuestion. - Treat 0.x minor bumps as potentially breaking.
- Do not hand-edit lockfiles; let the package manager resolve.
$ARGUMENTS