Skip to content

[v3 stable docs] Publish the final production migration and verification playbook #175

Description

@olliethedev

Stable-v3 cohort documentation correction — 2026-08-31

The stable-v3 guide must use the cohort verified by #244, better-auth-ui#22, and #174:

  • retain @btst/db@2.2.3 and the 2.2.3 adapters without a Better Auth fork upgrade;
  • use Better Auth 1.6.16, Core 1.6.16, Utils 0.4.1, Fetch 1.2.2, and Better Call 1.3.6;
  • use matching API-key and passkey 1.6.16 packages only when those optional features are enabled; and
  • require explicit adapter transaction: true configuration when installed plugins perform atomic writes, including Form Builder and Media.

The guide must not instruct v3 users to upgrade the BTST database fork to Better Auth 1.7.2. Future fork synchronization is separate post-v3 work.

This correction supersedes preserved planning text that names Better Auth 1.7.2 as the stable-v3 target.


This was generated by AI during triage.

Current status — 2026-08-31

RC3 is already published, core #202 is complete, and better-auth-ui#20 has shipped as 2.0.0-rc.3. This issue now targets the stable-v3 guide, not an RC3 publication gate.

Updated sequencing:

  1. incorporate the corrected dependency-cohort decision from [v3 RC4] Align Better Auth UI with the retained @btst/db cohort #244 and better-auth-ui#22, plus codegen behavior from RC3 codegen cannot load a real Next.js stack config #246;
  2. consume the restored optional companion scaffold from [v3 stable] Restore the Better Auth UI CLI scaffold and documentation #219 and the completed cross-repository contract evidence from [v3 stable] Verify exact Better Auth UI override contracts across repositories #170;
  3. use Add packed npm/pnpm compatibility smoke tests #174 as the permanent executable packed-consumer check rather than as a static compatibility catalog;
  4. update the canonical migration page against the newest release candidate; and
  5. pass docs builds, links, snippets, and clean-room migration verification before stable v3 publication.

The Better Stack Web RC3 audit is complete in better-stack-web#37. Bio Mogging #109 remains post-publication/user-owned validation and is non-blocking.

Any preserved wording below that says this work must finish before RC3 publication is superseded by this stable-release status.


Parent

What to build

Turn the existing v2-to-v3 guide into the canonical production migration and verification playbook for the final RC3 API. Preserve concise API diffs, but replace stale RC2 assumptions with the runtime/plugin design from #202, the final authorization contract delivered by #180#193, the executable compatibility contract from #174, and the separately maintained Better Auth UI boundary documented by better-stack-ai/better-auth-ui#20.

This guide must be sufficient for a developer who did not participate in the v3 design to migrate a non-trivial full-stack application without reading source code, release-tracker comments, or retained audit lockfiles.

Final RC3 ownership model

The migration path must consistently teach:

const stack = createClientStack({
  api: { baseURL, basePath: "/api/data" },
  site: { baseURL, basePath: "/pages" },
  queryClient,
  plugins: {
    blog: blogClientPlugin(),
    comments: commentsClientPlugin(),
  },
})
<StackProvider
  stack={stack}
  router={router}
  auth={clientAuth}
  initialIdentity={initialIdentity}
  overrides={{
    blog: {
      post: { /* actual plugin-specific customization */ },
    },
  }}
>
  {children}
</StackProvider>

The exact field names must match the landed #202 API. The normative concepts are:

  1. createClientStack owns API/site/query/request runtime and client plugin registration.
  2. StackProvider consumes the resolved browser-safe stack projection plus framework services and optional application-owned authorization.
  3. Plugin overrides contain only genuine plugin-specific presentation/browser behavior.
  4. Override keys/types are inferred from registered plugins.
  5. Omitting overrides is the canonical zero-customization path; empty blocks do not activate plugins.
  6. Server-only headers, secrets, backend stacks, and server auth never cross into browser code.

Final authorization chapter

Remove the stale #172/#173 migration assumptions and document the landed #180#193 contract directly:

  • Plugins publish schema-backed, typed permission descriptors and the minimum facts required for an operation.
  • Applications own the runtime identity schema and one browser-safe synchronous defineAuthorization rule set.
  • createClientAuth and createServerAuth resolve identity independently against the same schema; authentication finds the identity and authorization decides permissions.
  • Browser checks are local presentation checks and may use session claims such as role; they make no permission request and install no authorization-result cache.
  • The backend is authoritative: operations validate input, derive trusted facts, resolve the request identity, evaluate the declared permission, then enter lifecycle/domain execution.
  • forRequest(request).api is request-authorized; the trusted operation surface skips user authorization but preserves validation/domain/lifecycle; explicit raw access bypasses composition and is not the ordinary app API. Use the final names produced by [v3 RC3 DX] Centralize client runtime configuration and normalize all plugin interfaces #202.
  • Enabled authorization with no matching rule denies; omitting server authorization preserves the documented permissive compatibility behavior.
  • Local full-stack apps may import one browser-safe rule module on both sides. Managed/custom/separate backends share the rule-free versioned contract and may use an asynchronous remote evaluator.
  • Remote backends never trust browser identity or browser-supplied record facts; they resolve identity and facts authoritatively.
  • Ordinary denials are 401 for anonymous and 403 for authenticated callers. Identity/schema/transport/fact/policy failures remain errors rather than false.
  • initialIdentity is tri-state: undefined means unresolved and fetches, null means settled anonymous, and an identity means settled authenticated. Framework layout/parent-route helpers hydrate it without duplicating the initial request.
  • Session changes use explicit refresh/refetch at the application/framework seam.
  • Row/tenant query scoping is a separate server-only data concern, not boolean UI authorization.
  • Core exports no provider-specific auth adapter and no global open-string useCan/CanAccess API.

Include compact, type-checked client rule, server resolver, bound descriptor, operation, managed-backend contract, and hydration examples. Clearly label which modules are browser-safe, client-only, server-only, or publishable across repositories.

Better Auth UI companion boundary

After the corrected companion docs under better-stack-ai/better-auth-ui#22 are final, the core migration guide must link to and summarize the same boundary:

  • Better Auth is configured by the application and remains a prerequisite.
  • Better Auth UI reads its own Better Auth session and uses Better Auth native account/organization/permission APIs.
  • The companion exports no Better Auth-to-BTST client/server auth or identity factories.
  • Applications that want the same user in BTST authorization write a small app-owned createClientAuth/createServerAuth identity mapping; fields such as role/tenant remain application-owned.
  • Session synchronization is explicit: Next.js refresh, React Router revalidation, TanStack invalidation, or client-auth identity refetch.
  • Auth plus account is the minimal installation; organization/API-key/passkey/multi-session require matching optional Better Auth plugins.
  • authClient is configured once under auth, avatar only under account, exact account/organization override contracts reject auth-only fields, and route bases derive from the resolved site runtime.
  • Optional adapter subpaths list their extra peers; the base install does not pull them all in.

Do not duplicate the companion's complete reference guide or upstream Better Auth setup. Link to focused references and keep core's guide centered on the migration boundary.

Staged migration playbook

  1. Preflight and exact versions — record the current baseline, select the exact stable or next cohort from Add packed npm/pnpm compatibility smoke tests #174, install cleanly with the application's package manager, and preserve a rollback point.
  2. Constructors and runtime — migrate to canonical backend/client constructors, one client runtime, server-import-safe client plugin definitions, request-specific SSR stack creation, and the browser-safe provider projection.
  3. Plugin registration and IDs — migrate programmatic IDs to canonical camelCase, update full-stack registration, remove duplicate API/site/query/header fields, and preserve explicit per-plugin transport boundaries.
  4. Provider and overrides — remove manual override maps and empty activation blocks; keep only real plugin customization and framework services.
  5. Backend factories and lifecycle hooks — migrate every used plugin to one options object, nested hooks, the final lifecycle vocabulary, and explicit required domain dependencies.
  6. Authorization — define typed descriptors/rules/identity resolvers, preserve authoritative trusted facts and 401/403/error behavior, and audit request/trusted/raw call sites.
  7. Framework entry points and identity hydration — adopt API/page/layout helpers, including request-aware Next.js clients and dedicated wrapper pages with synthetic params where needed.
  8. Embedded surfaces — migrate comments, forms/direct hooks, cards/counts, and independent provider roots outside the primary catch-all layout.
  9. Better Auth UI — migrate to the corrected v3 companion on the retained Better Auth 1.6.16 cohort, exact overrides, derived route bases, minimal optional feature set, and explicit session refresh.
  10. Data and production verification — validate adapter/schema changes, existing records, optimized build/start, SSR/SSG/ISR, browser navigation/hydration/errors, authorization roles, and representative mutations.
  11. Cleanup — remove old constructors, positional hooks, kebab-case programmatic IDs, duplicated runtime wiring, manual override maps, legacy authorization APIs, and temporary compatibility wrappers.

Verification matrix

The guide must provide a copyable checklist covering:

  • clean install from the selected exact cohort with no undocumented peer repair;
  • typecheck, lint, schema generation/migration, optimized build, and production start;
  • server/client bundle separation and no serialized request headers/secrets;
  • direct navigation, refresh, back/forward, 404/error boundaries, console/server errors, and hydration warnings;
  • SSR, authenticated SSR, SSG/ISR, metadata, sitemap, and browser refetch using the same resolved endpoints;
  • anonymous, regular-user, and privileged-user rendered controls plus backend results;
  • allowed operation, anonymous 401, authenticated 403, missing rule, identity/fact/policy error, spoofed browser facts, and trusted internal execution;
  • login/logout/account switch/session refresh across tri-state initialIdentity;
  • embedded components outside the primary layout, resource-specific sign-in return URLs, and representative plugin mutations;
  • Better Auth account/profile/avatar and only the optional features the app actually configured;
  • database and remote test-asset cleanup.

Acceptance criteria

  • The existing v2-to-v3 page remains canonical and is expanded rather than replaced by a competing guide.
  • All examples compile against the API actually landed by [v3 RC3 DX] Centralize client runtime configuration and normalize all plugin interfaces #202 and use the exact cohort published by Add packed npm/pnpm compatibility smoke tests #174.
  • No example uses stale [v3 DX] Make zero-customization StackProvider usage unambiguous #171 empty-override activation, [v3 auth] Preserve application identity types across client and server auth #172/[v3 auth] Make can() a typed full-stack authorization contract #173 intermediate auth shapes, open-string permissions, or provider-specific core auth adapters.
  • Constructor, runtime ownership, plugin ID, factory, lifecycle, provider, override, and server trust-surface before/after tables are complete.
  • Authorization examples preserve exact identity/fact inference, browser-local presentation, backend-authoritative enforcement, managed-backend contracts, and tri-state hydration.
  • The guide distinguishes denial from operational/schema/policy error and request-authorized from trusted/raw execution.
  • Framework examples cover request-aware Next.js, React Router, and TanStack layout/route hydration without client/server import leaks.
  • Better Auth UI wording and snippets agree with the final companion docs and exact override contract.
  • Embedded comments/forms/hooks/cards and multiple provider roots receive an explicit migration path.
  • Verification covers install, types, data, production rendering/navigation, authorization roles, representative mutations, and cleanup.
  • A generated clean-room fixture follows the guide without undocumented edits; failures feed back into the guide before RC3 publication.
  • Docs build, link checks, and available code-snippet/type fixtures pass.

Out of scope

Blocked by

The completed better-auth-ui#20 remains the source for the RC3 bridge and ownership boundary; #22 changes only the supported v3 dependency cohort and associated verification.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or requestready-for-agentFully specified and ready for an agent to implement

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions