Upgrade FlowPanel
Align package versions, review migrations and changes, and validate generated and ejected surfaces.
FlowPanel workspace packages are released together. Most applications should depend on the umbrella @flowpanel/kit and local @flowpanel/cli at the same version rather than pinning lower-level packages independently.
Inspect the current install
pnpm list "@flowpanel/*"
pnpm flowpanel doctorBefore changing versions, record ejected files and any direct lower-level FlowPanel dependencies. Read the changelog for every version you will cross.
Update aligned packages
pnpm up "@flowpanel/*" --latest
pnpm installKeep direct FlowPanel packages on the same released version. Multiple copies of @flowpanel/core can split request context and module augmentation; flowpanel doctor checks for that condition.
Review database work
pnpm flowpanel migrate --dry-runReview pending SQL for the target dialect and deployment strategy before applying it. Back up production data according to the application's normal migration policy, then run pnpm flowpanel migrate in the controlled release step.
Validate the application
Run the application's typecheck and production build. Start the admin once so config compilation can catch duplicate/reserved names, stale columns, and unresolved references. Exercise auth, one scoped read/write, forms, actions, realtime, and queues used by the deployment.
Review ejected files
Ejected files contain a version stamp and are application-owned. The upgrade does not rewrite them. Compare their public imports and behavior with the changelog and current reference; test them separately from generated routes.
If a newer config, renderer, page, or slot now covers the customization, consider returning that surface to generated behavior. Re-enabling config also requires removing the explicit Next.js route.
Upgrading from 0.2 to 0.3
0.3 changes a few defaults and removes one dead option. Read this list against your flowpanel.config.ts before you upgrade.
- Rows open the detail page. A resource that configures
detailand nodrawernow navigates on row click and on Enter. SetrowClick: falseto keep rows inert, orrowClick: "drawer"where a drawer exists. - Pie charts show their legend.
pieChart({ showLegend: false })restores the previous look. table()honoursemptyStateandlimit. Both were declared and ignored; a table that relied on seeing every row of aqueryshould droplimit.detail.headeris deprecated. Move it todetail.title;subtitleandbadgeare new slots beside it.titlewins when both are set.- Validation messages come from
labels.form. An empty required field reads"{label} is required"(labels.form.required) instead of a Zod type message; custom messages still pass through. Override the key to change the wording. audit.retentionis removed. It was never applied; delete the line and keep retention where the rows live.- Drawer field payload shape. A drawer's serialized
fieldsare{ name, label? }objects instead of bare names. Only a host reading the drawer payload directly is affected. - Workers publish through
@flowpanel/kit/publish.createPublisher({ redis })replacesbindPublisher(config)in a publish-only process. The Redis wire is unchanged, so 0.2 and 0.3 instances interoperate during a rolling deploy. formatNumber's third argument. It is now the resolvedformattingobject (useFormatting()in a client component,resolveFormatting(config.formatting)on the server), not a locale string. A bare locale string still works and keeps 0.2'sUSD/UTC, so an ejected widget compiles either way.Datevalues in cards and ticks. ADatein astat,statGrouporkvvalue, and every chart x-axis tick, now renders through the admin'sformatting(locale,timeZone) like a table cell instead of the server's own clock. Drop any hand-rolledtoISOString().slice(0, 10)in a widget resolver.ctx.countrejects an unknownwherekey. A key the adapter does not report as a column throws a config error naming the field and the resource, on both count paths, instead of silently counting the whole table on Drizzle and throwing inside Prisma.HealthBanner's error tone is"err". The component now speaks the sharedTonevocabulary; renametone="error"totone="err".StatItem.valuetakes onlyctx. Its never-passed secondrowparameter is gone; the record isctx.row.- The memory realtime driver serialises payloads. Like Redis, it now JSON-encodes on publish and decodes on delivery, so a
Datein a payload arrives as a string and a non-serialisable payload throws in development too, with or without a subscriber. ctx.dbstays. Its deprecation notice now names 1.0 as the removal target;ctx.sqlandctx.countare the supported way to query from a widget.- New package. Add
@flowpanel/testas a dev dependency next to@playwright/testto runsmokeAdminin your browser suite.
Pre-1.0 expectations
Before 1.0, minor releases may contain breaking changes. Types and deprecation notes are part of the migration path, but they do not replace the changelog and application tests. Upgrade in a reviewable branch and avoid mixing unrelated dependency changes.
If the installed behavior and current site disagree, use the versioned package types and release notes as the authority and report the documentation mismatch.