@tanstack/create 0.59.4 → 0.61.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/dist/create-app.js +7 -5
  3. package/dist/file-helpers.js +13 -1
  4. package/dist/frameworks/react/add-ons/ai/info.json +0 -5
  5. package/dist/frameworks/react/add-ons/ai/package.json +0 -1
  6. package/dist/frameworks/{solid/add-ons/better-auth/README.md → react/add-ons/better-auth/README.md.ejs} +2 -2
  7. package/dist/frameworks/react/add-ons/better-auth/assets/_dot_env.local.append.ejs +3 -0
  8. package/dist/frameworks/react/add-ons/better-auth/assets/src/integrations/better-auth/header-user.tsx +3 -1
  9. package/dist/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +3 -1
  10. package/dist/frameworks/react/add-ons/convex/README.md.ejs +4 -0
  11. package/dist/frameworks/react/add-ons/drizzle/assets/src/routes/demo/{drizzle.tsx → drizzle.tsx.ejs} +3 -3
  12. package/dist/frameworks/react/add-ons/neon/assets/_dot_env.example.append +2 -2
  13. package/dist/frameworks/react/add-ons/neon/assets/neon-vite-plugin.ts +1 -1
  14. package/dist/frameworks/react/add-ons/neon/assets/src/db.ts +2 -2
  15. package/dist/frameworks/react/add-ons/posthog/README.md +9 -0
  16. package/dist/frameworks/react/add-ons/posthog/assets/_dot_env.local.append +4 -0
  17. package/dist/frameworks/react/add-ons/posthog/assets/src/integrations/posthog/provider.tsx +20 -0
  18. package/dist/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +93 -0
  19. package/dist/frameworks/react/add-ons/posthog/files.json +5 -0
  20. package/dist/frameworks/react/add-ons/posthog/info.json +28 -0
  21. package/dist/frameworks/react/add-ons/posthog/package.json +6 -0
  22. package/dist/frameworks/react/add-ons/prisma/assets/src/routes/demo/{prisma.tsx → prisma.tsx.ejs} +3 -3
  23. package/dist/frameworks/react/add-ons/prisma/package.json.ejs +1 -1
  24. package/dist/frameworks/react/add-ons/sentry/package.json +1 -1
  25. package/dist/frameworks/react/add-ons/tanstack-query/info.json +1 -1
  26. package/dist/frameworks/react/hosts/nitro/info.json +1 -1
  27. package/dist/frameworks/react/hosts/railway/info.json +1 -1
  28. package/dist/frameworks/react/project/base/README.md.ejs +1 -1
  29. package/dist/frameworks/react/project/base/package.json +1 -1
  30. package/dist/frameworks/react/project/base/vite.config.ts.ejs +1 -1
  31. package/dist/frameworks/{react/add-ons/better-auth/README.md → solid/add-ons/better-auth/README.md.ejs} +2 -2
  32. package/dist/frameworks/solid/add-ons/better-auth/assets/_dot_env.local.append.ejs +3 -0
  33. package/dist/frameworks/solid/add-ons/better-auth/assets/src/integrations/better-auth/header-user.tsx +3 -1
  34. package/dist/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +3 -1
  35. package/dist/frameworks/solid/add-ons/convex/README.md.ejs +4 -0
  36. package/{src/frameworks/solid/add-ons/solid-ui/README.md → dist/frameworks/solid/add-ons/solid-ui/README.md.ejs} +1 -1
  37. package/dist/frameworks/solid/add-ons/solid-ui/info.json +1 -5
  38. package/dist/frameworks/solid/project/base/README.md.ejs +1 -1
  39. package/dist/frameworks.js +6 -0
  40. package/dist/package-manager.js +29 -0
  41. package/dist/template-file.js +8 -1
  42. package/dist/types/custom-add-ons/add-on.d.ts +2 -1
  43. package/dist/types/package-manager.d.ts +7 -0
  44. package/dist/types/types.d.ts +21 -15
  45. package/dist/types/utils.d.ts +2 -0
  46. package/dist/types.js +2 -0
  47. package/dist/utils.js +6 -0
  48. package/package.json +1 -1
  49. package/src/create-app.ts +9 -6
  50. package/src/file-helpers.ts +12 -1
  51. package/src/frameworks/react/add-ons/ai/info.json +0 -5
  52. package/src/frameworks/react/add-ons/ai/package.json +0 -1
  53. package/src/frameworks/react/add-ons/better-auth/{README.md → README.md.ejs} +2 -2
  54. package/src/frameworks/react/add-ons/better-auth/assets/_dot_env.local.append.ejs +3 -0
  55. package/src/frameworks/react/add-ons/better-auth/assets/src/integrations/better-auth/header-user.tsx +3 -1
  56. package/src/frameworks/react/add-ons/better-auth/assets/src/routes/demo/better-auth.tsx +3 -1
  57. package/src/frameworks/react/add-ons/convex/README.md.ejs +4 -0
  58. package/src/frameworks/react/add-ons/drizzle/assets/src/routes/demo/{drizzle.tsx → drizzle.tsx.ejs} +3 -3
  59. package/src/frameworks/react/add-ons/neon/assets/_dot_env.example.append +2 -2
  60. package/src/frameworks/react/add-ons/neon/assets/neon-vite-plugin.ts +1 -1
  61. package/src/frameworks/react/add-ons/neon/assets/src/db.ts +2 -2
  62. package/src/frameworks/react/add-ons/posthog/README.md +9 -0
  63. package/src/frameworks/react/add-ons/posthog/assets/_dot_env.local.append +4 -0
  64. package/src/frameworks/react/add-ons/posthog/assets/src/integrations/posthog/provider.tsx +20 -0
  65. package/src/frameworks/react/add-ons/posthog/assets/src/routes/demo/posthog.tsx +93 -0
  66. package/src/frameworks/react/add-ons/posthog/files.json +5 -0
  67. package/src/frameworks/react/add-ons/posthog/info.json +28 -0
  68. package/src/frameworks/react/add-ons/posthog/package.json +6 -0
  69. package/src/frameworks/react/add-ons/prisma/assets/src/routes/demo/{prisma.tsx → prisma.tsx.ejs} +3 -3
  70. package/src/frameworks/react/add-ons/prisma/package.json.ejs +1 -1
  71. package/src/frameworks/react/add-ons/sentry/package.json +1 -1
  72. package/src/frameworks/react/add-ons/tanstack-query/info.json +1 -1
  73. package/src/frameworks/react/hosts/nitro/info.json +1 -1
  74. package/src/frameworks/react/hosts/railway/info.json +1 -1
  75. package/src/frameworks/react/project/base/README.md.ejs +1 -1
  76. package/src/frameworks/react/project/base/package.json +1 -1
  77. package/src/frameworks/react/project/base/vite.config.ts.ejs +1 -1
  78. package/src/frameworks/solid/add-ons/better-auth/{README.md → README.md.ejs} +2 -2
  79. package/src/frameworks/solid/add-ons/better-auth/assets/_dot_env.local.append.ejs +3 -0
  80. package/src/frameworks/solid/add-ons/better-auth/assets/src/integrations/better-auth/header-user.tsx +3 -1
  81. package/src/frameworks/solid/add-ons/better-auth/assets/src/routes/demo.better-auth.tsx +3 -1
  82. package/src/frameworks/solid/add-ons/convex/README.md.ejs +4 -0
  83. package/{dist/frameworks/solid/add-ons/solid-ui/README.md → src/frameworks/solid/add-ons/solid-ui/README.md.ejs} +1 -1
  84. package/src/frameworks/solid/add-ons/solid-ui/info.json +1 -5
  85. package/src/frameworks/solid/project/base/README.md.ejs +1 -1
  86. package/src/frameworks.ts +8 -0
  87. package/src/package-manager.ts +37 -0
  88. package/src/template-file.ts +14 -0
  89. package/src/types.ts +2 -0
  90. package/src/utils.ts +8 -0
  91. package/tests/file-helper.test.ts +6 -0
  92. package/tests/package-manager.test.ts +159 -0
  93. package/tests/template-file.test.ts +13 -0
  94. package/dist/frameworks/react/add-ons/ai/assets/src/lib/ai-devtools.tsx +0 -3
  95. package/dist/frameworks/react/add-ons/better-auth/assets/_dot_env.local.append +0 -3
  96. package/dist/frameworks/react/add-ons/convex/README.md +0 -4
  97. package/dist/frameworks/solid/add-ons/better-auth/assets/_dot_env.local.append +0 -3
  98. package/dist/frameworks/solid/add-ons/convex/README.md +0 -4
  99. package/src/frameworks/react/add-ons/ai/assets/src/lib/ai-devtools.tsx +0 -3
  100. package/src/frameworks/react/add-ons/better-auth/assets/_dot_env.local.append +0 -3
  101. package/src/frameworks/react/add-ons/convex/README.md +0 -4
  102. package/src/frameworks/solid/add-ons/better-auth/assets/_dot_env.local.append +0 -3
  103. package/src/frameworks/solid/add-ons/convex/README.md +0 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,152 @@
1
1
  # @tanstack/create
2
2
 
3
+ ## 0.61.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add PostHog add-on ([#317](https://github.com/TanStack/cli/pull/317))
8
+
9
+ ## 0.60.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Pin the React Sentry add-on to `@sentry/tanstackstart-react@10.34.0` to avoid a Nitro production build failure introduced in newer Sentry versions. ([`ab740ed`](https://github.com/TanStack/cli/commit/ab740ed2c5510a3266065aa98c8afe3093ea0034))
14
+
15
+ ## 0.60.0
16
+
17
+ ### Minor Changes
18
+
19
+ - feat(mcp): add getAddOnDetails tool and expand add-on metadata
20
+
21
+ Add new MCP tool to retrieve detailed add-on information including
22
+ routes, package additions, files, and documentation. Also expand
23
+ listTanStackAddOns to include type, category, link, warning, and
24
+ exclusive fields.
25
+
26
+ - feat: case-insensitive add-on lookup with typo suggestions
27
+
28
+ - feat: force TanStack Start with Tailwind CSS always enabled
29
+
30
+ - Remove code-router mode and --router-only flag (TanStack Start only)
31
+ - Remove start add-on (baked into base templates)
32
+ - Remove module-federation add-on
33
+ - Force Tailwind CSS to always be enabled
34
+ - Remove --tailwind/--no-tailwind CLI flags
35
+ - Remove selectTailwind and selectTypescript prompts
36
+ - Remove forcedMode parameter (mode always file-router)
37
+ - Simplify template conditionals and hardcode typescript/tailwind values
38
+ - Update README.md.ejs with instructions for removing Tailwind
39
+ - Clean up dead code and unused functions
40
+ - Update all CLI wrappers to show deprecation warnings
41
+
42
+ ### Patch Changes
43
+
44
+ - fix(create): ignore transient vitest unconfig files in templates
45
+
46
+ Fixes #345
47
+
48
+ - fix(create): bump Tailwind deps for Vite 7 compatibility
49
+
50
+ Fixes #332
51
+
52
+ - ci: Version Packages (#346)
53
+
54
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
55
+ Co-authored-by: Tanner Linsley <tannerlinsley@gmail.com>
56
+
57
+ - ci: Version Packages (#339)
58
+
59
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
60
+
61
+ - ci: Version Packages (#311)
62
+
63
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
64
+
65
+ - ci: Version Packages (#313)
66
+
67
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
68
+ Co-authored-by: Tanner Linsley <tannerlinsley@gmail.com>
69
+
70
+ - ci: Version Packages (#327)
71
+
72
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
73
+
74
+ - ci: Version Packages (#312)
75
+
76
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
77
+
78
+ - ci: Version Packages (#349)
79
+
80
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
81
+
82
+ - fix: Update Paraglide JS url (#307)
83
+
84
+ Co-authored-by: Tanner Linsley <tannerlinsley@gmail.com>
85
+
86
+ - ci: Version Packages (#341)
87
+
88
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
89
+
90
+ - fix: normalize path separators in toCleanPath to fix missing tsconfig.json on Windows (#319)
91
+
92
+ - ci: Version Packages (#338)
93
+
94
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
95
+
96
+ - ci: Version Packages (#325)
97
+
98
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
99
+
100
+ - fix(create): allow better-sqlite3 builds in pnpm templates
101
+
102
+ Set pnpm.onlyBuiltDependencies for React Drizzle and Prisma SQLite templates so better-sqlite3 native bindings build correctly in generated apps.
103
+
104
+ Fixes #321
105
+
106
+ - fix(create): normalize add-to-app output paths on Windows
107
+
108
+ Normalize generated and deleted output file paths to project-relative keys before compare/write/delete, preventing duplicated path segments when Windows drive letters are missing.
109
+
110
+ Fixes #329
111
+
112
+ - chore: remove unused Provider function from tanstack-query template (#272)
113
+
114
+ - fix: resolve Windows path handling in relativePath causing incorrect Clerk imports (#324)
115
+
116
+ - ci: Version Packages (#335)
117
+
118
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
119
+
120
+ - ci: Version Packages (#347)
121
+
122
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
123
+
124
+ - ci: Version Packages (#334)
125
+
126
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
127
+
128
+ - ci: Version Packages (#336)
129
+
130
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
131
+
132
+ - fix(create): normalize generated src js/jsx extensions for TypeScript
133
+
134
+ - ci: Version Packages (#326)
135
+
136
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
137
+
138
+ - fix(neon): use named import for postgresPlugin (#320)
139
+
140
+ The @neondatabase/vite-plugin-postgres package exports postgresPlugin as a
141
+ named export, not a default export. This fixes the SyntaxError when running
142
+ pnpm dev on projects created with the Neon add-on.
143
+
144
+ Fixes #318
145
+
146
+ - ci: Version Packages (#337)
147
+
148
+ Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
149
+
3
150
  ## 0.59.4
4
151
 
5
152
  ### Patch Changes
@@ -2,7 +2,7 @@ import { basename, resolve } from 'node:path';
2
2
  import { isBase64 } from './file-helpers.js';
3
3
  import { formatCommand } from './utils.js';
4
4
  import { writeConfigFileToEnvironment } from './config-file.js';
5
- import { getPackageManagerScriptCommand, packageManagerInstall, } from './package-manager.js';
5
+ import { getPackageManagerScriptCommand, packageManagerInstall, translateExecuteCommand, } from './package-manager.js';
6
6
  import { createPackageJSON } from './package-json.js';
7
7
  import { createTemplateFile } from './template-file.js';
8
8
  import { installShadcnComponents } from './integrations/shadcn.js';
@@ -134,16 +134,17 @@ async function runCommandsAndInstallDependencies(environment, options) {
134
134
  for (const phase of ['setup', 'add-on', 'example']) {
135
135
  for (const addOn of options.chosenAddOns.filter((addOn) => addOn.phase === phase && addOn.command && addOn.command.command)) {
136
136
  s.start(`Running commands for ${addOn.name}...`);
137
- const cmd = formatCommand({
137
+ const translated = translateExecuteCommand(options.packageManager, {
138
138
  command: addOn.command.command,
139
139
  args: addOn.command.args || [],
140
140
  });
141
+ const cmd = formatCommand(translated);
141
142
  environment.startStep({
142
143
  id: 'run-commands',
143
144
  type: 'command',
144
145
  message: cmd,
145
146
  });
146
- await environment.execute(addOn.command.command, addOn.command.args || [], options.targetDir, { inherit: true });
147
+ await environment.execute(translated.command, translated.args, options.targetDir, { inherit: true });
147
148
  environment.finishStep('run-commands', 'Setup commands complete');
148
149
  s.stop(`${addOn.name} commands complete`);
149
150
  }
@@ -153,16 +154,17 @@ async function runCommandsAndInstallDependencies(environment, options) {
153
154
  options.starter.command &&
154
155
  options.starter.command.command) {
155
156
  s.start(`Setting up starter ${options.starter.name}...`);
156
- const cmd = formatCommand({
157
+ const starterTranslated = translateExecuteCommand(options.packageManager, {
157
158
  command: options.starter.command.command,
158
159
  args: options.starter.command.args || [],
159
160
  });
161
+ const cmd = formatCommand(starterTranslated);
160
162
  environment.startStep({
161
163
  id: 'run-starter-command',
162
164
  type: 'command',
163
165
  message: cmd,
164
166
  });
165
- await environment.execute(options.starter.command.command, options.starter.command.args || [], options.targetDir, { inherit: true });
167
+ await environment.execute(starterTranslated.command, starterTranslated.args, options.targetDir, { inherit: true });
166
168
  environment.finishStep('run-starter-command', 'Starter command complete');
167
169
  s.stop(`${options.starter.name} commands complete`);
168
170
  }
@@ -3,6 +3,7 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
3
3
  import { basename, extname, resolve } from 'node:path';
4
4
  import parseGitignore from 'parse-gitignore';
5
5
  import ignore from 'ignore';
6
+ import { hasDrive, stripDrive } from './utils';
6
7
  const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico'];
7
8
  export function readFileHelper(path) {
8
9
  if (isBinaryFile(path)) {
@@ -35,7 +36,18 @@ export function toCleanPath(absolutePath, baseDir) {
35
36
  // Normalize both paths to use forward slashes for consistent comparison
36
37
  const normalizedPath = absolutePath.replace(/\\/g, '/');
37
38
  const normalizedBase = baseDir.replace(/\\/g, '/');
38
- let cleanPath = normalizedPath.replace(normalizedBase, '');
39
+ let cleanPath = normalizedPath;
40
+ if (normalizedPath.startsWith(normalizedBase)) {
41
+ cleanPath = normalizedPath.slice(normalizedBase.length);
42
+ }
43
+ else if (hasDrive(normalizedPath) !== hasDrive(normalizedBase)) {
44
+ // Handle paths that are missing the Windows drive letter (e.g. memfs on Windows)
45
+ const pathNoDrive = stripDrive(normalizedPath);
46
+ const baseNoDrive = stripDrive(normalizedBase);
47
+ if (pathNoDrive.startsWith(baseNoDrive)) {
48
+ cleanPath = pathNoDrive.slice(baseNoDrive.length);
49
+ }
50
+ }
39
51
  // Handle leading path separator
40
52
  if (cleanPath.startsWith('/')) {
41
53
  cleanPath = cleanPath.slice(1);
@@ -36,11 +36,6 @@
36
36
  "type": "header-user",
37
37
  "path": "src/components/demo-AIAssistant.tsx",
38
38
  "jsName": "TanChatAIAssistant"
39
- },
40
- {
41
- "type": "devtools",
42
- "path": "src/lib/ai-devtools.tsx",
43
- "jsName": "AiDevtools"
44
39
  }
45
40
  ],
46
41
  "dependsOn": ["store"],
@@ -7,7 +7,6 @@
7
7
  "@tanstack/ai-ollama": "latest",
8
8
  "@tanstack/ai-openai": "latest",
9
9
  "@tanstack/ai-react": "latest",
10
- "@tanstack/react-ai-devtools": "latest",
11
10
  "highlight.js": "^11.11.1",
12
11
  "streamdown": "^1.6.5",
13
12
  "lucide-react": "^0.544.0",
@@ -3,7 +3,7 @@
3
3
  1. Generate and set the `BETTER_AUTH_SECRET` environment variable in your `.env.local`:
4
4
 
5
5
  ```bash
6
- npx @better-auth/cli secret
6
+ <%- getPackageManagerExecuteScript('@better-auth/cli', ['secret']) %>
7
7
  ```
8
8
 
9
9
  2. Visit the [Better Auth documentation](https://www.better-auth.com) to unlock the full potential of authentication in your app.
@@ -28,5 +28,5 @@ export const auth = betterAuth({
28
28
  Then run migrations:
29
29
 
30
30
  ```bash
31
- npx @better-auth/cli migrate
31
+ <%- getPackageManagerExecuteScript('@better-auth/cli', ['migrate']) %>
32
32
  ```
@@ -0,0 +1,3 @@
1
+ # Better Auth configuration
2
+ BETTER_AUTH_URL=http://localhost:3000
3
+ BETTER_AUTH_SECRET= # Generate a secret key: `<%- getPackageManagerExecuteScript('@better-auth/cli', ['secret']) %>`
@@ -23,7 +23,9 @@ export default function BetterAuthHeader() {
23
23
  </div>
24
24
  )}
25
25
  <button
26
- onClick={() => authClient.signOut()}
26
+ onClick={() => {
27
+ void authClient.signOut()
28
+ }}
27
29
  className="flex-1 h-9 px-4 text-sm font-medium bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-50 border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors"
28
30
  >
29
31
  Sign out
@@ -57,7 +57,9 @@ function BetterAuthDemo() {
57
57
  </div>
58
58
 
59
59
  <button
60
- onClick={() => authClient.signOut()}
60
+ onClick={() => {
61
+ void authClient.signOut()
62
+ }}
61
63
  className="w-full h-9 px-4 text-sm font-medium border border-neutral-300 dark:border-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
62
64
  >
63
65
  Sign out
@@ -0,0 +1,4 @@
1
+ ## Setting up Convex
2
+
3
+ - Set the `VITE_CONVEX_URL` and `CONVEX_DEPLOYMENT` environment variables in your `.env.local`. (Or run `<%- getPackageManagerExecuteScript('convex', ['init']) %>` to set them automatically.)
4
+ - Run `<%- getPackageManagerExecuteScript('convex', ['dev']) %>` to start the Convex server.
@@ -163,19 +163,19 @@ function DemoDrizzle() {
163
163
  <li>
164
164
  Run:{' '}
165
165
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
166
- npx drizzle-kit generate
166
+ <%- getPackageManagerExecuteScript('drizzle-kit', ['generate']) %>
167
167
  </code>
168
168
  </li>
169
169
  <li>
170
170
  Run:{' '}
171
171
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
172
- npx drizzle-kit migrate
172
+ <%- getPackageManagerExecuteScript('drizzle-kit', ['migrate']) %>
173
173
  </code>
174
174
  </li>
175
175
  <li>
176
176
  Optional:{' '}
177
177
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
178
- npx drizzle-kit studio
178
+ <%- getPackageManagerExecuteScript('drizzle-kit', ['studio']) %>
179
179
  </code>
180
180
  </li>
181
181
  </ol>
@@ -1,4 +1,4 @@
1
1
  # These will be automatically created by Neon Launchpad (https://neon.new).
2
2
  # You will also need to
3
- VITE_DATABASE_URL=
4
- VITE_DATABASE_URL_POOLER=
3
+ DATABASE_URL=
4
+ DATABASE_URL_POOLER=
@@ -6,5 +6,5 @@ export default postgresPlugin({
6
6
  path: 'db/init.sql',
7
7
  },
8
8
  referrer: 'create-tanstack',
9
- dotEnvKey: 'VITE_DATABASE_URL',
9
+ dotEnvKey: 'DATABASE_URL',
10
10
  })
@@ -3,11 +3,11 @@ import { neon } from '@neondatabase/serverless'
3
3
  let client: ReturnType<typeof neon>
4
4
 
5
5
  export async function getClient() {
6
- if (!process.env.VITE_DATABASE_URL) {
6
+ if (!process.env.DATABASE_URL) {
7
7
  return undefined
8
8
  }
9
9
  if (!client) {
10
- client = await neon(process.env.VITE_DATABASE_URL!)
10
+ client = await neon(process.env.DATABASE_URL!)
11
11
  }
12
12
  return client
13
13
  }
@@ -0,0 +1,9 @@
1
+ ## Setting up PostHog
2
+
3
+ 1. Create a PostHog account at [posthog.com](https://posthog.com)
4
+ 2. Get your Project API Key from [Project Settings](https://app.posthog.com/project/settings)
5
+ 3. Set `VITE_POSTHOG_KEY` in your `.env.local`
6
+
7
+ ### Optional Configuration
8
+
9
+ - `VITE_POSTHOG_HOST` - Set this if you're using PostHog Cloud EU (`https://eu.i.posthog.com`) or self-hosting
@@ -0,0 +1,4 @@
1
+ # PostHog configuration, get your key from https://app.posthog.com/project/settings
2
+ VITE_POSTHOG_KEY=phc_xxx
3
+ # Optional: PostHog API host (for self-hosted or EU cloud)
4
+ # VITE_POSTHOG_HOST=https://us.i.posthog.com
@@ -0,0 +1,20 @@
1
+ import posthog from 'posthog-js'
2
+ import { PostHogProvider as BasePostHogProvider } from '@posthog/react'
3
+ import type { ReactNode } from 'react'
4
+
5
+ if (typeof window !== 'undefined' && import.meta.env.VITE_POSTHOG_KEY) {
6
+ posthog.init(import.meta.env.VITE_POSTHOG_KEY, {
7
+ api_host: import.meta.env.VITE_POSTHOG_HOST || 'https://us.i.posthog.com',
8
+ person_profiles: 'identified_only',
9
+ capture_pageview: false,
10
+ defaults: '2025-11-30',
11
+ })
12
+ }
13
+
14
+ interface PostHogProviderProps {
15
+ children: ReactNode
16
+ }
17
+
18
+ export default function PostHogProvider({ children }: PostHogProviderProps) {
19
+ return <BasePostHogProvider client={posthog}>{children}</BasePostHogProvider>
20
+ }
@@ -0,0 +1,93 @@
1
+ import { createFileRoute, Link } from '@tanstack/react-router'
2
+ import { usePostHog } from '@posthog/react'
3
+ import { useState } from 'react'
4
+
5
+ export const Route = createFileRoute('/demo/posthog')({
6
+ component: PostHogDemo,
7
+ })
8
+
9
+ function PostHogDemo() {
10
+ const posthog = usePostHog()
11
+ const [eventCount, setEventCount] = useState(0)
12
+ const posthogKey = import.meta.env.VITE_POSTHOG_KEY
13
+ const isConfigured = Boolean(posthogKey) && posthogKey !== 'phc_xxx'
14
+
15
+ const trackEvent = (
16
+ eventName: string,
17
+ properties?: Record<string, unknown>,
18
+ ) => {
19
+ posthog.capture(eventName, properties)
20
+ setEventCount((c) => c + 1)
21
+ }
22
+
23
+ return (
24
+ <div className="min-h-screen bg-gray-900 text-white p-8">
25
+ <div className="max-w-md mx-auto">
26
+ <h1 className="text-3xl font-bold mb-6">PostHog Demo</h1>
27
+
28
+ {!isConfigured && (
29
+ <div className="mb-4 p-4 bg-yellow-900/50 border border-yellow-600 rounded-lg">
30
+ <p className="text-yellow-200 text-sm">
31
+ <strong>Warning:</strong> VITE_POSTHOG_KEY is not configured.
32
+ Events won't be sent to PostHog. Add it to your{' '}
33
+ <code className="bg-yellow-900 px-1 rounded">.env</code> file.
34
+ </p>
35
+ </div>
36
+ )}
37
+
38
+ <div className="bg-gray-800 rounded-lg p-6">
39
+ <p className="text-gray-400 mb-4">
40
+ Click the button below to send events to PostHog. Check your PostHog
41
+ dashboard to see them appear in real-time.
42
+ </p>
43
+
44
+ <button
45
+ onClick={() => trackEvent('button_clicked', { button: 'demo' })}
46
+ className="w-full bg-cyan-600 hover:bg-cyan-700 px-4 py-3 rounded font-medium"
47
+ >
48
+ Track Click
49
+ </button>
50
+
51
+ {isConfigured && (
52
+ <div className="mt-6 p-4 bg-gray-700 rounded">
53
+ <p className="text-sm text-gray-400">Events sent this session:</p>
54
+ <p className="text-4xl font-bold text-cyan-400">{eventCount}</p>
55
+ </div>
56
+ )}
57
+ </div>
58
+
59
+ <p className="mt-4 text-sm text-gray-400">
60
+ Open your{' '}
61
+ <a
62
+ href="https://app.posthog.com/events"
63
+ target="_blank"
64
+ rel="noopener noreferrer"
65
+ className="text-cyan-400 hover:text-cyan-300 underline"
66
+ >
67
+ PostHog Events
68
+ </a>{' '}
69
+ page to see these events appear.
70
+ </p>
71
+
72
+ <p className="mt-2 text-sm text-gray-400">
73
+ Learn more in the{' '}
74
+ <a
75
+ href="https://posthog.com/docs/libraries/react"
76
+ target="_blank"
77
+ rel="noopener noreferrer"
78
+ className="text-cyan-400 hover:text-cyan-300 underline"
79
+ >
80
+ PostHog React docs
81
+ </a>
82
+ .
83
+ </p>
84
+
85
+ <div className="mt-8">
86
+ <Link to="/" className="text-cyan-400 hover:text-cyan-300">
87
+ &larr; Back to Home
88
+ </Link>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ )
93
+ }
@@ -0,0 +1,5 @@
1
+ [
2
+ "src/integrations/posthog/provider.tsx",
3
+ "src/routes/demo/posthog.tsx",
4
+ "_dot_env.local.append"
5
+ ]
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "PostHog",
3
+ "description": "Product analytics, session replay, and feature flags",
4
+ "phase": "add-on",
5
+ "modes": ["file-router"],
6
+ "type": "add-on",
7
+ "category": "analytics",
8
+ "color": "#1D4AFF",
9
+ "priority": 20,
10
+ "link": "https://posthog.com",
11
+ "tailwind": true,
12
+ "routes": [
13
+ {
14
+ "icon": "BarChart",
15
+ "url": "/demo/posthog",
16
+ "name": "PostHog",
17
+ "path": "src/routes/demo/posthog.tsx",
18
+ "jsName": "PostHogDemo"
19
+ }
20
+ ],
21
+ "integrations": [
22
+ {
23
+ "type": "provider",
24
+ "jsName": "PostHogProvider",
25
+ "path": "src/integrations/posthog/provider.tsx"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "dependencies": {
3
+ "posthog-js": "^1.335.4",
4
+ "@posthog/react": "^1.7.0"
5
+ }
6
+ }
@@ -162,19 +162,19 @@ function DemoPrisma() {
162
162
  <li>
163
163
  Run:{' '}
164
164
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
165
- npx prisma generate
165
+ <%- getPackageManagerExecuteScript('prisma', ['generate']) %>
166
166
  </code>
167
167
  </li>
168
168
  <li>
169
169
  Run:{' '}
170
170
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
171
- npx prisma db push
171
+ <%- getPackageManagerExecuteScript('prisma', ['db', 'push']) %>
172
172
  </code>
173
173
  </li>
174
174
  <li>
175
175
  Optional:{' '}
176
176
  <code className="px-2 py-1 rounded bg-black/30 text-purple-300">
177
- npx prisma studio
177
+ <%- getPackageManagerExecuteScript('prisma', ['studio']) %>
178
178
  </code>
179
179
  </li>
180
180
  </ol>
@@ -11,7 +11,7 @@
11
11
  "tsx": "^4.20.6"
12
12
  },
13
13
  "scripts": {<% if (addOnOption.prisma.database === 'postgres') { %>
14
- "post-cta-init": "npx create-db@latest --user-agent tanstack/tsrouter",<% } %>
14
+ "post-cta-init": "<%- getPackageManagerExecuteScript('create-db@latest', ['--user-agent', 'tanstack/tsrouter']) %>",<% } %>
15
15
  "db:generate": "dotenv -e .env.local -- prisma generate",
16
16
  "db:push": "dotenv -e .env.local -- prisma db push",
17
17
  "db:migrate": "dotenv -e .env.local -- prisma migrate dev",
@@ -5,7 +5,7 @@
5
5
  "start": "node --import ./.output/server/instrument.server.mjs .output/server/index.mjs"
6
6
  },
7
7
  "dependencies": {
8
- "@sentry/tanstackstart-react": "^10.22.0",
8
+ "@sentry/tanstackstart-react": "^10.34.0",
9
9
  "dotenv-cli": "^11.0.0"
10
10
  }
11
11
  }
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "integrations": [
21
21
  {
22
- "type": "root-provider",
22
+ "type": "provider",
23
23
  "path": "src/integrations/tanstack-query/root-provider.tsx",
24
24
  "jsName": "TanStackQueryProvider"
25
25
  },
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "type": "vite-plugin",
15
15
  "import": "import { nitro } from 'nitro/vite'",
16
- "code": "nitro()"
16
+ "code": "nitro({ rollupConfig: { external: [/^@sentry\\//] } })"
17
17
  }
18
18
  ],
19
19
  "default": true
@@ -13,7 +13,7 @@
13
13
  {
14
14
  "type": "vite-plugin",
15
15
  "import": "import { nitro } from 'nitro/vite'",
16
- "code": "nitro()"
16
+ "code": "nitro({ rollupConfig: { external: [/^@sentry\\//] } })"
17
17
  }
18
18
  ]
19
19
  }
@@ -52,7 +52,7 @@ This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.
52
52
  ```
53
53
  <% } %>
54
54
  <% for(const addon of addOns.filter(addon => addon.readme)) { %>
55
- <%- addon.readme %>
55
+ <%- addon.readmeIsEjs ? renderTemplate(addon.readme) : addon.readme %>
56
56
  <% } %>
57
57
 
58
58
  ## Routing
@@ -17,7 +17,7 @@
17
17
  "lucide-react": "^0.561.0",
18
18
  "react": "^19.2.0",
19
19
  "react-dom": "^19.2.0",
20
- "vite-tsconfig-paths": "^6.0.2"
20
+ "vite-tsconfig-paths": "^5.1.4"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@tanstack/devtools-vite": "^0.3.11",
@@ -6,7 +6,7 @@ import { paraglideVitePlugin } from "@inlang/paraglide-js"
6
6
  import { tanstackStart } from '@tanstack/react-start/plugin/vite';
7
7
  import viteReact from '@vitejs/plugin-react'
8
8
  import viteTsConfigPaths from 'vite-tsconfig-paths'
9
- import { fileURLToPath, URL } from 'url'
9
+ import { fileURLToPath, URL } from 'node:url'
10
10
  import tailwindcss from "@tailwindcss/vite"
11
11
  <% for(const integration of integrations.filter(i => i.type === 'vite-plugin')) { %><%- integrationImportContent(integration) %>
12
12
  <% } %>