create-better-t-stack 3.2.22 → 3.2.23-canary.2b547ed5

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 (84) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +1 -1
  3. package/dist/index.d.ts +4 -2
  4. package/dist/index.js +1 -1
  5. package/dist/{src-WIwtBCHf.js → src-ehteLbIu.js} +105 -65
  6. package/package.json +1 -1
  7. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +5 -5
  8. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +1 -1
  9. package/templates/auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs +127 -0
  10. package/templates/auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs +138 -0
  11. package/templates/auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs +91 -0
  12. package/templates/auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs +102 -0
  13. package/templates/auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs +186 -0
  14. package/templates/auth/better-auth/native/bare/components/sign-in.tsx.hbs +131 -0
  15. package/templates/auth/better-auth/native/bare/components/sign-up.tsx.hbs +150 -0
  16. package/templates/auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs +9 -1
  17. package/templates/auth/better-auth/native/unistyles/components/sign-in.tsx.hbs +5 -0
  18. package/templates/auth/better-auth/native/unistyles/components/sign-up.tsx.hbs +5 -0
  19. package/templates/auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs +123 -0
  20. package/templates/auth/better-auth/native/uniwind/components/sign-in.tsx.hbs +90 -0
  21. package/templates/auth/better-auth/native/uniwind/components/sign-up.tsx.hbs +116 -0
  22. package/templates/auth/better-auth/server/base/src/index.ts.hbs +5 -5
  23. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +287 -0
  24. package/templates/examples/ai/native/{nativewind → bare}/polyfills.js +1 -0
  25. package/templates/examples/ai/native/{nativewind → uniwind}/app/(drawer)/ai.tsx.hbs +52 -51
  26. package/templates/examples/ai/native/uniwind/polyfills.js +26 -0
  27. package/templates/examples/todo/native/bare/app/(drawer)/todos.tsx.hbs +430 -0
  28. package/templates/examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs +295 -0
  29. package/templates/extras/bunfig.toml.hbs +3 -3
  30. package/templates/frontend/native/bare/_gitignore +18 -0
  31. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/(tabs)/_layout.tsx.hbs +7 -12
  32. package/templates/frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs +43 -0
  33. package/templates/frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs +43 -0
  34. package/templates/frontend/native/{nativewind → bare}/app/(drawer)/_layout.tsx.hbs +24 -1
  35. package/templates/frontend/native/bare/app/(drawer)/index.tsx.hbs +234 -0
  36. package/templates/frontend/native/bare/app/+not-found.tsx.hbs +65 -0
  37. package/templates/frontend/native/bare/app/_layout.tsx.hbs +163 -0
  38. package/templates/frontend/native/bare/app/modal.tsx.hbs +34 -0
  39. package/templates/frontend/native/{nativewind → bare}/app.json.hbs +1 -0
  40. package/templates/frontend/native/bare/components/container.tsx.hbs +25 -0
  41. package/templates/frontend/native/bare/components/header-button.tsx.hbs +47 -0
  42. package/templates/frontend/native/{nativewind → bare}/components/tabbar-icon.tsx.hbs +1 -0
  43. package/templates/frontend/native/{nativewind → bare}/lib/android-navigation-bar.tsx.hbs +1 -0
  44. package/templates/frontend/native/{nativewind → bare}/lib/constants.ts.hbs +1 -0
  45. package/templates/frontend/native/bare/lib/use-color-scheme.ts.hbs +20 -0
  46. package/templates/frontend/native/bare/metro.config.js.hbs +9 -0
  47. package/templates/frontend/native/{nativewind → bare}/package.json.hbs +1 -2
  48. package/templates/frontend/native/bare/tsconfig.json.hbs +11 -0
  49. package/templates/frontend/native/{nativewind → uniwind}/_gitignore +4 -8
  50. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs +46 -0
  51. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs +15 -0
  52. package/templates/frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs +15 -0
  53. package/templates/frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs +83 -0
  54. package/templates/frontend/native/uniwind/app/(drawer)/index.tsx.hbs +151 -0
  55. package/templates/frontend/native/uniwind/app/+not-found.tsx.hbs +32 -0
  56. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +131 -0
  57. package/templates/frontend/native/uniwind/app/modal.tsx.hbs +53 -0
  58. package/templates/frontend/native/uniwind/app.json.hbs +19 -0
  59. package/templates/frontend/native/uniwind/components/container.tsx.hbs +33 -0
  60. package/templates/frontend/native/uniwind/components/theme-toggle.tsx.hbs +35 -0
  61. package/templates/frontend/native/uniwind/contexts/app-theme-context.tsx.hbs +62 -0
  62. package/templates/frontend/native/uniwind/global.css +5 -0
  63. package/templates/frontend/native/uniwind/metro.config.js.hbs +13 -0
  64. package/templates/frontend/native/uniwind/package.json.hbs +54 -0
  65. package/templates/frontend/native/{nativewind → uniwind}/tsconfig.json.hbs +4 -8
  66. package/templates/auth/better-auth/convex/native/nativewind/components/sign-in.tsx.hbs +0 -86
  67. package/templates/auth/better-auth/convex/native/nativewind/components/sign-up.tsx.hbs +0 -97
  68. package/templates/auth/better-auth/native/nativewind/app/(drawer)/index.tsx.hbs +0 -95
  69. package/templates/auth/better-auth/native/nativewind/components/sign-in.tsx.hbs +0 -93
  70. package/templates/auth/better-auth/native/nativewind/components/sign-up.tsx.hbs +0 -104
  71. package/templates/examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs +0 -295
  72. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/index.tsx.hbs +0 -19
  73. package/templates/frontend/native/nativewind/app/(drawer)/(tabs)/two.tsx.hbs +0 -19
  74. package/templates/frontend/native/nativewind/app/(drawer)/index.tsx.hbs +0 -178
  75. package/templates/frontend/native/nativewind/app/+not-found.tsx.hbs +0 -29
  76. package/templates/frontend/native/nativewind/app/_layout.tsx.hbs +0 -175
  77. package/templates/frontend/native/nativewind/app/modal.tsx.hbs +0 -14
  78. package/templates/frontend/native/nativewind/babel.config.js.hbs +0 -14
  79. package/templates/frontend/native/nativewind/components/container.tsx.hbs +0 -8
  80. package/templates/frontend/native/nativewind/components/header-button.tsx.hbs +0 -26
  81. package/templates/frontend/native/nativewind/global.css +0 -50
  82. package/templates/frontend/native/nativewind/lib/use-color-scheme.ts.hbs +0 -12
  83. package/templates/frontend/native/nativewind/metro.config.js.hbs +0 -12
  84. package/templates/frontend/native/nativewind/tailwind.config.js.hbs +0 -59
package/README.md CHANGED
@@ -57,7 +57,7 @@ Options:
57
57
  --orm <type> ORM type (none, drizzle, prisma, mongoose)
58
58
  --auth Include authentication
59
59
  --no-auth Exclude authentication
60
- --frontend <types...> Frontend types (tanstack-router, react-router, tanstack-start, next, nuxt, svelte, solid, native-nativewind, native-unistyles, none)
60
+ --frontend <types...> Frontend types (tanstack-router, react-router, tanstack-start, next, nuxt, svelte, solid, native-bare, native-uniwind, native-unistyles, none)
61
61
  --addons <types...> Additional addons (pwa, tauri, starlight, biome, husky, turborepo, fumadocs, ultracite, oxlint, none)
62
62
  --examples <types...> Examples to include (todo, ai, none)
63
63
  --git Initialize git repository
@@ -119,7 +119,7 @@ npx create-better-t-stack my-app --backend elysia --runtime node
119
119
  Create a project with multiple frontend options (one web + one native):
120
120
 
121
121
  ```bash
122
- npx create-better-t-stack my-app --frontend tanstack-router native-nativewind
122
+ npx create-better-t-stack my-app --frontend tanstack-router native-bare
123
123
  ```
124
124
 
125
125
  Create a project with examples:
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as createBtsCli } from "./src-WIwtBCHf.js";
2
+ import { n as createBtsCli } from "./src-ehteLbIu.js";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.d.ts CHANGED
@@ -43,7 +43,8 @@ declare const FrontendSchema: z.ZodEnum<{
43
43
  "tanstack-start": "tanstack-start";
44
44
  next: "next";
45
45
  nuxt: "nuxt";
46
- "native-nativewind": "native-nativewind";
46
+ "native-bare": "native-bare";
47
+ "native-uniwind": "native-uniwind";
47
48
  "native-unistyles": "native-unistyles";
48
49
  svelte: "svelte";
49
50
  solid: "solid";
@@ -242,7 +243,8 @@ declare const router: {
242
243
  "tanstack-start": "tanstack-start";
243
244
  next: "next";
244
245
  nuxt: "nuxt";
245
- "native-nativewind": "native-nativewind";
246
+ "native-bare": "native-bare";
247
+ "native-uniwind": "native-uniwind";
246
248
  "native-unistyles": "native-unistyles";
247
249
  svelte: "svelte";
248
250
  solid: "solid";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-WIwtBCHf.js";
2
+ import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-ehteLbIu.js";
3
3
 
4
4
  export { builder, createBtsCli, docs, init, router, sponsors };
@@ -216,7 +216,8 @@ const FrontendSchema = z.enum([
216
216
  "tanstack-start",
217
217
  "next",
218
218
  "nuxt",
219
- "native-nativewind",
219
+ "native-bare",
220
+ "native-uniwind",
220
221
  "native-unistyles",
221
222
  "svelte",
222
223
  "solid",
@@ -337,13 +338,13 @@ function isWebFrontend(value) {
337
338
  function splitFrontends(values = []) {
338
339
  return {
339
340
  web: values.filter((f) => isWebFrontend(f)),
340
- native: values.filter((f) => f === "native-nativewind" || f === "native-unistyles")
341
+ native: values.filter((f) => f === "native-bare" || f === "native-uniwind" || f === "native-unistyles")
341
342
  };
342
343
  }
343
344
  function ensureSingleWebAndNative(frontends) {
344
345
  const { web, native } = splitFrontends(frontends);
345
346
  if (web.length > 1) exitWithError("Cannot select multiple web frameworks. Choose only one of: tanstack-router, tanstack-start, react-router, next, nuxt, svelte, solid");
346
- if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-nativewind, native-unistyles");
347
+ if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-bare, native-uniwind, native-unistyles");
347
348
  }
348
349
  const FULLSTACK_FRONTENDS$1 = ["next", "tanstack-start"];
349
350
  function validateSelfBackendCompatibility(providedFlags, options, config) {
@@ -352,7 +353,7 @@ function validateSelfBackendCompatibility(providedFlags, options, config) {
352
353
  if (backend === "self") {
353
354
  const { web, native } = splitFrontends(frontends);
354
355
  if (!(web.length === 1 && FULLSTACK_FRONTENDS$1.includes(web[0]))) exitWithError("Backend 'self' (fullstack) currently only supports Next.js and TanStack Start frontends. Please use --frontend next or --frontend tanstack-start. Support for Nuxt and SvelteKit will be added in a future update.");
355
- if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-nativewind, native-unistyles");
356
+ if (native.length > 1) exitWithError("Cannot select multiple native frameworks. Choose only one of: native-bare, native-uniwind, native-unistyles");
356
357
  }
357
358
  const hasFullstackFrontend = frontends.some((f) => FULLSTACK_FRONTENDS$1.includes(f));
358
359
  if (providedFlags.has("backend") && !hasFullstackFrontend && backend === "self") exitWithError("Backend 'self' (fullstack) currently only supports Next.js and TanStack Start frontends. Please use --frontend next or --frontend tanstack-start or choose a different backend. Support for Nuxt and SvelteKit will be added in a future update.");
@@ -622,7 +623,8 @@ async function getAuthChoice(auth, backend, frontend) {
622
623
  "tanstack-router",
623
624
  "tanstack-start",
624
625
  "next",
625
- "native-nativewind",
626
+ "native-bare",
627
+ "native-uniwind",
626
628
  "native-unistyles"
627
629
  ].includes(f));
628
630
  const hasClerkCompatibleFrontends = frontend?.some((f) => [
@@ -630,7 +632,8 @@ async function getAuthChoice(auth, backend, frontend) {
630
632
  "tanstack-router",
631
633
  "tanstack-start",
632
634
  "next",
633
- "native-nativewind",
635
+ "native-bare",
636
+ "native-uniwind",
634
637
  "native-unistyles"
635
638
  ].includes(f));
636
639
  const options = [];
@@ -965,16 +968,24 @@ async function getFrontendChoice(frontendOptions, backend, auth) {
965
968
  if (frontendTypes.includes("native")) {
966
969
  const nativeFramework = await select({
967
970
  message: "Choose native",
968
- options: [{
969
- value: "native-nativewind",
970
- label: "NativeWind",
971
- hint: "Use Tailwind CSS for React Native"
972
- }, {
973
- value: "native-unistyles",
974
- label: "Unistyles",
975
- hint: "Consistent styling for React Native"
976
- }],
977
- initialValue: "native-nativewind"
971
+ options: [
972
+ {
973
+ value: "native-bare",
974
+ label: "Bare",
975
+ hint: "Bare Expo without styling library"
976
+ },
977
+ {
978
+ value: "native-uniwind",
979
+ label: "UniWind",
980
+ hint: "Use Tailwind CSS for React Native"
981
+ },
982
+ {
983
+ value: "native-unistyles",
984
+ label: "Unistyles",
985
+ hint: "Consistent styling for React Native"
986
+ }
987
+ ],
988
+ initialValue: "native-bare"
978
989
  });
979
990
  if (isCancel(nativeFramework)) return exitCancelled("Operation cancelled");
980
991
  result.push(nativeFramework);
@@ -1376,7 +1387,7 @@ const getLatestCLIVersion = () => {
1376
1387
  */
1377
1388
  function isTelemetryEnabled() {
1378
1389
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
1379
- const BTS_TELEMETRY = "1";
1390
+ const BTS_TELEMETRY = "0";
1380
1391
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
1381
1392
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
1382
1393
  return true;
@@ -1384,8 +1395,8 @@ function isTelemetryEnabled() {
1384
1395
 
1385
1396
  //#endregion
1386
1397
  //#region src/utils/analytics.ts
1387
- const POSTHOG_API_KEY = "phc_8ZUxEwwfKMajJLvxz1daGd931dYbQrwKNficBmsdIrs";
1388
- const POSTHOG_HOST = "https://us.i.posthog.com";
1398
+ const POSTHOG_API_KEY = "random";
1399
+ const POSTHOG_HOST = "random";
1389
1400
  function generateSessionId() {
1390
1401
  const rand = Math.random().toString(36).slice(2);
1391
1402
  return `cli_${Date.now().toString(36)}${rand}`;
@@ -1733,7 +1744,8 @@ function validateConvexConstraints(config, providedFlags) {
1733
1744
  "tanstack-router",
1734
1745
  "tanstack-start",
1735
1746
  "next",
1736
- "native-nativewind",
1747
+ "native-bare",
1748
+ "native-uniwind",
1737
1749
  "native-unistyles"
1738
1750
  ];
1739
1751
  if (!config.frontend?.some((f) => supportedFrontends.includes(f))) exitWithError("Better-Auth with Convex backend requires a supported frontend (TanStack Router, TanStack Start, Next.js, or Native).");
@@ -2076,12 +2088,12 @@ async function setupFumadocs(config) {
2076
2088
  const fumadocsInitCommand = getPackageExecutionCommand(packageManager, `create-fumadocs-app@latest fumadocs --template ${TEMPLATES[template].value} --src --pm ${packageManager} --no-git`);
2077
2089
  const appsDir = path.join(projectDir, "apps");
2078
2090
  await fs.ensureDir(appsDir);
2079
- log.info("Running Fumadocs create command...");
2091
+ const s = spinner();
2092
+ s.start("Running Fumadocs create command...");
2080
2093
  await execa(fumadocsInitCommand, {
2081
2094
  cwd: appsDir,
2082
2095
  env: { CI: "true" },
2083
- shell: true,
2084
- stdio: "inherit"
2096
+ shell: true
2085
2097
  });
2086
2098
  const fumadocsDir = path.join(projectDir, "apps", "fumadocs");
2087
2099
  const packageJsonPath = path.join(fumadocsDir, "package.json");
@@ -2091,7 +2103,7 @@ async function setupFumadocs(config) {
2091
2103
  if (packageJson.scripts?.dev) packageJson.scripts.dev = `${packageJson.scripts.dev} --port=4000`;
2092
2104
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
2093
2105
  }
2094
- log.success("Fumadocs setup complete!");
2106
+ s.stop("Fumadocs setup complete!");
2095
2107
  } catch (error) {
2096
2108
  log.error(pc.red("Failed to set up Fumadocs"));
2097
2109
  if (error instanceof Error) consola.error(pc.red(error.message));
@@ -2295,6 +2307,10 @@ const AGENTS = {
2295
2307
  goose: { label: "Goose" },
2296
2308
  "roo-code": { label: "Roo Code" }
2297
2309
  };
2310
+ const HOOKS = {
2311
+ cursor: { label: "Cursor" },
2312
+ claude: { label: "Claude" }
2313
+ };
2298
2314
  function getFrameworksFromFrontend(frontend) {
2299
2315
  const frameworkMap = {
2300
2316
  "tanstack-router": "react",
@@ -2302,7 +2318,8 @@ function getFrameworksFromFrontend(frontend) {
2302
2318
  "tanstack-start": "react",
2303
2319
  next: "next",
2304
2320
  nuxt: "vue",
2305
- "native-nativewind": "react",
2321
+ "native-bare": "react",
2322
+ "native-uniwind": "react",
2306
2323
  "native-unistyles": "react",
2307
2324
  svelte: "svelte",
2308
2325
  solid: "solid"
@@ -2332,12 +2349,20 @@ async function setupUltracite(config, hasHusky) {
2332
2349
  label: agent.label
2333
2350
  })),
2334
2351
  required: true
2352
+ }),
2353
+ hooks: () => autocompleteMultiselect({
2354
+ message: "Choose hooks",
2355
+ options: Object.entries(HOOKS).map(([key, hook]) => ({
2356
+ value: key,
2357
+ label: hook.label
2358
+ }))
2335
2359
  })
2336
2360
  }, { onCancel: () => {
2337
2361
  exitCancelled("Operation cancelled");
2338
2362
  } });
2339
2363
  const editors = result.editors;
2340
2364
  const agents = result.agents;
2365
+ const hooks = result.hooks;
2341
2366
  const frameworks = getFrameworksFromFrontend(frontend);
2342
2367
  const ultraciteArgs = [
2343
2368
  "init",
@@ -2347,21 +2372,21 @@ async function setupUltracite(config, hasHusky) {
2347
2372
  if (frameworks.length > 0) ultraciteArgs.push("--frameworks", ...frameworks);
2348
2373
  if (editors.length > 0) ultraciteArgs.push("--editors", ...editors);
2349
2374
  if (agents.length > 0) ultraciteArgs.push("--agents", ...agents);
2375
+ if (hooks.length > 0) ultraciteArgs.push("--hooks", ...hooks);
2350
2376
  if (hasHusky) ultraciteArgs.push("--integrations", "husky", "lint-staged");
2351
2377
  const ultraciteInitCommand = getPackageExecutionCommand(packageManager, `ultracite@latest ${ultraciteArgs.join(" ")} --skip-install`);
2352
- log.info("Running Ultracite init command...");
2378
+ const s = spinner();
2379
+ s.start("Running Ultracite init command...");
2353
2380
  await execa(ultraciteInitCommand, {
2354
2381
  cwd: projectDir,
2355
2382
  env: { CI: "true" },
2356
- shell: true,
2357
- stdio: "inherit"
2383
+ shell: true
2358
2384
  });
2359
- log.success("Ultracite setup complete!");
2360
2385
  if (hasHusky) await addPackageDependency({
2361
2386
  devDependencies: ["husky", "lint-staged"],
2362
2387
  projectDir
2363
2388
  });
2364
- log.success("Ultracite setup successfully!");
2389
+ s.stop("Ultracite setup successfully!");
2365
2390
  } catch (error) {
2366
2391
  log.error(pc.red("Failed to set up Ultracite"));
2367
2392
  if (error instanceof Error) console.error(pc.red(error.message));
@@ -2747,7 +2772,8 @@ async function setupFrontendTemplates(projectDir, context) {
2747
2772
  const hasNuxtWeb = context.frontend.includes("nuxt");
2748
2773
  const hasSvelteWeb = context.frontend.includes("svelte");
2749
2774
  const hasSolidWeb = context.frontend.includes("solid");
2750
- const hasNativeWind = context.frontend.includes("native-nativewind");
2775
+ const hasNativeBare = context.frontend.includes("native-bare");
2776
+ const hasNativeUniwind = context.frontend.includes("native-uniwind");
2751
2777
  const hasUnistyles = context.frontend.includes("native-unistyles");
2752
2778
  const isConvex = context.backend === "convex";
2753
2779
  if (hasReactWeb || hasNuxtWeb || hasSvelteWeb || hasSolidWeb) {
@@ -2797,13 +2823,14 @@ async function setupFrontendTemplates(projectDir, context) {
2797
2823
  }
2798
2824
  }
2799
2825
  }
2800
- if (hasNativeWind || hasUnistyles) {
2826
+ if (hasNativeBare || hasNativeUniwind || hasUnistyles) {
2801
2827
  const nativeAppDir = path.join(projectDir, "apps/native");
2802
2828
  await fs.ensureDir(nativeAppDir);
2803
2829
  const nativeBaseCommonDir = path.join(PKG_ROOT, "templates/frontend/native/base");
2804
2830
  if (await fs.pathExists(nativeBaseCommonDir)) await processAndCopyFiles("**/*", nativeBaseCommonDir, nativeAppDir, context);
2805
2831
  let nativeFrameworkPath = "";
2806
- if (hasNativeWind) nativeFrameworkPath = "nativewind";
2832
+ if (hasNativeBare) nativeFrameworkPath = "bare";
2833
+ else if (hasNativeUniwind) nativeFrameworkPath = "uniwind";
2807
2834
  else if (hasUnistyles) nativeFrameworkPath = "unistyles";
2808
2835
  const nativeSpecificDir = path.join(PKG_ROOT, `templates/frontend/native/${nativeFrameworkPath}`);
2809
2836
  if (await fs.pathExists(nativeSpecificDir)) await processAndCopyFiles("**/*", nativeSpecificDir, nativeAppDir, context, true);
@@ -2877,9 +2904,10 @@ async function setupAuthTemplate(projectDir, context) {
2877
2904
  const hasNuxtWeb = context.frontend.includes("nuxt");
2878
2905
  const hasSvelteWeb = context.frontend.includes("svelte");
2879
2906
  const hasSolidWeb = context.frontend.includes("solid");
2880
- const hasNativeWind = context.frontend.includes("native-nativewind");
2907
+ const hasNativeBare = context.frontend.includes("native-bare");
2908
+ const hasUniwind = context.frontend.includes("native-uniwind");
2881
2909
  const hasUnistyles = context.frontend.includes("native-unistyles");
2882
- const hasNative = hasNativeWind || hasUnistyles;
2910
+ const hasNative = hasNativeBare || hasUniwind || hasUnistyles;
2883
2911
  const authProvider = context.auth;
2884
2912
  if (context.backend === "convex" && authProvider === "clerk") {
2885
2913
  const convexBackendDestDir = path.join(projectDir, "packages/backend");
@@ -2903,11 +2931,10 @@ async function setupAuthTemplate(projectDir, context) {
2903
2931
  if (nativeAppDirExists) {
2904
2932
  const convexClerkNativeBaseSrc = path.join(PKG_ROOT, "templates/auth/clerk/convex/native/base");
2905
2933
  if (await fs.pathExists(convexClerkNativeBaseSrc)) await processAndCopyFiles("**/*", convexClerkNativeBaseSrc, nativeAppDir, context);
2906
- const hasNativeWind$1 = context.frontend.includes("native-nativewind");
2907
- const hasUnistyles$1 = context.frontend.includes("native-unistyles");
2908
2934
  let nativeFrameworkPath = "";
2909
- if (hasNativeWind$1) nativeFrameworkPath = "nativewind";
2910
- else if (hasUnistyles$1) nativeFrameworkPath = "unistyles";
2935
+ if (hasNativeBare) nativeFrameworkPath = "bare";
2936
+ else if (hasUniwind) nativeFrameworkPath = "uniwind";
2937
+ else if (hasUnistyles) nativeFrameworkPath = "unistyles";
2911
2938
  if (nativeFrameworkPath) {
2912
2939
  const convexClerkNativeFrameworkSrc = path.join(PKG_ROOT, `templates/auth/clerk/convex/native/${nativeFrameworkPath}`);
2913
2940
  if (await fs.pathExists(convexClerkNativeFrameworkSrc)) await processAndCopyFiles("**/*", convexClerkNativeFrameworkSrc, nativeAppDir, context);
@@ -2940,7 +2967,8 @@ async function setupAuthTemplate(projectDir, context) {
2940
2967
  const convexBetterAuthNativeBaseSrc = path.join(PKG_ROOT, "templates/auth/better-auth/convex/native/base");
2941
2968
  if (await fs.pathExists(convexBetterAuthNativeBaseSrc)) await processAndCopyFiles("**/*", convexBetterAuthNativeBaseSrc, nativeAppDir, context);
2942
2969
  let nativeFrameworkPath = "";
2943
- if (hasNativeWind) nativeFrameworkPath = "nativewind";
2970
+ if (hasNativeBare) nativeFrameworkPath = "bare";
2971
+ else if (hasUniwind) nativeFrameworkPath = "uniwind";
2944
2972
  else if (hasUnistyles) nativeFrameworkPath = "unistyles";
2945
2973
  if (nativeFrameworkPath) {
2946
2974
  const convexBetterAuthNativeFrameworkSrc = path.join(PKG_ROOT, `templates/auth/better-auth/convex/native/${nativeFrameworkPath}`);
@@ -2999,7 +3027,8 @@ async function setupAuthTemplate(projectDir, context) {
2999
3027
  const authNativeBaseSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/native/base`);
3000
3028
  if (await fs.pathExists(authNativeBaseSrc)) await processAndCopyFiles("**/*", authNativeBaseSrc, nativeAppDir, context);
3001
3029
  let nativeFrameworkAuthPath = "";
3002
- if (hasNativeWind) nativeFrameworkAuthPath = "nativewind";
3030
+ if (hasNativeBare) nativeFrameworkAuthPath = "bare";
3031
+ else if (hasUniwind) nativeFrameworkAuthPath = "uniwind";
3003
3032
  else if (hasUnistyles) nativeFrameworkAuthPath = "unistyles";
3004
3033
  if (nativeFrameworkAuthPath) {
3005
3034
  const authNativeFrameworkSrc = path.join(PKG_ROOT, `templates/auth/${authProvider}/native/${nativeFrameworkAuthPath}`);
@@ -3143,11 +3172,13 @@ async function setupExamplesTemplate(projectDir, context) {
3143
3172
  }
3144
3173
  }
3145
3174
  if (nativeAppDirExists) {
3146
- const hasNativeWind = context.frontend.includes("native-nativewind");
3175
+ const hasNativeBare = context.frontend.includes("native-bare");
3176
+ const hasUniwind = context.frontend.includes("native-uniwind");
3147
3177
  const hasUnistyles = context.frontend.includes("native-unistyles");
3148
- if (hasNativeWind || hasUnistyles) {
3178
+ if (hasNativeBare || hasUniwind || hasUnistyles) {
3149
3179
  let nativeFramework = "";
3150
- if (hasNativeWind) nativeFramework = "nativewind";
3180
+ if (hasNativeBare) nativeFramework = "bare";
3181
+ else if (hasUniwind) nativeFramework = "uniwind";
3151
3182
  else if (hasUnistyles) nativeFramework = "unistyles";
3152
3183
  const exampleNativeSrc = path.join(exampleBaseDir, `native/${nativeFramework}`);
3153
3184
  if (await fs.pathExists(exampleNativeSrc)) await processAndCopyFiles("**/*", exampleNativeSrc, nativeAppDir, context, false);
@@ -3157,9 +3188,10 @@ async function setupExamplesTemplate(projectDir, context) {
3157
3188
  }
3158
3189
  async function handleExtras(projectDir, context) {
3159
3190
  const extrasDir = path.join(PKG_ROOT, "templates/extras");
3160
- const hasNativeWind = context.frontend.includes("native-nativewind");
3191
+ const hasNativeBare = context.frontend.includes("native-bare");
3192
+ const hasUniwind = context.frontend.includes("native-uniwind");
3161
3193
  const hasUnistyles = context.frontend.includes("native-unistyles");
3162
- const hasNative = hasNativeWind || hasUnistyles;
3194
+ const hasNative = hasNativeBare || hasUniwind || hasUnistyles;
3163
3195
  if (context.packageManager === "pnpm") {
3164
3196
  const pnpmWorkspaceSrc = path.join(extrasDir, "pnpm-workspace.yaml");
3165
3197
  const pnpmWorkspaceDest = path.join(projectDir, "pnpm-workspace.yaml");
@@ -4020,6 +4052,7 @@ async function setupCatalogs(projectDir, options) {
4020
4052
  const packagePaths = [
4021
4053
  "apps/server",
4022
4054
  "apps/web",
4055
+ "apps/native",
4023
4056
  "apps/fumadocs",
4024
4057
  "apps/docs",
4025
4058
  "packages/api",
@@ -4150,7 +4183,7 @@ async function setupExamples(config) {
4150
4183
  const hasSvelte = frontend.includes("svelte");
4151
4184
  const hasReactWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("next") || frontend.includes("tanstack-start");
4152
4185
  const hasNext = frontend.includes("next");
4153
- const hasReactNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
4186
+ const hasReactNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
4154
4187
  if (webClientDirExists) {
4155
4188
  const dependencies = ["ai"];
4156
4189
  if (hasNuxt) dependencies.push("@ai-sdk/vue");
@@ -4195,7 +4228,11 @@ function getFrontendType(frontend) {
4195
4228
  "tanstack-start",
4196
4229
  "next"
4197
4230
  ];
4198
- const nativeFrontends = ["native-nativewind", "native-unistyles"];
4231
+ const nativeFrontends = [
4232
+ "native-bare",
4233
+ "native-uniwind",
4234
+ "native-unistyles"
4235
+ ];
4199
4236
  return {
4200
4237
  hasReactWeb: frontend.some((f) => reactBasedFrontends.includes(f)),
4201
4238
  hasNuxtWeb: frontend.includes("nuxt"),
@@ -4270,13 +4307,14 @@ function getQueryDependencies(frontend) {
4270
4307
  "tanstack-router",
4271
4308
  "tanstack-start",
4272
4309
  "next",
4273
- "native-nativewind",
4310
+ "native-bare",
4311
+ "native-uniwind",
4274
4312
  "native-unistyles"
4275
4313
  ];
4276
4314
  const deps = {};
4277
4315
  if (frontend.some((f) => reactBasedFrontends.includes(f))) {
4278
- const hasReactWeb = frontend.some((f) => f !== "native-nativewind" && f !== "native-unistyles" && reactBasedFrontends.includes(f));
4279
- const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
4316
+ const hasReactWeb = frontend.some((f) => f !== "native-bare" && f !== "native-uniwind" && f !== "native-unistyles" && reactBasedFrontends.includes(f));
4317
+ const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
4280
4318
  if (hasReactWeb) deps.web = {
4281
4319
  dependencies: ["@tanstack/react-query"],
4282
4320
  devDependencies: ["@tanstack/react-query-devtools"]
@@ -4428,7 +4466,7 @@ async function setupBetterAuthPlugins(projectDir, config) {
4428
4466
  pluginsToAdd.push("nextCookies()");
4429
4467
  importsToAdd.push("import { nextCookies } from \"better-auth/next-js\";");
4430
4468
  }
4431
- if (config.frontend?.includes("native-nativewind") || config.frontend?.includes("native-unistyles")) {
4469
+ if (config.frontend?.includes("native-bare") || config.frontend?.includes("native-uniwind") || config.frontend?.includes("native-unistyles")) {
4432
4470
  pluginsToAdd.push("expo()");
4433
4471
  importsToAdd.push("import { expo } from \"@better-auth/expo\";");
4434
4472
  }
@@ -4485,7 +4523,7 @@ async function setupAuth(config) {
4485
4523
  if (auth === "better-auth") {
4486
4524
  const convexBackendDir = path.join(projectDir, "packages/backend");
4487
4525
  const convexBackendDirExists = await fs.pathExists(convexBackendDir);
4488
- const hasNativeForBA = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
4526
+ const hasNativeForBA = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
4489
4527
  if (convexBackendDirExists) {
4490
4528
  await addPackageDependency({
4491
4529
  dependencies: ["better-auth", "@convex-dev/better-auth"],
@@ -4518,9 +4556,10 @@ async function setupAuth(config) {
4518
4556
  projectDir: clientDir
4519
4557
  });
4520
4558
  }
4521
- const hasNativeWind$1 = frontend.includes("native-nativewind");
4559
+ const hasNativeBare$1 = frontend.includes("native-bare");
4560
+ const hasNativeUniwind$1 = frontend.includes("native-uniwind");
4522
4561
  const hasUnistyles$1 = frontend.includes("native-unistyles");
4523
- if (nativeDirExists && (hasNativeWind$1 || hasUnistyles$1)) await addPackageDependency({
4562
+ if (nativeDirExists && (hasNativeBare$1 || hasNativeUniwind$1 || hasUnistyles$1)) await addPackageDependency({
4524
4563
  dependencies: [
4525
4564
  "better-auth",
4526
4565
  "@better-auth/expo",
@@ -4533,9 +4572,10 @@ async function setupAuth(config) {
4533
4572
  projectDir: nativeDir
4534
4573
  });
4535
4574
  }
4536
- const hasNativeWind = frontend.includes("native-nativewind");
4575
+ const hasNativeBare = frontend.includes("native-bare");
4576
+ const hasNativeUniwind = frontend.includes("native-uniwind");
4537
4577
  const hasUnistyles = frontend.includes("native-unistyles");
4538
- if (auth === "clerk" && nativeDirExists && (hasNativeWind || hasUnistyles)) await addPackageDependency({
4578
+ if (auth === "clerk" && nativeDirExists && (hasNativeBare || hasNativeUniwind || hasUnistyles)) await addPackageDependency({
4539
4579
  dependencies: ["@clerk/clerk-expo"],
4540
4580
  projectDir: nativeDir
4541
4581
  });
@@ -4561,7 +4601,7 @@ async function setupAuth(config) {
4561
4601
  projectDir: clientDir
4562
4602
  });
4563
4603
  }
4564
- if ((frontend.includes("native-nativewind") || frontend.includes("native-unistyles")) && nativeDirExists) {
4604
+ if ((frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles")) && nativeDirExists) {
4565
4605
  if (auth === "better-auth") {
4566
4606
  await addPackageDependency({
4567
4607
  dependencies: ["better-auth", "@better-auth/expo"],
@@ -4728,7 +4768,7 @@ async function setupEnvironmentVariables(config) {
4728
4768
  await addEnvVariablesToFile(path.join(clientDir, ".env"), clientVars);
4729
4769
  }
4730
4770
  }
4731
- if (frontend.includes("native-nativewind") || frontend.includes("native-unistyles")) {
4771
+ if (frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles")) {
4732
4772
  const nativeDir = path.join(projectDir, "apps/native");
4733
4773
  if (await fs.pathExists(nativeDir)) {
4734
4774
  let envVarName = "EXPO_PUBLIC_SERVER_URL";
@@ -4761,7 +4801,7 @@ async function setupEnvironmentVariables(config) {
4761
4801
  const convexBackendDir = path.join(projectDir, "packages/backend");
4762
4802
  if (await fs.pathExists(convexBackendDir)) {
4763
4803
  const envLocalPath = path.join(convexBackendDir, ".env.local");
4764
- const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
4804
+ const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
4765
4805
  const hasWeb = hasWebFrontend$1;
4766
4806
  if (!await fs.pathExists(envLocalPath) || !(await fs.readFile(envLocalPath, "utf8")).includes("npx convex env set")) {
4767
4807
  const convexCommands = `# Set Convex environment variables
@@ -6070,7 +6110,7 @@ function generateReadmeContent(options) {
6070
6110
  const { projectName, packageManager, database, auth, addons = [], orm = "drizzle", runtime = "bun", frontend = ["tanstack-router"], backend = "hono", api = "trpc", webDeploy, serverDeploy } = options;
6071
6111
  const isConvex = backend === "convex";
6072
6112
  const hasReactRouter = frontend.includes("react-router");
6073
- const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
6113
+ const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
6074
6114
  const hasSvelte = frontend.includes("svelte");
6075
6115
  const packageManagerRunCmd = `${packageManager} run`;
6076
6116
  let webPort = "3001";
@@ -6196,7 +6236,7 @@ function generateProjectStructure(projectName, frontend, backend, addons, isConv
6196
6236
  else structure.push(`│ ├── web/ # Frontend application (${frontendType})`);
6197
6237
  }
6198
6238
  }
6199
- if (frontend.includes("native-nativewind") || frontend.includes("native-unistyles")) if (isBackendSelf) structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6239
+ if (frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles")) if (isBackendSelf) structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6200
6240
  else structure.push("│ ├── native/ # Mobile application (React Native, Expo)");
6201
6241
  if (addons.includes("starlight")) if (isBackendSelf) structure.push("│ ├── docs/ # Documentation site (Astro Starlight)");
6202
6242
  else structure.push("│ ├── docs/ # Documentation site (Astro Starlight)");
@@ -6225,7 +6265,7 @@ function generateFeaturesList(database, auth, addons, orm, runtime, frontend, ba
6225
6265
  const isBackendNone = backend === "none";
6226
6266
  const hasTanstackRouter = frontend.includes("tanstack-router");
6227
6267
  const hasReactRouter = frontend.includes("react-router");
6228
- const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles");
6268
+ const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
6229
6269
  const hasNext = frontend.includes("next");
6230
6270
  const hasTanstackStart = frontend.includes("tanstack-start");
6231
6271
  const hasSvelte = frontend.includes("svelte");
@@ -6504,7 +6544,7 @@ async function displayPostInstallInstructions(config) {
6504
6544
  const databaseInstructions = !isConvex && database !== "none" ? await getDatabaseInstructions(database, orm, runCmd, runtime, dbSetup, serverDeploy, backend) : "";
6505
6545
  const tauriInstructions = addons?.includes("tauri") ? getTauriInstructions(runCmd) : "";
6506
6546
  const lintingInstructions = hasHuskyOrBiome ? getLintingInstructions(runCmd) : "";
6507
- const nativeInstructions = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles") ? getNativeInstructions(isConvex, isBackendSelf, frontend || []) : "";
6547
+ const nativeInstructions = frontend?.includes("native-bare") || frontend?.includes("native-uniwind") || frontend?.includes("native-unistyles") ? getNativeInstructions(isConvex, isBackendSelf, frontend || []) : "";
6508
6548
  const pwaInstructions = addons?.includes("pwa") && frontend?.includes("react-router") ? getPwaInstructions() : "";
6509
6549
  const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
6510
6550
  const clerkInstructions = isConvex && config.auth === "clerk" ? getClerkInstructions() : "";
@@ -6520,7 +6560,7 @@ async function displayPostInstallInstructions(config) {
6520
6560
  "svelte",
6521
6561
  "solid"
6522
6562
  ].includes(f));
6523
- const hasNative = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles");
6563
+ const hasNative = frontend?.includes("native-bare") || frontend?.includes("native-uniwind") || frontend?.includes("native-unistyles");
6524
6564
  const bunWebNativeWarning = packageManager === "bun" && hasNative && hasWeb ? getBunWebNativeWarning() : "";
6525
6565
  const noOrmWarning = !isConvex && database !== "none" && orm === "none" ? getNoOrmWarning() : "";
6526
6566
  const hasReactRouter = frontend?.includes("react-router");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.2.22",
3
+ "version": "3.2.23-canary.2b547ed5",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import { createClient, type GenericCtx } from "@convex-dev/better-auth";
2
- {{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
2
+ {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
3
3
  import { convex } from "@convex-dev/better-auth/plugins";
4
4
  import { expo } from "@better-auth/expo";
5
5
  {{else}}
@@ -17,7 +17,7 @@ import { v } from "convex/values";
17
17
  {{#if (or (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
18
18
  const siteUrl = process.env.SITE_URL!;
19
19
  {{/if}}
20
- {{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
20
+ {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
21
21
  const nativeAppUrl = process.env.NATIVE_APP_URL || "mybettertapp://";
22
22
  {{/if}}
23
23
 
@@ -31,10 +31,10 @@ function createAuth(
31
31
  logger: {
32
32
  disabled: optionsOnly,
33
33
  },
34
- {{#if (and (or (includes frontend "native-nativewind") (includes frontend "native-unistyles")) (or (includes frontend "tanstack-start") (includes frontend "next")))}}
34
+ {{#if (and (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles")) (or (includes frontend "tanstack-start") (includes frontend "next")))}}
35
35
  baseURL: siteUrl,
36
36
  trustedOrigins: [siteUrl, nativeAppUrl],
37
- {{else if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
37
+ {{else if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
38
38
  trustedOrigins: [nativeAppUrl],
39
39
  {{else if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
40
40
  baseURL: siteUrl,
@@ -48,7 +48,7 @@ function createAuth(
48
48
  requireEmailVerification: false,
49
49
  },
50
50
  plugins: [
51
- {{#if (or (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
51
+ {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
52
52
  expo(),
53
53
  {{/if}}
54
54
  {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
@@ -3,7 +3,7 @@ import { authComponent, createAuth } from "./auth";
3
3
 
4
4
  const http = httpRouter();
5
5
 
6
- {{#if (or (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "native-nativewind") (includes frontend "native-unistyles"))}}
6
+ {{#if (or (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
7
7
  authComponent.registerRoutes(http, createAuth);
8
8
  {{else}}
9
9
  authComponent.registerRoutes(http, createAuth, { cors: true });