create-convex-monorepo 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -45
- package/assets/backend-better-auth/PROVENANCE.md +3 -0
- package/assets/backend-better-auth/convex/_generated/api.d.ts +57 -0
- package/assets/backend-better-auth/convex/_generated/api.js +23 -0
- package/assets/backend-better-auth/convex/_generated/dataModel.d.ts +60 -0
- package/assets/backend-better-auth/convex/_generated/server.d.ts +162 -0
- package/assets/backend-better-auth/convex/_generated/server.js +101 -0
- package/assets/backend-better-auth/convex/messages.ts +38 -0
- package/assets/backend-better-auth/convex/schema.ts +9 -0
- package/assets/backend-blank-better-auth/PROVENANCE.md +3 -0
- package/assets/backend-blank-better-auth/convex/_generated/api.d.ts +53 -0
- package/assets/backend-blank-better-auth/convex/_generated/api.js +23 -0
- package/assets/backend-blank-better-auth/convex/_generated/dataModel.d.ts +60 -0
- package/assets/backend-blank-better-auth/convex/_generated/server.d.ts +162 -0
- package/assets/backend-blank-better-auth/convex/_generated/server.js +101 -0
- package/assets/backend-blank-better-auth/convex/schema.ts +3 -0
- package/assets/backend-blank-convex-auth/PROVENANCE.md +3 -0
- package/assets/backend-blank-convex-auth/convex/_generated/api.d.ts +51 -0
- package/assets/backend-blank-convex-auth/convex/_generated/api.js +23 -0
- package/assets/backend-blank-convex-auth/convex/_generated/dataModel.d.ts +60 -0
- package/assets/backend-blank-convex-auth/convex/_generated/server.d.ts +162 -0
- package/assets/backend-blank-convex-auth/convex/_generated/server.js +101 -0
- package/assets/backend-blank-convex-auth/convex/schema.ts +4 -0
- package/assets/backend-convex-auth/PROVENANCE.md +3 -0
- package/assets/backend-convex-auth/convex/_generated/api.d.ts +55 -0
- package/assets/backend-convex-auth/convex/_generated/api.js +23 -0
- package/assets/backend-convex-auth/convex/_generated/dataModel.d.ts +60 -0
- package/assets/backend-convex-auth/convex/_generated/server.d.ts +162 -0
- package/assets/backend-convex-auth/convex/_generated/server.js +101 -0
- package/assets/backend-convex-auth/convex/messages.ts +38 -0
- package/assets/backend-convex-auth/convex/schema.ts +11 -0
- package/assets/setup/better-auth-env.mjs +187 -0
- package/assets/setup/convex-auth-keys.mjs +139 -0
- package/assets/setup/convex-auth-site.mjs +129 -0
- package/assets/setup/convex-setup.d.mts +9 -1
- package/assets/setup/convex-setup.mjs +64 -10
- package/dist/commands/create.d.ts +1 -1
- package/dist/commands/create.js +34 -7
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/entry.js +6 -0
- package/dist/commands/entry.js.map +1 -1
- package/dist/commands/workspace.d.ts +5 -3
- package/dist/commands/workspace.js +118 -38
- package/dist/commands/workspace.js.map +1 -1
- package/dist/generator/format.js +15 -1
- package/dist/generator/format.js.map +1 -1
- package/dist/generator/index.js +7 -5
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/options.d.ts +4 -1
- package/dist/generator/options.js +38 -5
- package/dist/generator/options.js.map +1 -1
- package/dist/generator/types.d.ts +8 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/auth/better-auth/controls.d.ts +1 -0
- package/dist/integrations/auth/better-auth/controls.js +67 -0
- package/dist/integrations/auth/better-auth/controls.js.map +1 -0
- package/dist/integrations/auth/better-auth/index.d.ts +2 -0
- package/dist/integrations/auth/better-auth/index.js +109 -0
- package/dist/integrations/auth/better-auth/index.js.map +1 -0
- package/dist/integrations/auth/better-auth/providers.d.ts +2 -0
- package/dist/integrations/auth/better-auth/providers.js +63 -0
- package/dist/integrations/auth/better-auth/providers.js.map +1 -0
- package/dist/integrations/auth/better-auth/setup.d.ts +2 -0
- package/dist/integrations/auth/better-auth/setup.js +37 -0
- package/dist/integrations/auth/better-auth/setup.js.map +1 -0
- package/dist/integrations/auth/clerk/index.js +15 -3
- package/dist/integrations/auth/clerk/index.js.map +1 -1
- package/dist/integrations/auth/convex-auth/controls.d.ts +2 -0
- package/dist/integrations/auth/convex-auth/controls.js +88 -0
- package/dist/integrations/auth/convex-auth/controls.js.map +1 -0
- package/dist/integrations/auth/convex-auth/index.d.ts +3 -0
- package/dist/integrations/auth/convex-auth/index.js +100 -0
- package/dist/integrations/auth/convex-auth/index.js.map +1 -0
- package/dist/integrations/auth/convex-auth/providers.d.ts +2 -0
- package/dist/integrations/auth/convex-auth/providers.js +36 -0
- package/dist/integrations/auth/convex-auth/providers.js.map +1 -0
- package/dist/integrations/auth/convex-auth/setup.d.ts +2 -0
- package/dist/integrations/auth/convex-auth/setup.js +76 -0
- package/dist/integrations/auth/convex-auth/setup.js.map +1 -0
- package/dist/integrations/auth/index.d.ts +2 -1
- package/dist/integrations/auth/index.js +22 -0
- package/dist/integrations/auth/index.js.map +1 -1
- package/dist/integrations/auth/none/index.js +16 -1
- package/dist/integrations/auth/none/index.js.map +1 -1
- package/dist/integrations/auth/shared.d.ts +7 -1
- package/dist/integrations/auth/shared.js +91 -6
- package/dist/integrations/auth/shared.js.map +1 -1
- package/dist/integrations/auth/workos/controls.d.ts +2 -0
- package/dist/integrations/auth/workos/controls.js +53 -0
- package/dist/integrations/auth/workos/controls.js.map +1 -0
- package/dist/integrations/auth/workos/index.d.ts +6 -0
- package/dist/integrations/auth/workos/index.js +104 -0
- package/dist/integrations/auth/workos/index.js.map +1 -0
- package/dist/integrations/auth/workos/providers.d.ts +3 -0
- package/dist/integrations/auth/workos/providers.js +53 -0
- package/dist/integrations/auth/workos/providers.js.map +1 -0
- package/dist/integrations/auth/workos/setup.d.ts +2 -0
- package/dist/integrations/auth/workos/setup.js +27 -0
- package/dist/integrations/auth/workos/setup.js.map +1 -0
- package/dist/package-manager/index.d.ts +7 -1
- package/dist/package-manager/index.js +20 -0
- package/dist/package-manager/index.js.map +1 -1
- package/dist/templates/apps/astro/index.d.ts +2 -0
- package/dist/templates/apps/astro/index.js +69 -0
- package/dist/templates/apps/astro/index.js.map +1 -0
- package/dist/templates/apps/index.js +8 -0
- package/dist/templates/apps/index.js.map +1 -1
- package/dist/templates/apps/nuxt/index.d.ts +2 -0
- package/dist/templates/apps/nuxt/index.js +123 -0
- package/dist/templates/apps/nuxt/index.js.map +1 -0
- package/dist/templates/apps/react-router/index.d.ts +2 -0
- package/dist/templates/apps/react-router/index.js +85 -0
- package/dist/templates/apps/react-router/index.js.map +1 -0
- package/dist/templates/apps/shared.d.ts +1 -1
- package/dist/templates/apps/shared.js +25 -5
- package/dist/templates/apps/shared.js.map +1 -1
- package/dist/templates/apps/sveltekit/index.d.ts +2 -0
- package/dist/templates/apps/sveltekit/index.js +155 -0
- package/dist/templates/apps/sveltekit/index.js.map +1 -0
- package/dist/templates/backend/index.js +4 -4
- package/dist/templates/backend/index.js.map +1 -1
- package/dist/templates/root/index.js +99 -42
- package/dist/templates/root/index.js.map +1 -1
- package/dist/templates/versions.d.ts +45 -0
- package/dist/templates/versions.js +45 -0
- package/dist/templates/versions.js.map +1 -1
- package/dist/workspace/add.d.ts +7 -2
- package/dist/workspace/add.js +741 -111
- package/dist/workspace/add.js.map +1 -1
- package/dist/workspace/doctor.js +326 -36
- package/dist/workspace/doctor.js.map +1 -1
- package/dist/workspace/env.js +1 -1
- package/dist/workspace/env.js.map +1 -1
- package/dist/workspace/planning.d.ts +11 -0
- package/dist/workspace/planning.js +70 -0
- package/dist/workspace/planning.js.map +1 -0
- package/dist/workspace/project.d.ts +6 -2
- package/dist/workspace/project.js +22 -5
- package/dist/workspace/project.js.map +1 -1
- package/dist/workspace/upgrade.d.ts +2 -0
- package/dist/workspace/upgrade.js +153 -0
- package/dist/workspace/upgrade.js.map +1 -1
- package/docs/adding-a-framework.md +30 -4
- package/docs/adding-an-auth-provider.md +23 -6
- package/docs/architecture.md +10 -5
- package/docs/research.md +148 -1
- package/docs/verification.md +174 -0
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# create-convex-monorepo
|
|
2
2
|
|
|
3
|
-
A TypeScript CLI that generates pnpm
|
|
3
|
+
A TypeScript CLI that generates pnpm or bun workspaces. Turborepo runs multiple frontends sharing one typed Convex backend. Choose Next.js, Vite + React, TanStack Start, React Router v7, Expo, Astro + React island, SvelteKit, Nuxt, or a combination. React apps support optional Clerk, Convex Auth, WorkOS AuthKit, or Better Auth authentication on their supported frameworks. SvelteKit and Nuxt support auth `none` only.
|
|
4
4
|
|
|
5
5
|
The generator composes framework templates and auth adapters. It does not copy a single starter and delete unwanted pieces. Choose blank apps or a messages example. The example includes a query and mutation, plus compile-time assertions for the shared API's argument and return types.
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ Convex already generates an API from your backend functions. Sharing that API be
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
Requires Node.js 22.12 or newer and pnpm for the generated workspace.
|
|
13
|
+
Requires Node.js 22.12 or newer and pnpm or bun for the generated workspace.
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
16
|
pnpm create convex-monorepo@latest
|
|
@@ -22,7 +22,7 @@ Or use npx:
|
|
|
22
22
|
npx create-convex-monorepo@latest
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Both commands run the same CLI. You can also install it globally with `npm install --global create-convex-monorepo` and run `create-convex-monorepo` directly. Running through npx does not change the generated workspace's package manager
|
|
25
|
+
Both commands run the same CLI. You can also install it globally with `npm install --global create-convex-monorepo` and run `create-convex-monorepo` directly. Running through npx does not change the generated workspace's package manager. The default is pnpm; select bun with `--package-manager bun` or the interactive prompt.
|
|
26
26
|
|
|
27
27
|
Contributors can run the checkout with `pnpm dev`; see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
28
28
|
|
|
@@ -34,7 +34,7 @@ Run the same CLI from the workspace root or any subdirectory. No global or proje
|
|
|
34
34
|
npx create-convex-monorepo@latest
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
With a terminal attached, it detects `convex-monorepo.json` and offers a menu to add an app, add
|
|
37
|
+
With a terminal attached, it detects `convex-monorepo.json` and offers a menu to add an app, add a shared package, add authentication, check the workspace, sync frontend URLs, update dependencies, or check for updates. Without a terminal, it prints management help without changing files.
|
|
38
38
|
|
|
39
39
|
You can also run each command directly:
|
|
40
40
|
|
|
@@ -42,11 +42,21 @@ You can also run each command directly:
|
|
|
42
42
|
npx create-convex-monorepo@latest add app admin --framework vite --example none --dry-run
|
|
43
43
|
npx create-convex-monorepo@latest add app admin --framework vite --example none --install
|
|
44
44
|
npx create-convex-monorepo@latest add app mobile --framework expo --no-install
|
|
45
|
+
npx create-convex-monorepo@latest add package shared --dry-run
|
|
46
|
+
npx create-convex-monorepo@latest add package shared --no-install
|
|
45
47
|
npx create-convex-monorepo@latest add auth clerk --dry-run
|
|
46
48
|
npx create-convex-monorepo@latest add auth clerk --install
|
|
49
|
+
npx create-convex-monorepo@latest add auth convex-auth --dry-run
|
|
50
|
+
npx create-convex-monorepo@latest add auth convex-auth --install
|
|
51
|
+
npx create-convex-monorepo@latest add auth better-auth --dry-run
|
|
52
|
+
npx create-convex-monorepo@latest add auth better-auth --install
|
|
53
|
+
npx create-convex-monorepo@latest add auth workos --dry-run
|
|
54
|
+
npx create-convex-monorepo@latest add auth workos --install
|
|
47
55
|
npx create-convex-monorepo@latest env sync --app mobile
|
|
48
56
|
npx create-convex-monorepo@latest doctor
|
|
49
57
|
npx create-convex-monorepo@latest upgrade --check
|
|
58
|
+
npx create-convex-monorepo@latest upgrade --dry-run
|
|
59
|
+
npx create-convex-monorepo@latest upgrade --install
|
|
50
60
|
```
|
|
51
61
|
|
|
52
62
|
The same commands work through pnpm:
|
|
@@ -64,27 +74,33 @@ To explicitly generate a new project, use `create <project-name>`. This also let
|
|
|
64
74
|
npx create-convex-monorepo@latest create doctor --apps vite --no-install --no-git
|
|
65
75
|
```
|
|
66
76
|
|
|
67
|
-
| Command | Behavior
|
|
68
|
-
| ----------------- |
|
|
69
|
-
| `add app` | Creates an app using the existing backend and auth, updates root scripts and metadata, and links the public backend URL when configured.
|
|
70
|
-
| `add
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
77
|
+
| Command | Behavior |
|
|
78
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `add app` | Creates an app using the existing backend and auth, updates root scripts and metadata, and links the public backend URL when configured. |
|
|
80
|
+
| `add package` | Creates a blank shared TypeScript package under `packages/<name>` and records it in metadata. |
|
|
81
|
+
| `add auth` | Adds Clerk, Convex Auth, WorkOS AuthKit, or Better Auth to generated app providers and the backend auth configuration. Customized files that need replacement cause a conflict. |
|
|
82
|
+
| `env sync` | Links only the public backend URL, using each framework's variable prefix. Supports `--app` and `--dry-run`. |
|
|
83
|
+
| `doctor` | Checks workspace configuration, installed dependencies, environment settings, and shared API types. Supports `--json`; errors exit with status 1. |
|
|
84
|
+
| `upgrade` | Updates existing exact dependency pins and the recorded package-manager version to the running CLI's tested baseline. Keeps newer pins and rejects non-exact customizations. |
|
|
85
|
+
| `upgrade --check` | Compares generator versions with npm's latest stable release and reports the running CLI's tested dependency baseline through `--json`. Makes no changes. |
|
|
74
86
|
|
|
75
|
-
The add commands support `--dry-run`, `--install`, `--no-install`, and `--yes`. Without prompts, provide the app name and framework
|
|
87
|
+
The `add app`, `add package`, `add auth`, and `upgrade` commands support `--dry-run`, `--install`, `--no-install`, and `--yes`. Without prompts, provide the app name and framework for `add app`, the package name for `add package`, or `clerk`, `convex-auth`, `workos`, or `better-auth` for `add auth`. Dependency installation defaults to off. `--yes` enables installation unless `--no-install` is set, and never overrides conflicts. A dry run shows file paths without printing environment values or installing dependencies.
|
|
76
88
|
|
|
77
|
-
Existing workspaces with metadata version 1, including projects created with 0.2.1, are supported. Preserve `convex-monorepo.json`; the CLI reads it rather than guessing which directories belong to your project. Per-app starter choices are recorded there when they differ from the original selection.
|
|
89
|
+
Existing pnpm workspaces with metadata version 1, including projects created with 0.2.1, are supported. Bun workspaces also use metadata version 1. Preserve `convex-monorepo.json`; the CLI reads it rather than guessing which directories belong to your project. Per-app starter choices are recorded there when they differ from the original selection. Shared packages added by the CLI are recorded in the optional `packages` list as `{ "name": "shared" }` entries.
|
|
78
90
|
|
|
79
91
|
### Changes and conflicts
|
|
80
92
|
|
|
81
|
-
Commands plan every file before applying changes. They reject unsafe paths, symlinks, existing app
|
|
93
|
+
Commands plan every file before applying changes. They reject unsafe paths, symlinks, existing app or package paths, conflicting scripts or dependencies, and customized auth files that would need replacement. App addition requires the generated `apps/*` and `packages/*` workspace layout and Turbo dev script. Adding a messages UI also requires the generated messages backend contract; use `--example none` with a customized backend. Adding SvelteKit also updates an unchanged older URL setup script and adds formatter ignores for its generated output; customized setup scripts cause a conflict. Adding Astro or Nuxt to an older workspace also updates its recognized setup helper, adds the framework's public environment prefix to Turbo settings, and ignores its generated output. Astro adds `PUBLIC_*` and `.astro/`; Nuxt adds `NUXT_PUBLIC_*`, `.nuxt/`, and `.output/`. A customized setup helper that cannot be upgraded causes a conflict before writes. Restore the generated helper, add the app, then reapply custom changes.
|
|
82
94
|
|
|
83
|
-
|
|
95
|
+
Package addition creates plain TypeScript source with shared lint and typecheck settings. Add `"@<scope>/<name>": "workspace:*"` to each consuming app's dependencies, then run `pnpm install`. Next configs are updated when they match the generated config apart from the `transpilePackages` string list, so repeated `add package` calls keep appending. A missing config or any other customization produces a note with the required manual edit. Other frameworks need no config change.
|
|
96
|
+
|
|
97
|
+
Auth addition supports `none` to Clerk, Convex Auth, WorkOS AuthKit, or Better Auth. It preserves user functions, generated internals, unrelated package fields, and existing README content. Convex Auth adds `authTables` to a generated schema or a customized schema with a single `defineSchema` call taking an object literal. Other schema shapes need the two manual edits named in the conflict. A customized HTTP router needs a manual `auth.addHttpRoutes(http)` call. Follow the new `CLERK_SETUP.md`, `CONVEX_AUTH_SETUP.md`, `WORKOS_SETUP.md`, or `BETTER_AUTH_SETUP.md` for setup. For Convex Auth, run `pnpm install`, then `pnpm convex:auth-keys`; refresh generated types with `pnpm convex:dev` or `convex codegen`. Existing public messages do not acquire an owner automatically and will not appear in authenticated accounts. Review stored-data migration separately. Adding the configured provider again is a no-op; replacing an auth provider is not supported.
|
|
84
98
|
|
|
85
99
|
A workspace lock prevents two CLI edits from running together. Each planned file is checked again before writing. Failed edits roll back files that still contain this command's output; observed concurrent edits are preserved and reported. Filesystem checks are optimistic, so avoid editing affected files while a command is applying. A failed dependency installation leaves the applied files available for retry with `pnpm install`.
|
|
86
100
|
|
|
87
|
-
Doctor is read-only and uses an in-memory TypeScript probe. It does not run application scripts, start services, configure a deployment, validate a real Clerk session, or prove a native Expo build works. Missing installation or environment configuration is reported with suggested steps.
|
|
101
|
+
Doctor is read-only and uses an in-memory TypeScript probe. It does not run application scripts, start services, configure a deployment, validate a real Clerk session, or prove a native Expo build works. Missing installation or environment configuration is reported with suggested steps.
|
|
102
|
+
|
|
103
|
+
Upgrade updates matching dependency entries in root, app, and shared-package manifests and records the running CLI version in metadata. It never downgrades exact pins. Non-exact managed pins, such as `^` ranges, cause a conflict before any writes. User-added dependencies and unrelated package fields are preserved; missing tested dependencies are reported but not added. Manifests are rewritten from parsed JSON, so comments are not supported and integer values above 2^53 lose precision. Upgrade does not migrate template files or write the lockfile itself. Run `pnpm install` afterward, or use `--install`, to update the lockfile.
|
|
88
104
|
|
|
89
105
|
## Interactive usage
|
|
90
106
|
|
|
@@ -92,14 +108,15 @@ With a terminal attached, the CLI asks for missing choices:
|
|
|
92
108
|
|
|
93
109
|
```text
|
|
94
110
|
Project name? my-app
|
|
95
|
-
Package manager? pnpm
|
|
111
|
+
Package manager? pnpm / bun (default: pnpm)
|
|
96
112
|
Application framework? Next.js
|
|
97
113
|
Application name? web
|
|
98
114
|
Add another frontend? Yes
|
|
99
115
|
Application framework? Expo / React Native
|
|
100
116
|
Application name? mobile
|
|
101
117
|
Add another frontend? No
|
|
102
|
-
Authentication?
|
|
118
|
+
Authentication? Convex Auth (email + password)
|
|
119
|
+
OAuth providers? None
|
|
103
120
|
Starter content? Blank project
|
|
104
121
|
Initialize git? Yes
|
|
105
122
|
Initialize Convex and link frontend URLs? Yes
|
|
@@ -116,20 +133,43 @@ pnpm create convex-monorepo@latest my-app --apps web:next,admin:vite --no-instal
|
|
|
116
133
|
pnpm create convex-monorepo@latest my-app --apps app:tanstack-start,dashboard:next --auth none --package-manager pnpm --yes
|
|
117
134
|
```
|
|
118
135
|
|
|
119
|
-
| Option | Meaning
|
|
120
|
-
| ----------------------------------- |
|
|
121
|
-
| `--apps` | Comma-separated framework IDs or `name:framework` entries
|
|
122
|
-
| `--auth` | `none`, the default, or `
|
|
123
|
-
| `--
|
|
124
|
-
| `--
|
|
125
|
-
| `--
|
|
126
|
-
| `--
|
|
127
|
-
| `--
|
|
128
|
-
| `--
|
|
129
|
-
| `--
|
|
136
|
+
| Option | Meaning |
|
|
137
|
+
| ----------------------------------- | ----------------------------------------------------------------------- |
|
|
138
|
+
| `--apps` | Comma-separated framework IDs or `name:framework` entries |
|
|
139
|
+
| `--auth` | `none`, the default, `clerk`, `convex-auth`, `workos`, or `better-auth` |
|
|
140
|
+
| `--oauth` | Optional comma list `github,google`; requires `--auth convex-auth` |
|
|
141
|
+
| `--example` | `messages`, the default, or `none` for blank projects |
|
|
142
|
+
| `--package-manager` | `pnpm`, the default, or `bun`; npm and yarn are rejected |
|
|
143
|
+
| `--install`, `--no-install` | Enable or skip dependency installation |
|
|
144
|
+
| `--init-convex`, `--no-init-convex` | Initialize Convex and link URLs; enables installation |
|
|
145
|
+
| `--git`, `--no-git` | Enable or skip `git init`; no commit is created |
|
|
146
|
+
| `--yes`, `-y` | Skip prompts and accept defaults, including install and git |
|
|
147
|
+
| `--help`, `--version` | Show usage or the generator version |
|
|
130
148
|
|
|
131
149
|
Without a terminal, prompts are disabled and install/git default to off unless explicitly enabled or `--yes` is passed. Explicit negative flags override `--yes`. Convex initialization defaults to off when prompts are skipped, including with `--yes`; request it explicitly with `--init-convex`. That flag still lets Convex prompt for an account or deployment, and conflicts with `--no-install`. The default app is Next.js. Project and app names must be lowercase letters, digits, and hyphens, at most 100 characters, with no path separators or reserved device names.
|
|
132
150
|
|
|
151
|
+
## Bun workspaces
|
|
152
|
+
|
|
153
|
+
Select bun in the "Package manager?" prompt or pass the flag:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
npx create-convex-monorepo@latest my-app --apps next,expo --package-manager bun --install --no-git
|
|
157
|
+
cd my-app
|
|
158
|
+
bun run convex:setup
|
|
159
|
+
bun run dev
|
|
160
|
+
bun run typecheck
|
|
161
|
+
bun run lint
|
|
162
|
+
bun run build
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If installation was skipped, run `bun install` first. Use `bun run convex:link`, `bun run convex:dev`, for Convex Auth, `bun run convex:auth-keys`, and for Better Auth, `bun run convex:better-auth-env`. The pnpm script examples in this README use `bun run <script>` in bun workspaces. Run backend binaries from the root with `bun run --cwd packages/backend convex <command>`.
|
|
166
|
+
|
|
167
|
+
Bun workspaces put `apps/*` and `packages/*` in the root manifest's `workspaces` list and pin bun in `packageManager`. They keep Turborepo and `workspace:*` dependencies. Commit `bun.lock`; no `pnpm-workspace.yaml` is generated. Existing-workspace commands read the recorded manager, including when invoked through npx or pnpm. `--install` uses that manager, and upgrade updates its version pin. This does not migrate existing pnpm workspaces.
|
|
168
|
+
|
|
169
|
+
Keep Node.js 22.12+ installed for the CLI and framework tools. Bun's dependency lifecycle policy differs from pnpm's; the template trusts only esbuild, sharp, and unrs-resolver, matching the pnpm template's build allowlist. Review scripts before trusting additional dependencies. Expo keeps its default Metro configuration; JavaScript export does not verify native Xcode or Gradle builds. See [bun and Expo findings](docs/research.md#bun-workspaces).
|
|
170
|
+
|
|
171
|
+
Metadata stays at version 1. Older CLI releases that validate the manager as pnpm-only reject bun workspaces; use a CLI release with bun support to manage them.
|
|
172
|
+
|
|
133
173
|
## Blank projects
|
|
134
174
|
|
|
135
175
|
Choose **Blank project** in the starter-content prompt, or pass `--example none`:
|
|
@@ -138,22 +178,34 @@ Choose **Blank project** in the starter-content prompt, or pass `--example none`
|
|
|
138
178
|
pnpm create convex-monorepo@latest my-app --apps next,expo --example none --yes
|
|
139
179
|
```
|
|
140
180
|
|
|
141
|
-
Every selected app starts with a minimal page or screen showing its name. Convex providers, workspace dependencies, environment setup, and the selected auth integration remain configured. The backend has an empty schema and
|
|
181
|
+
Every selected app starts with a minimal page or screen showing its name. Convex providers, workspace dependencies, environment setup, and the selected auth integration remain configured. The backend has official generated types and an empty schema, except Convex Auth projects retain their auth tables and functions. Better Auth keeps its tables in the component and exposes the current-user query. There are no example tables, messages functions, access helpers, query/mutation screens, or demo-specific type-test files to remove.
|
|
142
182
|
|
|
143
|
-
Add your tables to `packages/backend/convex/schema.ts` and your functions beside it. Run `pnpm convex:dev` to generate their shared API references. With
|
|
183
|
+
Add your tables to `packages/backend/convex/schema.ts` and your functions beside it. Run `pnpm convex:dev` to generate their shared API references. With any auth provider, add server-side identity and authorization checks to your protected functions. The blank starter retains sign-in controls and the existing authenticated provider behavior.
|
|
144
184
|
|
|
145
185
|
The choice applies to the whole workspace. `--example messages` keeps the existing query/mutation demo and remains the default, including with `--yes`.
|
|
146
186
|
|
|
147
187
|
## Supported frameworks
|
|
148
188
|
|
|
149
|
-
| ID | Application
|
|
150
|
-
| ---------------- |
|
|
151
|
-
| `next` | Next.js App Router
|
|
152
|
-
| `vite` | Vite + React
|
|
153
|
-
| `tanstack-start` | TanStack Start with Vite
|
|
154
|
-
| `
|
|
189
|
+
| ID | Application | Public Convex variable | Convex data loading |
|
|
190
|
+
| ---------------- | ------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------ |
|
|
191
|
+
| `next` | Next.js App Router | `NEXT_PUBLIC_CONVEX_URL` | Client React hooks |
|
|
192
|
+
| `vite` | Vite + React | `VITE_CONVEX_URL` | Client React hooks |
|
|
193
|
+
| `tanstack-start` | TanStack Start with Vite | `VITE_CONVEX_URL` | Client React hooks, no server prefetch |
|
|
194
|
+
| `react-router` | React Router v7 framework mode, SSR enabled | `VITE_CONVEX_URL` | Client React hooks, no server prefetch or data loaders |
|
|
195
|
+
| `expo` | Expo / React Native | `EXPO_PUBLIC_CONVEX_URL` | Client React hooks |
|
|
196
|
+
| `astro` | Astro + React island | `PUBLIC_CONVEX_URL` | Client React hooks in a client-only island |
|
|
197
|
+
| `sveltekit` | SvelteKit with Svelte 5 | `PUBLIC_CONVEX_URL` | Client Svelte queries, no server preloading |
|
|
198
|
+
| `nuxt` | Nuxt, auth `none` only; Node `^22.19.0 \|\| ^24.11.0 \|\| >=26.0.0` | `NUXT_PUBLIC_CONVEX_URL` | Client Vue composables inside `ClientOnly` |
|
|
199
|
+
|
|
200
|
+
Nuxt uses Vue and supports only `--auth none`, including workspaces that mix Nuxt, SvelteKit, and React apps. Adding Nuxt to an authenticated workspace or adding auth to a workspace containing Nuxt is rejected before files change.
|
|
201
|
+
|
|
202
|
+
Nuxt keeps SSR enabled, but its Convex plugin and messages component run only in the browser. `NUXT_PUBLIC_CONVEX_URL` maps to `runtimeConfig.public.convexUrl`. Dev, build, and preview read `.env.local`; production servers accept the variable at runtime. Typechecking runs `nuxt prepare`, then `vue-tsc --noEmit` against both `.nuxt/tsconfig.json` and `.nuxt/tsconfig.server.json` to check app and server code. Lint uses `eslint-plugin-vue` with the shared TypeScript rules.
|
|
203
|
+
|
|
204
|
+
SvelteKit currently supports only `--auth none`, for both starters. It can share a workspace with any of the React frameworks when auth is `none`. Adding SvelteKit to an authenticated workspace or adding auth to a workspace containing SvelteKit fails before files are written.
|
|
205
|
+
|
|
206
|
+
Astro generates a static page with a React island mounted through `client:only="react"`. Convex and auth run in the browser. Its `typecheck` script uses `astro check`; Clerk uses the official `@clerk/astro` integration and middleware. No SSR adapter is needed for the static page.
|
|
155
207
|
|
|
156
|
-
Versions are pinned in the templates.
|
|
208
|
+
Versions are pinned in the templates. React Router follows the Vite framework scaffold with `app/root.tsx`, `app/routes.ts`, and `app/routes/home.tsx`. Its typecheck script generates route types before running TypeScript. Its root loader handles auth only; Convex queries and mutations use the shared client components. Expo's build command exports JavaScript, not native application binaries. See [research and upstream caveats](docs/research.md).
|
|
157
209
|
|
|
158
210
|
## Generated architecture
|
|
159
211
|
|
|
@@ -173,7 +225,7 @@ my-app/
|
|
|
173
225
|
│ ├── typescript-config/
|
|
174
226
|
│ └── eslint-config/
|
|
175
227
|
├── convex-monorepo.json
|
|
176
|
-
├── pnpm-workspace.yaml
|
|
228
|
+
├── pnpm-workspace.yaml # pnpm only
|
|
177
229
|
├── turbo.json
|
|
178
230
|
└── package.json
|
|
179
231
|
```
|
|
@@ -212,7 +264,9 @@ pnpm lint
|
|
|
212
264
|
pnpm build
|
|
213
265
|
```
|
|
214
266
|
|
|
215
|
-
Complete setup in a normal terminal before starting Turbo. Stop a separately running backend watcher before `pnpm dev`, which starts its own.
|
|
267
|
+
Complete setup in a normal terminal before starting Turbo. Stop a separately running backend watcher before `pnpm dev` or `bun run dev`, which starts its own. SvelteKit reads `PUBLIC_CONVEX_URL` from `$env/static/public`, so set it before typechecking or building. Its root layout mounts the Svelte Convex provider; messages subscribe with `useQuery`.
|
|
268
|
+
|
|
269
|
+
Public environment values are embedded at build time; rebuild frontends when they change. Backend build checks types and does not deploy.
|
|
216
270
|
|
|
217
271
|
## Code formatting
|
|
218
272
|
|
|
@@ -223,7 +277,7 @@ pnpm format
|
|
|
223
277
|
pnpm format:check
|
|
224
278
|
```
|
|
225
279
|
|
|
226
|
-
Convex `_generated` files, TanStack's generated route tree, build output, lockfiles, and environment files are excluded. Adding an app formats its new files; it does not reformat existing application code. Auth migration accepts formatting differences in older starters while still rejecting customized code that would be replaced.
|
|
280
|
+
Svelte components use the pinned `prettier-plugin-svelte` formatter. Convex `_generated` files, TanStack's generated route tree, React Router's `.react-router` types, SvelteKit's generated files, build output, lockfiles, and environment files are excluded. Adding an app formats its new files; it does not reformat existing application code. Auth migration accepts formatting differences in older starters while still rejecting customized code that would be replaced.
|
|
227
281
|
|
|
228
282
|
## Convex backend sharing
|
|
229
283
|
|
|
@@ -238,7 +292,153 @@ Dynamic Convex declarations refer to backend source modules. Client TypeScript p
|
|
|
238
292
|
|
|
239
293
|
## Authentication
|
|
240
294
|
|
|
241
|
-
|
|
295
|
+
New projects accept `none`, `clerk`, `convex-auth`, or `better-auth` across the six React frameworks and both starters. SvelteKit and Nuxt support only `none`; the generator has no Svelte or Vue binding for Clerk, Convex Auth, WorkOS, or Better Auth. Existing no-auth workspaces without Nuxt or SvelteKit accept `add auth clerk`, `add auth convex-auth`, `add auth workos`, or `add auth better-auth`. All providers support `add app` for their supported frameworks. WorkOS AuthKit supports Next.js, Vite, and TanStack Start with both starters. Expo, Astro, React Router, SvelteKit, and Nuxt are rejected before writing files. Expo has no official React Native AuthKit SDK. The [official Astro SDK](https://github.com/workos/authkit-astro) requires a server adapter and on-demand rendering; this generator uses static Astro output.
|
|
296
|
+
React Router has an official SDK, but this generator has no binding for it yet.
|
|
297
|
+
|
|
298
|
+
`--auth convex-auth` and `add auth convex-auth` configure email and password sign-up/sign-in, sign-out, and per-user backend access. Web apps use the client ConvexAuthProvider; Expo persists tokens with expo-secure-store. No frontend public auth keys or password-flow redirect scheme are needed. Next.js, TanStack Start, and React Router do not configure server-side authentication or authenticated SSR. GitHub and Google OAuth are opt-in with `--oauth github,google`. Magic links, email verification, password reset, and MFA are outside this starter.
|
|
299
|
+
|
|
300
|
+
Run `pnpm convex:setup`, then `pnpm convex:auth-keys`. The key script generates an RSA 2048 key pair and sets `JWT_PRIVATE_KEY` and `JWKS` on the deployment through the installed Convex CLI. It never stores the key locally or prints either value. The initial push can finish before keys exist, but sign-in fails until they are configured. Run `pnpm convex:auth-keys --prod` to set a separate pair for production. `SITE_URL` is a deployment setting for redirects and is optional for this Password-only flow. The generated `.env.convex-auth.example` belongs to the backend package. See the [official manual setup](https://labs.convex.dev/auth/setup/manual).
|
|
301
|
+
|
|
302
|
+
### Optional GitHub and Google OAuth
|
|
303
|
+
|
|
304
|
+
Keep Password sign-in and add either or both providers:
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
pnpm create convex-monorepo@latest my-app --apps next,expo --auth convex-auth --oauth github,google
|
|
308
|
+
npx create-convex-monorepo@latest add auth convex-auth --oauth google --install
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
OAuth supports both package managers. The examples below use pnpm. For bun workspaces, use `bun install`, replace `pnpm <script>` with `bun run <script>`, and replace `pnpm --filter @my-app/backend exec convex` with `bun run --cwd packages/backend convex`. Generated setup instructions use the selected manager.
|
|
312
|
+
|
|
313
|
+
The interactive OAuth multiselect defaults to none. `--oauth` is valid only with Convex Auth; unknown providers fail before generation. Both starters and all six React frameworks support it, including the Astro React island. Nuxt and SvelteKit reject Convex Auth, including OAuth, before generation or workspace changes. Metadata version 1 records the selected providers in an optional `oauth` array. `add auth` accepts this flag only on a no-auth workspace. Adding OAuth to a workspace with authentication already configured requires the manual edits below.
|
|
314
|
+
|
|
315
|
+
For OAuth, `SITE_URL` is required on the Convex deployment. Generated OAuth workspaces include a helper that leaves signing keys unchanged:
|
|
316
|
+
|
|
317
|
+
```sh
|
|
318
|
+
pnpm convex:auth-site http://localhost:3000
|
|
319
|
+
pnpm convex:auth-site https://your-app.example --prod
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Set `AUTH_GITHUB_ID`, `AUTH_GITHUB_SECRET`, `AUTH_GOOGLE_ID`, and `AUTH_GOOGLE_SECRET` for the selected providers with `pnpm --filter @my-app/backend exec convex env set <name> <value>` or the Convex dashboard. These are deployment settings, never frontend public environment variables. The backend `.env.convex-auth.example` lists the selected settings.
|
|
323
|
+
|
|
324
|
+
Create the OAuth applications in GitHub's developer settings and Google's Cloud console. Register the callback for each selected provider:
|
|
325
|
+
|
|
326
|
+
| Provider | Callback URL |
|
|
327
|
+
| -------- | -------------------------------------------- |
|
|
328
|
+
| GitHub | `<CONVEX_SITE_URL>/api/auth/callback/github` |
|
|
329
|
+
| Google | `<CONVEX_SITE_URL>/api/auth/callback/google` |
|
|
330
|
+
|
|
331
|
+
`CONVEX_SITE_URL` is the deployment's HTTPS `.convex.site` URL. Use separate provider applications and credentials for development and production. Web buttons start `signIn('github')` or `signIn('google')`; successful sign-ins return to `SITE_URL`. Browser OAuth must start on the SITE_URL origin so the returning page can read its stored verifier. For additional web origins, change the web handler to `signIn(provider, { redirectTo: window.location.href })` and allow those origins in the backend redirect callback. Changing only the callback is insufficient.
|
|
332
|
+
|
|
333
|
+
Expo uses the scheme already defined in `app.json`, `ccm-<project>-<app>`, with return URL `ccm-<project>-<app>://auth`. Use `pnpm ios` or `pnpm android` in the app directory to create a development build. Expo Go cannot handle this custom scheme. The provider console uses the HTTPS Convex callback above, then Convex redirects to the app scheme. Register the scheme return URL in any native redirect allowlist required by the provider console. Do not replace the GitHub or Google web client's HTTPS callback with the app scheme.
|
|
334
|
+
|
|
335
|
+
The generated native handler uses `expo-linking` to create the return URL and `expo-web-browser` to open the URL returned by `signIn(provider, { redirectTo })`. It completes successful browser sessions with `signIn(provider, { code })`. The backend allows only the generated native return URLs and the configured web origin. Keep those URLs and the app scheme aligned if you rename an app. See [Convex Auth OAuth](https://labs.convex.dev/auth/config/oauth) and [Expo authentication](https://docs.expo.dev/guides/authentication/).
|
|
336
|
+
|
|
337
|
+
### Add OAuth to an existing Convex Auth workspace
|
|
338
|
+
|
|
339
|
+
This is a manual edit. In `packages/backend/convex/auth.ts`, retain Password and add the selected imports and array entries. These OAuth providers come from the existing pinned `@auth/core` dependency; `@convex-dev/auth@0.0.95` does not export GitHub or Google provider modules.
|
|
340
|
+
|
|
341
|
+
```ts
|
|
342
|
+
import { convexAuth } from '@convex-dev/auth/server';
|
|
343
|
+
import { Password } from '@convex-dev/auth/providers/Password';
|
|
344
|
+
import GitHub from '@auth/core/providers/github';
|
|
345
|
+
import Google from '@auth/core/providers/google';
|
|
346
|
+
|
|
347
|
+
export const { auth, signIn, signOut, store, isAuthenticated } = convexAuth({
|
|
348
|
+
providers: [Password, GitHub, Google],
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Remove the import and array entry for any provider you do not want. In each web app's `src/auth-controls.tsx`, add these buttons inside the signed-out form, beside the Password controls:
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
<button type="button" disabled={pending} onClick={() => {
|
|
356
|
+
void signIn('github').catch(() => setError('Could not sign in. Try again.'));
|
|
357
|
+
}}>Sign in with GitHub</button>
|
|
358
|
+
<button type="button" disabled={pending} onClick={() => {
|
|
359
|
+
void signIn('google').catch(() => setError('Could not sign in. Try again.'));
|
|
360
|
+
}}>Sign in with Google</button>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
For Expo, add exact dependencies `"expo-web-browser": "57.0.3"` and `"expo-linking": "57.0.10"` to the app's `package.json`, then run `pnpm install`. Confirm the `expo.scheme` value in `app.json`. Add these imports to `src/auth-controls.tsx`:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
import * as Linking from 'expo-linking';
|
|
367
|
+
import { openAuthSessionAsync } from 'expo-web-browser';
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Add this handler inside `AuthControls`, replacing `ccm-my-app-mobile` with the actual scheme:
|
|
371
|
+
|
|
372
|
+
```tsx
|
|
373
|
+
async function authenticateOAuth(provider: 'github' | 'google') {
|
|
374
|
+
if (pending) return;
|
|
375
|
+
setPending(true);
|
|
376
|
+
setError(null);
|
|
377
|
+
try {
|
|
378
|
+
const redirectTo = Linking.createURL('auth', {
|
|
379
|
+
scheme: 'ccm-my-app-mobile',
|
|
380
|
+
});
|
|
381
|
+
const { redirect } = await signIn(provider, { redirectTo });
|
|
382
|
+
if (!redirect) throw new Error('Missing sign-in URL.');
|
|
383
|
+
const result = await openAuthSessionAsync(redirect.toString(), redirectTo);
|
|
384
|
+
if (result.type === 'success') {
|
|
385
|
+
const code = new URL(result.url).searchParams.get('code');
|
|
386
|
+
if (!code) throw new Error('Missing sign-in code.');
|
|
387
|
+
await signIn(provider, { code });
|
|
388
|
+
}
|
|
389
|
+
} catch (cause) {
|
|
390
|
+
setError(cause instanceof Error ? cause.message : 'Could not sign in.');
|
|
391
|
+
} finally {
|
|
392
|
+
setPending(false);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
Add native buttons inside the signed-out `View`:
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
<Button title="Sign in with GitHub" disabled={pending} onPress={() => { void authenticateOAuth('github'); }} />
|
|
401
|
+
<Button title="Sign in with Google" disabled={pending} onPress={() => { void authenticateOAuth('google'); }} />
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
For a shared web and native backend, add this `callbacks` property beside `providers` in `convexAuth`. Replace the example native URL with the actual scheme, adding each native app's exact return URL to the array:
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
callbacks: {
|
|
408
|
+
async redirect({ redirectTo }) {
|
|
409
|
+
const siteUrl = process.env.SITE_URL;
|
|
410
|
+
if (!siteUrl) throw new Error('Set SITE_URL on the Convex deployment.');
|
|
411
|
+
if (['ccm-my-app-mobile://auth'].includes(redirectTo)) return redirectTo;
|
|
412
|
+
const target = new URL(redirectTo, siteUrl);
|
|
413
|
+
if (target.origin === new URL(siteUrl).origin && ['http:', 'https:'].includes(target.protocol)) {
|
|
414
|
+
return target.toString();
|
|
415
|
+
}
|
|
416
|
+
throw new Error('Invalid OAuth redirect destination.');
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
To enable OAuth from multiple web frontends, pass `{ redirectTo: window.location.href }` as the second argument to each web `signIn` call. Replace the callback's same-origin condition above with an explicit list of trusted origins, using your actual addresses:
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
const allowedOrigins = [new URL(siteUrl).origin, 'http://localhost:3001'];
|
|
425
|
+
if (
|
|
426
|
+
allowedOrigins.includes(target.origin) &&
|
|
427
|
+
['http:', 'https:'].includes(target.protocol)
|
|
428
|
+
) {
|
|
429
|
+
return target.toString();
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Use production origins in production. Do not allow arbitrary URLs supplied by the client.
|
|
434
|
+
|
|
435
|
+
Configure credentials and callbacks as above. Set `SITE_URL` with `pnpm --filter @my-app/backend exec convex env set SITE_URL http://localhost:3000`, or use the scheme return URL for a mobile-only workspace. Add `"oauth": ["github", "google"]` to `convex-monorepo.json`, omitting unselected providers. Add `# SITE_URL is required for OAuth` and the selected `AUTH_*` variable names to `packages/backend/.env.convex-auth.example`. Run `pnpm convex:dev` to push the auth configuration, then rebuild the frontends and native development client. The backend module set is unchanged, so no codegen asset edits are needed.
|
|
436
|
+
|
|
437
|
+
Convex Auth message owners are `users` table IDs returned by `getAuthUserId`. Clerk owners are `tokenIdentifier` values. WorkOS owners are `identity.subject` values from `ctx.auth.getUserIdentity()`. Switching providers changes these keys and needs a data migration; the CLI does not replace auth providers.
|
|
438
|
+
|
|
439
|
+
`--auth workos` and `add auth workos` configure hosted AuthKit sign-in, SDK token refresh, sign-out, and Convex identity validation. The blank starter keeps the providers and sign-in controls. Append each app's `.env.workos.example` to `.env.local` and follow the generated README's WorkOS setup section, or `WORKOS_SETUP.md` after adding auth. The client ID uses each framework's public prefix. Next.js and TanStack Start also need its unprefixed server SDK value, plus server-only `WORKOS_API_KEY` and `WORKOS_COOKIE_PASSWORD`. Vite receives no server secrets. See [WorkOS research and configuration constraints](docs/research.md#workos-authkit).
|
|
440
|
+
|
|
441
|
+
`--auth clerk` adds SDK-specific bindings, a Convex auth configuration, and provider wiring. The messages example also includes backend identity checks and an owner index that keeps messages private. With `--auth none`, that example is a public message board. Blank projects omit the messages example; Convex Auth retains its auth tables and functions. Add authorization checks when writing protected functions. UI visibility alone is not authorization.
|
|
242
442
|
|
|
243
443
|
Use one Clerk application across the frontends. Configure Clerk's Convex integration and a JWT template named `convex`. Set `CLERK_JWT_ISSUER_DOMAIN` on the Convex deployment:
|
|
244
444
|
|
|
@@ -248,7 +448,34 @@ pnpm --filter @my-app/backend exec convex env set CLERK_JWT_ISSUER_DOMAIN https:
|
|
|
248
448
|
|
|
249
449
|
On a fresh deployment, first run `pnpm convex:setup` to select it. If the push reports a missing issuer, set that value and rerun setup. Repeat the configuration for production.
|
|
250
450
|
|
|
251
|
-
Append the variables from each app's `.env.clerk.example` to its `.env.local`, alongside the Convex URL. Publishable keys belong in the appropriate public variables. Next.js and
|
|
451
|
+
Append the variables from each app's `.env.clerk.example` to its `.env.local`, alongside the Convex URL. Publishable keys belong in the appropriate public variables. Next.js, Start, and React Router use a server-only `CLERK_SECRET_KEY`; Vite and Expo must never receive that secret. React Router uses `@clerk/react-router`, `clerkMiddleware`, and `rootAuthLoader`, with `v8_middleware` enabled. Its provider receives the root loader's session data and connects Convex through `ConvexProviderWithClerk`. For production, set `VITE_CLERK_PUBLISHABLE_KEY` at build time and both Clerk keys in the server runtime environment; `react-router-serve` does not load `.env.local` automatically. See [Convex's Clerk guide](https://docs.convex.dev/auth/clerk) and [Clerk's React Router setup](https://clerk.com/docs/react-router/getting-started/quickstart).
|
|
452
|
+
|
|
453
|
+
## Better Auth setup
|
|
454
|
+
|
|
455
|
+
Astro uses Better Auth inside its React island with `PUBLIC_CONVEX_URL` and `PUBLIC_CONVEX_SITE_URL`. React Router uses client authentication. Both support messages and blank starters. `--oauth` is only supported with Convex Auth.
|
|
456
|
+
|
|
457
|
+
`--auth better-auth` uses the official `@convex-dev/better-auth` component for email and password sign-up, sign-in, and sign-out on Next.js, Vite, TanStack Start, React Router, Expo, and Astro. Both starters include loading and error states. Next.js, TanStack Start, and React Router use client authentication. Social providers, magic links, email verification, and authenticated SSR are not configured.
|
|
458
|
+
|
|
459
|
+
Both package managers are supported. The examples below use pnpm; for bun workspaces, replace `pnpm <script>` with `bun run <script>`. Generated setup instructions use the selected manager.
|
|
460
|
+
|
|
461
|
+
Run `pnpm convex:setup` to select a deployment. If its first push requests auth configuration, set the deployment variables below and rerun setup. From the generated workspace root, configure your primary web origin and any additional frontend origins or native schemes:
|
|
462
|
+
|
|
463
|
+
```sh
|
|
464
|
+
pnpm convex:better-auth-env --site-url http://localhost:3000 --trusted-origins http://localhost:3001,ccm-my-app-mobile://
|
|
465
|
+
pnpm convex:better-auth-env --site-url https://example.com --trusted-origins https://admin.example.com,ccm-my-app-mobile:// --prod
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Use the actual scheme from the Expo app's `app.json`. For Expo-only development, use its web origin for `SITE_URL` and include its native scheme in the trusted origins. Use a cloud deployment for physical devices and a development build for your custom scheme.
|
|
469
|
+
|
|
470
|
+
The script generates `BETTER_AUTH_SECRET` in memory and sets it, `SITE_URL`, and `BETTER_AUTH_TRUSTED_ORIGINS` through the installed Convex CLI. It does not store or print the secret. Run the production command separately for production. Re-running rotates the secret, which can invalidate existing sessions. Convex supplies the backend's `CONVEX_SITE_URL`.
|
|
471
|
+
|
|
472
|
+
Set the public HTTP endpoint in every app's `.env.local`: `NEXT_PUBLIC_CONVEX_SITE_URL` for Next.js, `VITE_CONVEX_SITE_URL` for Vite, TanStack Start, and React Router, `PUBLIC_CONVEX_SITE_URL` for Astro, and `EXPO_PUBLIC_CONVEX_SITE_URL` for Expo. Use your deployment's HTTP URL, normally ending in `.convex.site`. Keep the existing public `CONVEX_URL` setting, normally ending in `.convex.cloud`. `convex:link` and `env sync` copy only `CONVEX_URL`; enter the site URL yourself. Never put `BETTER_AUTH_SECRET` in frontend files.
|
|
473
|
+
|
|
474
|
+
Better Auth stores its tables inside the component. Message ownership uses the Better Auth user ID returned by `authComponent.getAuthUser(ctx)`. Blank projects keep an empty application schema and the auth query. Expo uses `@better-auth/expo` with SecureStore on native platforms and the cross-domain client on web.
|
|
475
|
+
|
|
476
|
+
`add auth better-auth` writes `BETTER_AUTH_SETUP.md` and preserves your schema and generated internals. A missing `convex/convex.config.ts` is created. An existing component config or HTTP router that needs integration produces a conflict with the exact manual edit. After installation and configuration, run `pnpm convex:dev` to refresh component types. Provider replacement and stored-data migration remain manual.
|
|
477
|
+
|
|
478
|
+
See the [official React guide](https://labs.convex.dev/better-auth/framework-guides/react), [Expo guide](https://labs.convex.dev/better-auth/framework-guides/expo), and [email/password documentation](https://www.better-auth.com/docs/authentication/email-password).
|
|
252
479
|
|
|
253
480
|
## Expo notes
|
|
254
481
|
|
|
@@ -262,7 +489,7 @@ Typechecking and Metro export checks do not establish that real OAuth, device pe
|
|
|
262
489
|
|
|
263
490
|
- **Destination already exists:** choose a new or empty directory. The CLI refuses non-empty directories and symlinks. Template failures remove staging output; install/git/Convex setup failures preserve the completed project and print a retry command.
|
|
264
491
|
- **Missing URL screen:** run `pnpm convex:setup`, or `pnpm convex:link` if the backend is already configured, then restart development.
|
|
265
|
-
- **Authentication never connects:** check the `convex` JWT template and deployment issuer
|
|
492
|
+
- **Authentication never connects:** for Better Auth, check deployment `BETTER_AUTH_SECRET`, `SITE_URL`, trusted origins, and each frontend's public `CONVEX_SITE_URL`. For Convex Auth, check deployment signing keys and the generated auth modules. For Clerk, check the `convex` JWT template and deployment issuer, and use the same Clerk application across frontends.
|
|
266
493
|
- **Missing API types:** keep both generated JavaScript and declarations, run the backend watcher, and verify matching Convex versions. Do not fix this by casting the API.
|
|
267
494
|
- **Missing Start route tree:** run that app's `routes:generate` script. Its typecheck script runs route generation automatically.
|
|
268
495
|
- **Metro resolution after dependency changes:** run `pnpm --filter @my-app/mobile exec expo start --clear`. Check SDK-compatible dependency versions before changing resolver settings.
|
|
@@ -275,7 +502,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md), [adding a framework](docs/adding-a-frame
|
|
|
275
502
|
|
|
276
503
|
## Roadmap
|
|
277
504
|
|
|
278
|
-
Next candidates are
|
|
505
|
+
Next candidates are Convex Auth installation in existing workspaces, reviewed upgrade migrations, and more package-manager adapters. `upgrade` updates dependency pins; template migrations remain manual.
|
|
279
506
|
|
|
280
507
|
MIT licensed. See [LICENSE](LICENSE).
|
|
281
508
|
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
Generated files under convex/\_generated were produced unchanged by convex@1.45.0 using CONVEX_AGENT_MODE=anonymous pnpm exec convex dev --once on 2026-09-18, after pnpm install in a temporary generated workspace. Dynamic JS/declaration output. Auth dependencies: @convex-dev/better-auth@0.12.5, better-auth@1.6.15 and @better-auth/expo@1.6.15. Input modules: convex.config.ts, schema.ts, auth.ts, http.ts, messages.ts, access.ts. auth.config.ts configures the issuer and is excluded from the generated function API. No internal codegen entry point was called. Run normal convex dev after changing backend modules.
|
|
2
|
+
|
|
3
|
+
Convex SDK source is Apache-2.0 licensed: https://github.com/get-convex/convex-js/blob/main/LICENSE.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Generated `api` utility.
|
|
4
|
+
*
|
|
5
|
+
* THIS CODE IS AUTOMATICALLY GENERATED.
|
|
6
|
+
*
|
|
7
|
+
* To regenerate, run `npx convex dev`.
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type * as access from "../access.js";
|
|
12
|
+
import type * as auth from "../auth.js";
|
|
13
|
+
import type * as http from "../http.js";
|
|
14
|
+
import type * as messages from "../messages.js";
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
ApiFromModules,
|
|
18
|
+
FilterApi,
|
|
19
|
+
FunctionReference,
|
|
20
|
+
} from "convex/server";
|
|
21
|
+
|
|
22
|
+
declare const fullApi: ApiFromModules<{
|
|
23
|
+
access: typeof access;
|
|
24
|
+
auth: typeof auth;
|
|
25
|
+
http: typeof http;
|
|
26
|
+
messages: typeof messages;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A utility for referencing Convex functions in your app's public API.
|
|
31
|
+
*
|
|
32
|
+
* Usage:
|
|
33
|
+
* ```js
|
|
34
|
+
* const myFunctionReference = api.myModule.myFunction;
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const api: FilterApi<
|
|
38
|
+
typeof fullApi,
|
|
39
|
+
FunctionReference<any, "public">
|
|
40
|
+
>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A utility for referencing Convex functions in your app's internal API.
|
|
44
|
+
*
|
|
45
|
+
* Usage:
|
|
46
|
+
* ```js
|
|
47
|
+
* const myFunctionReference = internal.myModule.myFunction;
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const internal: FilterApi<
|
|
51
|
+
typeof fullApi,
|
|
52
|
+
FunctionReference<any, "internal">
|
|
53
|
+
>;
|
|
54
|
+
|
|
55
|
+
export declare const components: {
|
|
56
|
+
betterAuth: import("@convex-dev/better-auth/_generated/component.js").ComponentApi<"betterAuth">;
|
|
57
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/**
|
|
3
|
+
* Generated `api` utility.
|
|
4
|
+
*
|
|
5
|
+
* THIS CODE IS AUTOMATICALLY GENERATED.
|
|
6
|
+
*
|
|
7
|
+
* To regenerate, run `npx convex dev`.
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A utility for referencing Convex functions in your app's API.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* ```js
|
|
18
|
+
* const myFunctionReference = api.myModule.myFunction;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const api = anyApi;
|
|
22
|
+
export const internal = anyApi;
|
|
23
|
+
export const components = componentsGeneric();
|