@tanstack/create 0.60.0 → 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 +12 -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
@@ -69,6 +69,35 @@ export function packageManagerInstall(environment, cwd, packagerManager, pkg) {
69
69
  const { command, args: commandArgs } = getPackageManagerInstallCommand(packagerManager, pkg);
70
70
  return environment.execute(command, commandArgs, cwd);
71
71
  }
72
+ export function translateExecuteCommand(packageManager, command) {
73
+ const args = command.args || [];
74
+ const parsed = parseExecuteCommand(command.command, args);
75
+ if (parsed) {
76
+ return getPackageManagerExecuteCommand(packageManager, parsed.pkg, parsed.args);
77
+ }
78
+ return { command: command.command, args };
79
+ }
80
+ function parseExecuteCommand(command, args) {
81
+ if (command === 'npx') {
82
+ const filtered = args[0] === '-y' ? args.slice(1) : args;
83
+ const [pkg, ...rest] = filtered;
84
+ return pkg ? { pkg, args: rest } : null;
85
+ }
86
+ if (command === 'pnpx' || command === 'bunx') {
87
+ const filtered = command === 'bunx' && args[0] === '--bun' ? args.slice(1) : args;
88
+ const [pkg, ...rest] = filtered;
89
+ return pkg ? { pkg, args: rest } : null;
90
+ }
91
+ if ((command === 'pnpm' || command === 'yarn') && args[0] === 'dlx') {
92
+ const [, pkg, ...rest] = args;
93
+ return pkg ? { pkg, args: rest } : null;
94
+ }
95
+ if (command === 'deno' && args[0] === 'run' && args[1]?.startsWith('npm:')) {
96
+ const pkg = args[1].slice(4);
97
+ return pkg ? { pkg, args: args.slice(2) } : null;
98
+ }
99
+ return null;
100
+ }
72
101
  export function packageManagerExecute(environment, cwd, packagerManager, pkg, args) {
73
102
  const { command, args: commandArgs } = getPackageManagerExecuteCommand(packagerManager, pkg, args);
74
103
  return environment.execute(command, commandArgs, cwd);
@@ -2,7 +2,7 @@ import { resolve, sep } from 'node:path';
2
2
  import { render } from 'ejs';
3
3
  import { format } from 'prettier';
4
4
  import { formatCommand } from './utils.js';
5
- import { getPackageManagerInstallCommand, getPackageManagerScriptCommand, } from './package-manager.js';
5
+ import { getPackageManagerExecuteCommand, getPackageManagerInstallCommand, getPackageManagerScriptCommand, } from './package-manager.js';
6
6
  import { relativePath } from './file-helpers.js';
7
7
  function convertDotFilesAndPaths(path) {
8
8
  return path
@@ -36,6 +36,9 @@ export function createTemplateFile(environment, options) {
36
36
  ...args,
37
37
  ]));
38
38
  }
39
+ function getPackageManagerExecuteScript(pkg, args = []) {
40
+ return formatCommand(getPackageManagerExecuteCommand(options.packageManager, pkg, args));
41
+ }
39
42
  class IgnoreFileError extends Error {
40
43
  constructor() {
41
44
  super('ignoreFile');
@@ -86,9 +89,13 @@ export function createTemplateFile(environment, options) {
86
89
  routes,
87
90
  getPackageManagerAddScript,
88
91
  getPackageManagerRunScript,
92
+ getPackageManagerExecuteScript,
89
93
  relativePath: (path, stripExtension = false) => relativePath(file, path, stripExtension),
90
94
  integrationImportContent,
91
95
  integrationImportCode,
96
+ renderTemplate: (content) => {
97
+ return render(content, templateValues);
98
+ },
92
99
  ignoreFile: () => {
93
100
  throw new IgnoreFileError();
94
101
  },
@@ -39,7 +39,7 @@ export declare function generateProject(persistedOptions: PersistedOptions): Pro
39
39
  license?: string | undefined;
40
40
  warning?: string | undefined;
41
41
  tailwind?: boolean | undefined;
42
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
42
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
43
43
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
44
44
  color?: string | undefined;
45
45
  priority?: number | undefined;
@@ -69,6 +69,7 @@ export declare function generateProject(persistedOptions: PersistedOptions): Pro
69
69
  import?: string | undefined;
70
70
  }[] | undefined;
71
71
  readme?: string | undefined;
72
+ readmeIsEjs?: boolean | undefined;
72
73
  };
73
74
  output: import("../environment.js").MemoryEnvironmentOutput;
74
75
  }>;
@@ -18,6 +18,13 @@ export declare function getPackageManagerInstallCommand(packagerManager: Package
18
18
  export declare function packageManagerInstall(environment: Environment, cwd: string, packagerManager: PackageManager, pkg?: string): Promise<{
19
19
  stdout: string;
20
20
  }>;
21
+ export declare function translateExecuteCommand(packageManager: PackageManager, command: {
22
+ command: string;
23
+ args?: Array<string>;
24
+ }): {
25
+ command: string;
26
+ args: Array<string>;
27
+ };
21
28
  export declare function packageManagerExecute(environment: Environment, cwd: string, packagerManager: PackageManager, pkg: string, args: Array<string>): Promise<{
22
29
  stdout: string;
23
30
  }>;
@@ -114,7 +114,7 @@ export declare const AddOnBaseSchema: z.ZodObject<{
114
114
  warning: z.ZodOptional<z.ZodString>;
115
115
  tailwind: z.ZodOptional<z.ZodBoolean>;
116
116
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
117
- category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
117
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "analytics", "i18n", "tooling", "other"]>>;
118
118
  exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
119
119
  color: z.ZodOptional<z.ZodString>;
120
120
  priority: z.ZodOptional<z.ZodNumber>;
@@ -225,7 +225,7 @@ export declare const AddOnBaseSchema: z.ZodObject<{
225
225
  license?: string | undefined;
226
226
  warning?: string | undefined;
227
227
  tailwind?: boolean | undefined;
228
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
228
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
229
229
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
230
230
  color?: string | undefined;
231
231
  priority?: number | undefined;
@@ -273,7 +273,7 @@ export declare const AddOnBaseSchema: z.ZodObject<{
273
273
  license?: string | undefined;
274
274
  warning?: string | undefined;
275
275
  tailwind?: boolean | undefined;
276
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
276
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
277
277
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
278
278
  color?: string | undefined;
279
279
  priority?: number | undefined;
@@ -307,7 +307,7 @@ export declare const StarterSchema: z.ZodObject<{
307
307
  warning: z.ZodOptional<z.ZodString>;
308
308
  tailwind: z.ZodOptional<z.ZodBoolean>;
309
309
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
310
- category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
310
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "analytics", "i18n", "tooling", "other"]>>;
311
311
  exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
312
312
  color: z.ZodOptional<z.ZodString>;
313
313
  priority: z.ZodOptional<z.ZodNumber>;
@@ -426,7 +426,7 @@ export declare const StarterSchema: z.ZodObject<{
426
426
  license?: string | undefined;
427
427
  warning?: string | undefined;
428
428
  tailwind?: boolean | undefined;
429
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
429
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
430
430
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
431
431
  color?: string | undefined;
432
432
  priority?: number | undefined;
@@ -478,7 +478,7 @@ export declare const StarterSchema: z.ZodObject<{
478
478
  license?: string | undefined;
479
479
  warning?: string | undefined;
480
480
  tailwind?: boolean | undefined;
481
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
481
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
482
482
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
483
483
  color?: string | undefined;
484
484
  priority?: number | undefined;
@@ -513,7 +513,7 @@ export declare const StarterCompiledSchema: z.ZodObject<{
513
513
  warning: z.ZodOptional<z.ZodString>;
514
514
  tailwind: z.ZodOptional<z.ZodBoolean>;
515
515
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
516
- category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
516
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "analytics", "i18n", "tooling", "other"]>>;
517
517
  exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
518
518
  color: z.ZodOptional<z.ZodString>;
519
519
  priority: z.ZodOptional<z.ZodNumber>;
@@ -637,7 +637,7 @@ export declare const StarterCompiledSchema: z.ZodObject<{
637
637
  license?: string | undefined;
638
638
  warning?: string | undefined;
639
639
  tailwind?: boolean | undefined;
640
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
640
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
641
641
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
642
642
  color?: string | undefined;
643
643
  priority?: number | undefined;
@@ -691,7 +691,7 @@ export declare const StarterCompiledSchema: z.ZodObject<{
691
691
  license?: string | undefined;
692
692
  warning?: string | undefined;
693
693
  tailwind?: boolean | undefined;
694
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
694
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
695
695
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
696
696
  color?: string | undefined;
697
697
  priority?: number | undefined;
@@ -745,7 +745,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
745
745
  warning: z.ZodOptional<z.ZodString>;
746
746
  tailwind: z.ZodOptional<z.ZodBoolean>;
747
747
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
748
- category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
748
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "analytics", "i18n", "tooling", "other"]>>;
749
749
  exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
750
750
  color: z.ZodOptional<z.ZodString>;
751
751
  priority: z.ZodOptional<z.ZodNumber>;
@@ -853,6 +853,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
853
853
  }>, "many">>;
854
854
  phase: z.ZodEnum<["setup", "add-on"]>;
855
855
  readme: z.ZodOptional<z.ZodString>;
856
+ readmeIsEjs: z.ZodOptional<z.ZodBoolean>;
856
857
  }, "strip", z.ZodTypeAny, {
857
858
  type: "add-on" | "example" | "starter" | "toolchain" | "deployment";
858
859
  description: string;
@@ -881,7 +882,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
881
882
  license?: string | undefined;
882
883
  warning?: string | undefined;
883
884
  tailwind?: boolean | undefined;
884
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
885
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
885
886
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
886
887
  color?: string | undefined;
887
888
  priority?: number | undefined;
@@ -911,6 +912,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
911
912
  import?: string | undefined;
912
913
  }[] | undefined;
913
914
  readme?: string | undefined;
915
+ readmeIsEjs?: boolean | undefined;
914
916
  }, {
915
917
  type: "add-on" | "example" | "starter" | "toolchain" | "deployment";
916
918
  description: string;
@@ -939,7 +941,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
939
941
  license?: string | undefined;
940
942
  warning?: string | undefined;
941
943
  tailwind?: boolean | undefined;
942
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
944
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
943
945
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
944
946
  color?: string | undefined;
945
947
  priority?: number | undefined;
@@ -969,6 +971,7 @@ export declare const AddOnInfoSchema: z.ZodObject<{
969
971
  import?: string | undefined;
970
972
  }[] | undefined;
971
973
  readme?: string | undefined;
974
+ readmeIsEjs?: boolean | undefined;
972
975
  }>;
973
976
  export declare const AddOnCompiledSchema: z.ZodObject<{
974
977
  id: z.ZodString;
@@ -981,7 +984,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
981
984
  warning: z.ZodOptional<z.ZodString>;
982
985
  tailwind: z.ZodOptional<z.ZodBoolean>;
983
986
  type: z.ZodEnum<["add-on", "example", "starter", "toolchain", "deployment"]>;
984
- category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "i18n", "tooling", "other"]>>;
987
+ category: z.ZodOptional<z.ZodEnum<["tanstack", "database", "orm", "auth", "deploy", "styling", "monitoring", "cms", "api", "analytics", "i18n", "tooling", "other"]>>;
985
988
  exclusive: z.ZodOptional<z.ZodArray<z.ZodEnum<["orm", "auth", "deploy", "database", "linter"]>, "many">>;
986
989
  color: z.ZodOptional<z.ZodString>;
987
990
  priority: z.ZodOptional<z.ZodNumber>;
@@ -1089,6 +1092,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1089
1092
  }>, "many">>;
1090
1093
  phase: z.ZodEnum<["setup", "add-on"]>;
1091
1094
  readme: z.ZodOptional<z.ZodString>;
1095
+ readmeIsEjs: z.ZodOptional<z.ZodBoolean>;
1092
1096
  } & {
1093
1097
  files: z.ZodRecord<z.ZodString, z.ZodString>;
1094
1098
  deletedFiles: z.ZodArray<z.ZodString, "many">;
@@ -1123,7 +1127,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1123
1127
  license?: string | undefined;
1124
1128
  warning?: string | undefined;
1125
1129
  tailwind?: boolean | undefined;
1126
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
1130
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
1127
1131
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
1128
1132
  color?: string | undefined;
1129
1133
  priority?: number | undefined;
@@ -1153,6 +1157,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1153
1157
  import?: string | undefined;
1154
1158
  }[] | undefined;
1155
1159
  readme?: string | undefined;
1160
+ readmeIsEjs?: boolean | undefined;
1156
1161
  packageTemplate?: string | undefined;
1157
1162
  }, {
1158
1163
  type: "add-on" | "example" | "starter" | "toolchain" | "deployment";
@@ -1184,7 +1189,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1184
1189
  license?: string | undefined;
1185
1190
  warning?: string | undefined;
1186
1191
  tailwind?: boolean | undefined;
1187
- category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "i18n" | "tooling" | undefined;
1192
+ category?: "other" | "tanstack" | "database" | "orm" | "auth" | "deploy" | "styling" | "monitoring" | "cms" | "api" | "analytics" | "i18n" | "tooling" | undefined;
1188
1193
  exclusive?: ("database" | "orm" | "auth" | "deploy" | "linter")[] | undefined;
1189
1194
  color?: string | undefined;
1190
1195
  priority?: number | undefined;
@@ -1214,6 +1219,7 @@ export declare const AddOnCompiledSchema: z.ZodObject<{
1214
1219
  import?: string | undefined;
1215
1220
  }[] | undefined;
1216
1221
  readme?: string | undefined;
1222
+ readmeIsEjs?: boolean | undefined;
1217
1223
  packageTemplate?: string | undefined;
1218
1224
  }>;
1219
1225
  export type AddOnSelectOption = z.infer<typeof AddOnSelectOptionSchema>;
@@ -5,3 +5,5 @@ export declare function formatCommand({ command, args, }: {
5
5
  args: Array<string>;
6
6
  }): string;
7
7
  export declare function handleSpecialURL(url: string): string;
8
+ export declare function hasDrive(path: string): boolean;
9
+ export declare function stripDrive(path: string): string;
package/dist/types.js CHANGED
@@ -35,6 +35,7 @@ export const AddOnBaseSchema = z.object({
35
35
  'monitoring',
36
36
  'cms',
37
37
  'api',
38
+ 'analytics',
38
39
  'i18n',
39
40
  'tooling',
40
41
  'other',
@@ -98,6 +99,7 @@ export const AddOnInfoSchema = AddOnBaseSchema.extend({
98
99
  integrations: z.array(IntegrationSchema).optional(),
99
100
  phase: z.enum(['setup', 'add-on']),
100
101
  readme: z.string().optional(),
102
+ readmeIsEjs: z.boolean().optional(),
101
103
  });
102
104
  export const AddOnCompiledSchema = AddOnInfoSchema.extend({
103
105
  files: z.record(z.string(), z.string()),
package/dist/utils.js CHANGED
@@ -29,3 +29,9 @@ export function handleSpecialURL(url) {
29
29
  }
30
30
  return url;
31
31
  }
32
+ export function hasDrive(path) {
33
+ return /^[A-Za-z]:/.test(path);
34
+ }
35
+ export function stripDrive(path) {
36
+ return path.replace(/^[A-Za-z]:/, '');
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/create",
3
- "version": "0.60.0",
3
+ "version": "0.61.0",
4
4
  "description": "TanStack Application Builder Engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/create-app.ts CHANGED
@@ -6,6 +6,7 @@ import { writeConfigFileToEnvironment } from './config-file.js'
6
6
  import {
7
7
  getPackageManagerScriptCommand,
8
8
  packageManagerInstall,
9
+ translateExecuteCommand,
9
10
  } from './package-manager.js'
10
11
  import { createPackageJSON } from './package-json.js'
11
12
  import { createTemplateFile } from './template-file.js'
@@ -181,18 +182,19 @@ async function runCommandsAndInstallDependencies(
181
182
  addOn.phase === phase && addOn.command && addOn.command.command,
182
183
  )) {
183
184
  s.start(`Running commands for ${addOn.name}...`)
184
- const cmd = formatCommand({
185
+ const translated = translateExecuteCommand(options.packageManager, {
185
186
  command: addOn.command!.command,
186
187
  args: addOn.command!.args || [],
187
188
  })
189
+ const cmd = formatCommand(translated)
188
190
  environment.startStep({
189
191
  id: 'run-commands',
190
192
  type: 'command',
191
193
  message: cmd,
192
194
  })
193
195
  await environment.execute(
194
- addOn.command!.command,
195
- addOn.command!.args || [],
196
+ translated.command,
197
+ translated.args,
196
198
  options.targetDir,
197
199
  { inherit: true },
198
200
  )
@@ -208,10 +210,11 @@ async function runCommandsAndInstallDependencies(
208
210
  options.starter.command.command
209
211
  ) {
210
212
  s.start(`Setting up starter ${options.starter.name}...`)
211
- const cmd = formatCommand({
213
+ const starterTranslated = translateExecuteCommand(options.packageManager, {
212
214
  command: options.starter.command.command,
213
215
  args: options.starter.command.args || [],
214
216
  })
217
+ const cmd = formatCommand(starterTranslated)
215
218
  environment.startStep({
216
219
  id: 'run-starter-command',
217
220
  type: 'command',
@@ -219,8 +222,8 @@ async function runCommandsAndInstallDependencies(
219
222
  })
220
223
 
221
224
  await environment.execute(
222
- options.starter.command.command,
223
- options.starter.command.args || [],
225
+ starterTranslated.command,
226
+ starterTranslated.args,
224
227
  options.targetDir,
225
228
  { inherit: true },
226
229
  )
@@ -4,6 +4,7 @@ import { basename, extname, resolve } from 'node:path'
4
4
  import parseGitignore from 'parse-gitignore'
5
5
  import ignore from 'ignore'
6
6
 
7
+ import { hasDrive, stripDrive } from './utils'
7
8
  import type { Environment } from './types'
8
9
 
9
10
  const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico']
@@ -43,7 +44,17 @@ export function toCleanPath(absolutePath: string, baseDir: string): string {
43
44
  // Normalize both paths to use forward slashes for consistent comparison
44
45
  const normalizedPath = absolutePath.replace(/\\/g, '/')
45
46
  const normalizedBase = baseDir.replace(/\\/g, '/')
46
- let cleanPath = normalizedPath.replace(normalizedBase, '')
47
+ let cleanPath = normalizedPath
48
+ if (normalizedPath.startsWith(normalizedBase)) {
49
+ cleanPath = normalizedPath.slice(normalizedBase.length)
50
+ } else if (hasDrive(normalizedPath) !== hasDrive(normalizedBase)) {
51
+ // Handle paths that are missing the Windows drive letter (e.g. memfs on Windows)
52
+ const pathNoDrive = stripDrive(normalizedPath)
53
+ const baseNoDrive = stripDrive(normalizedBase)
54
+ if (pathNoDrive.startsWith(baseNoDrive)) {
55
+ cleanPath = pathNoDrive.slice(baseNoDrive.length)
56
+ }
57
+ }
47
58
  // Handle leading path separator
48
59
  if (cleanPath.startsWith('/')) {
49
60
  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
+ }