Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/init.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- 'packages/cli/**'
- 'docs/content/docs/cli.mdx'
- 'docs/content/docs/installation.mdx'
- 'docs/content/docs/breaking-changes.mdx'
- 'docs/content/docs/plugins/better-auth-ui.mdx'
- '.github/workflows/init.yml'

concurrency:
Expand Down Expand Up @@ -59,3 +61,38 @@ jobs:
name: btst-init-fixtures
path: /tmp/test-btst-init-*/
retention-days: 3

better-auth-ui-fixtures:
name: Better Auth UI packed fixtures
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

- name: Setup Node.js 22
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run packed framework fixtures
run: pnpm --filter @btst/codegen test:better-auth-ui-fixtures
env:
BTST_KEEP_FIXTURES: 1
CI: true

- name: Upload artifacts on failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: better-auth-ui-fixtures
path: /tmp/btst-better-auth-ui-*/
retention-days: 3
34 changes: 20 additions & 14 deletions docs/content/docs/breaking-changes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ deployment origins, never a server stack or request headers.
BTST core is authentication-provider agnostic. Better Auth and Better Auth UI
are not core dependencies or hidden identity bridges; adapt the provider your
application already uses through `createClientAuth` and `createServerAuth`.
The separate Better Auth UI companion migration happens downstream of the
completed core DX migration.
Applications that already run Better Auth can separately opt into the migrated
Better Auth UI companion for auth and account pages.

---

Expand Down Expand Up @@ -676,15 +676,19 @@ above. JavaScript applications must update removed keys too; removed callback
names are not invoked at runtime. Keep hook denials exception-based while
renaming them.

### 8. Replace the retired provider-specific auth scaffold
### 8. Replace the v2 provider-specific auth bridge

The v3 CLI no longer offers `better-auth-ui`, installs
`@btst/better-auth-ui` or Better Auth packages, or generates auth, account,
and organization routes. BTST authorization is provider-agnostic: keep your
authentication provider and UI in application code, then adapt its session
through the generic client and server identity resolvers.
The v3 CLI no longer generates the old Better Auth-to-BTST authorization
provider. BTST authorization is provider-agnostic: adapt your application
session through the generic client and server identity resolvers.

Before:
The stable-v3 CLI does offer an optional `better-auth-ui` companion scaffold
for applications that already own a Better Auth server. That selection creates
only the Better Auth browser client plus auth and account UI routes; it does not
generate the server, database, schema, migrations, providers, secrets,
organization plugin, or a BTST identity bridge.

Remove the old bridge:

```bash
npx @btst/codegen init --plugins blog,better-auth-ui
Expand All @@ -698,7 +702,7 @@ import { createBetterAuthProvider } from "@btst/better-auth-ui"
</StackProvider>
```

After:
Keep authorization application-owned:

```ts title="authorization.client.ts"
export const clientAuth = createClientAuth({
Expand All @@ -717,9 +721,9 @@ export const serverAuth = createServerAuth({

Pass `clientAuth` to `StackProvider`, pass `serverAuth` to
`createBackendStack({ auth: serverAuth })`, and keep
sign-in, account, and organization routes in your chosen authentication
framework. Remove the retired plugin from existing `btst init` commands and
delete its generated imports, overrides, CSS import, and package dependencies.
authorization independent from the optional Better Auth UI routes. See
[Better Auth UI Companion](/plugins/better-auth-ui) for the supported scaffold
and exact dependency cohort.

### Migration checklist

Expand All @@ -735,7 +739,9 @@ delete its generated imports, overrides, CSS import, and package dependencies.
- Change backend hook denials from boolean returns to thrown errors.
- Replace every retired Form Builder, Kanban, and Media lifecycle spelling
using the RC3 mapping tables.
- Replace the provider-specific auth scaffold with application-owned identity resolvers and routes.
- Keep the Better Auth backend and identity resolvers application-owned. When
selected, use the optional companion scaffold for browser auth/account routes
and connect it to that existing backend.
- Run your framework build, TypeScript checks, and tests.

---
Expand Down
8 changes: 7 additions & 1 deletion docs/content/docs/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Common flags:
|------|-------------|
| `--framework` | `nextjs`, `react-router`, or `tanstack` |
| `--adapter` | `memory`, `prisma`, `drizzle`, `kysely`, or `mongodb` |
| `--plugins` | Comma-separated plugin keys: `blog`, `ai-chat`, `cms`, `form-builder`, `ui-builder`, `kanban`, `comments`, `media`, `route-docs`, `open-api` (or `all`) |
| `--plugins` | Comma-separated plugin keys: `blog`, `ai-chat`, `cms`, `form-builder`, `ui-builder`, `kanban`, `comments`, `media`, `route-docs`, `open-api`, `better-auth-ui` (or `all`) |
| `--cwd` | Target directory |
| `--skip-install` | Skip package installation step |
| `--yes` | Non-interactive defaults (useful in CI) |
Expand All @@ -55,6 +55,12 @@ Generated v3 layouts never repeat framework router, API, or identity wiring in
plugin overrides. Replace only the plugin-specific TODO values (for example an
upload function or user resolver).

`better-auth-ui` is an optional companion selection. It generates the auth and
account client plugins, a browser client for an existing `/api/auth` endpoint,
and the framework-native session refresh callback. It never generates a Better
Auth server, database schema, migrations, providers, secrets, or BTST identity
adapter. See [Better Auth UI Companion](/plugins/better-auth-ui).

## Generate and Migrate via Codegen

If you prefer one command surface, these delegate to `@btst/cli`:
Expand Down
1 change: 1 addition & 0 deletions docs/content/docs/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"plugins/media",
"plugins/open-api",
"plugins/route-docs",
"plugins/better-auth-ui",
"plugins/development",
"---[Database]Databases---",
"databases/adapters",
Expand Down
174 changes: 174 additions & 0 deletions docs/content/docs/plugins/better-auth-ui.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
title: Better Auth UI Companion
description: Add optional auth and account pages to an application that already runs Better Auth.
---

import { Callout } from "fumadocs-ui/components/callout";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";

[`@btst/better-auth-ui`](https://github.com/better-stack-ai/better-auth-ui)
is the separately maintained Better Auth UI companion for BTST v3. It adds
resolved auth and account routes while Better Auth UI continues to read its own
session and native permissions from your Better Auth client.

<Callout type="warn">
This integration assumes your application already owns a Better Auth server
endpoint. It does not generate a Better Auth backend, database adapter,
schema, migrations, authentication providers, secrets, or deployment
configuration.
</Callout>

## Generate the minimal integration

Select the companion explicitly; it is never part of the default scaffold.

```bash
npx @btst/codegen init --plugins better-auth-ui
```

The generated result:

- registers only `authClientPlugin()` and `accountClientPlugin()`;
- creates one browser client for the existing `/api/auth` endpoint;
- mounts routes under the resolved BTST site path (`/pages/auth/*` and
`/pages/account/*` by default);
- configures API, site, and QueryClient runtime only once in
`createClientStack()`; and
- refreshes the framework explicitly after a Better Auth session change.

Organization, API-key, passkey, multi-session, and other Better Auth extensions
are not enabled by the generated code. Add one only after the matching Better
Auth server and client plugin are configured in your application.

<Callout type="info">
RC4 publishes API-key and passkey as required declaration peers because its
synthetic full `AuthClient` type exposes their surfaces. The CLI therefore
installs their aligned 1.6.16 packages to keep strict dependency trees clean,
but it does not import, register, or enable either runtime feature. Activation
remains an explicit application choice and requires the matching Better Auth
server/client plugins.
</Callout>

## Supported release cohort

The corrected companion candidate is `@btst/better-auth-ui@2.0.0-rc.4`. Its
stable-v3 compatibility contract retains these exact versions:

| Package | Version |
| --- | --- |
| `better-auth`, `@better-auth/core` | `1.6.16` |
| `@better-auth/api-key`, `@better-auth/passkey` | `1.6.16` |
| `@better-auth/utils` | `0.4.1` |
| `@better-fetch/fetch` | `1.2.2` |
| `better-call` | `1.3.6` |
| `@btst/db` and BTST database adapters | `2.2.3` |

Do not combine this companion release with a Better Auth 1.7 dependency graph.
The CLI installs the corrected auth cohort without changing the retained
`@btst/db@2.2.3` or adapter versions.

For a manual installation, add the companion and exact auth cohort alongside
your existing BTST dependencies:

```bash
pnpm add @btst/better-auth-ui@2.0.0-rc.4 \
better-auth@1.6.16 @better-auth/core@1.6.16 \
@better-auth/api-key@1.6.16 @better-auth/passkey@1.6.16 \
@better-auth/utils@0.4.1 @better-fetch/fetch@1.2.2 better-call@1.3.6
```

The package declares its component-library peers. Resolve any peer warning
against the companion's published manifest. These optional data-adapter
subpaths add their own peers; do not install or import them unless you select
that integration:

| Optional subpath | Additional peers |
| --- | --- |
| `@btst/better-auth-ui/tanstack` | `@daveyplate/better-auth-tanstack@^1.3.6` |
| `@btst/better-auth-ui/instantdb` | `@instantdb/react@>=0.18.0` |
| `@btst/better-auth-ui/triplit` | `@triplit/client@>=1.0.0`, `@triplit/react@>=1.0.0` |

## Browser client and resolved routes

The CLI generates the following application-owned seam:

```ts title="lib/auth-client.ts"
import { createAuthClient } from "better-auth/react"

export function createAppAuthClient(baseURL?: string) {
return createAuthClient({
...(baseURL ? { baseURL } : {}),
basePath: "/api/auth",
})
}
```

Change `basePath` only when your existing Better Auth handler uses a different
path. The companion route bases are not configured here: they derive from the
site runtime passed once to `createClientStack()`.

```tsx title="lib/stack-client.tsx"
import { accountClientPlugin, authClientPlugin } from "@btst/better-auth-ui/client"
import { createClientStack } from "@btst/stack/client"

return createClientStack({
api: { baseURL: apiOrigin, basePath: "/api/data" },
site: { baseURL: siteOrigin, basePath: "/pages" },
queryClient,
plugins: {
auth: authClientPlugin(),
account: accountClientPlugin(),
},
})
```

## Provider overrides

The resolved stack infers both override keys. Configure the Better Auth client
once under `auth`; account-specific settings remain under `account`.

```tsx
<StackProvider
stack={browserStack}
router={frameworkRouter}
overrides={{
auth: {
authClient,
redirectTo: "/pages/account/settings",
onSessionChange: refreshThroughTheFramework,
},
account: {
account: true,
// Avatar customization belongs here:
// avatar: { upload, delete: deleteAvatar, size: 128 },
},
}}
>
{children}
</StackProvider>
```

Use the framework-native synchronization generated for your target:

<Tabs groupId="framework" items={["Next.js", "React Router", "TanStack Start"]}>
<Tab value="Next.js">
```ts
onSessionChange: () => router.refresh()
```
</Tab>
<Tab value="React Router">
```ts
onSessionChange: () => revalidator.revalidate()
```
</Tab>
<Tab value="TanStack Start">
```ts
onSessionChange: () => router.invalidate()
```
</Tab>
</Tabs>

The bridge performs no hidden BTST identity refetch. If business plugins use
BTST authorization, map the Better Auth session separately with BTST's generic
`createClientAuth` and `createServerAuth` contracts and keep server
authorization authoritative.
8 changes: 7 additions & 1 deletion docs/content/docs/plugins/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Available plugins and features for BTST
---

import { Card, Cards } from "fumadocs-ui/components/card";
import { BookOpen, Database, Hammer, Bot, FileText, FileCode, Route, Layout, Columns3, MessageSquare, ImageIcon } from "lucide-react";
import { BookOpen, Database, Hammer, Bot, FileText, FileCode, Route, Layout, Columns3, MessageSquare, ImageIcon, ShieldCheck } from "lucide-react";


BTST provides a collection of full-stack plugins that you can easily integrate into your React application. Each plugin includes routes, APIs, database schemas, components, and hooks—everything you need to add complete features to your app.
Expand Down Expand Up @@ -72,6 +72,12 @@ With more plugins coming soon, you can add complete features to your app in minu
icon={<Route size={20} />}
description="Auto-generated client route documentation with interactive navigation."
/>
<Card
title="Better Auth UI Companion"
href="/plugins/better-auth-ui"
icon={<ShieldCheck size={20} />}
description="Optional auth and account routes for applications that already run Better Auth."
/>
<Card
title="Building Plugins"
href="/plugins/development"
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"legacy-next-hashes:generate": "node scripts/generate-legacy-next-render-hashes.mjs",
"typecheck": "tsc --project tsconfig.json",
"test": "vitest run",
"test:init": "bash scripts/test-init.sh"
"test:init": "bash scripts/test-init.sh",
"test:better-auth-ui-fixtures": "node scripts/test-better-auth-ui-fixtures.mjs"
},
"dependencies": {
"@clack/prompts": "^0.11.0",
Expand Down
Loading
Loading