create-better-fullstack 1.0.0-canary.c9b74dcc → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,110 +1,71 @@
1
1
  # Better Fullstack CLI
2
2
 
3
- A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations.
3
+ A CLI-first toolkit for building Full Stack applications. Skip the configuration. Ship the code.
4
4
 
5
5
  ## Quick Start
6
6
 
7
- Run without installing globally:
8
-
9
7
  ```bash
10
8
  # Using bun (recommended)
11
- bun create better-t-stack@latest
9
+ bun create better-fullstack@latest
12
10
 
13
11
  # Using pnpm
14
- pnpm create better-t-stack@latest
12
+ pnpm create better-fullstack@latest
15
13
 
16
14
  # Using npm
17
- npx create-better-t-stack@latest
15
+ npx create-better-fullstack@latest
18
16
  ```
19
17
 
20
- Follow the prompts to configure your project or use the `--yes` flag for defaults.
21
-
22
- ## Features
23
-
24
- | Category | Options |
25
- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
26
- | **TypeScript** | End-to-end type safety across all parts of your application |
27
- | **Frontend** | • React with TanStack Router<br>• React with React Router<br>• React with TanStack Start (SSR)<br>• Next.js<br>• SvelteKit<br>• Nuxt (Vue)<br>• SolidJS<br>• React Native with NativeWind (via Expo)<br>• React Native with Unistyles (via Expo)<br>• None |
28
- | **Backend** | • Hono<br>• Express<br>• Elysia<br>• Next.js API routes<br>• Convex<br>• Fastify<br>• None |
29
- | **API Layer** | • tRPC (type-safe APIs)<br>• oRPC (OpenAPI-compatible type-safe APIs)<br>• None |
30
- | **Runtime** | • Bun<br>• Node.js<br>• Cloudflare Workers<br>• None |
31
- | **Database** | • SQLite<br>• PostgreSQL<br>• MySQL<br>• MongoDB<br>• None |
32
- | **ORM** | • Drizzle (TypeScript-first)<br>• Prisma (feature-rich)<br>• Mongoose (for MongoDB)<br>• None |
33
- | **Database Setup** | • Turso (SQLite)<br>• Cloudflare D1 (SQLite)<br>• Neon (PostgreSQL)<br>• Supabase (PostgreSQL)<br>• Prisma Postgres<br>• MongoDB Atlas<br>• None (manual setup) |
34
- | **Authentication** | Better-Auth (email/password, with more options coming soon) |
35
- | **Styling** | Tailwind CSS with shadcn/ui components |
36
- | **Addons** | • PWA support<br>• Tauri (desktop applications)<br>• Starlight (documentation site)<br>• Biome (linting and formatting)<br>• Lefthook, Husky (Git hooks)<br>• Turborepo (optimized builds) |
37
- | **Examples** | • Todo app<br>• AI Chat interface (using Vercel AI SDK) |
38
- | **Developer Experience** | • Automatic Git initialization<br>• Package manager choice (npm, pnpm, bun)<br>• Automatic dependency installation |
39
-
40
18
  ## Usage
41
19
 
42
20
  ```bash
43
- Usage: create-better-t-stack [project-directory] [options]
21
+ Usage: create-better-fullstack [project-directory] [options]
44
22
 
45
23
  Options:
46
24
  -V, --version Output the version number
47
25
  -y, --yes Use default configuration
26
+ --yolo Random configuration (experimental)
48
27
  --database <type> Database type (none, sqlite, postgres, mysql, mongodb)
49
- --orm <type> ORM type (none, drizzle, prisma, mongoose)
50
- --auth Include authentication
51
- --no-auth Exclude authentication
52
- --frontend <types...> Frontend types (tanstack-router, react-router, tanstack-start, next, nuxt, svelte, solid, native-bare, native-uniwind, native-unistyles, none)
53
- --addons <types...> Additional addons (pwa, tauri, starlight, biome, lefthook, husky, turborepo, fumadocs, ultracite, oxlint, none)
28
+ --orm <type> ORM type (drizzle, prisma, mongoose, typeorm, kysely, mikroorm, sequelize, none)
29
+ --auth <type> Authentication (better-auth, clerk, nextauth, none)
30
+ --payments <type> Payments (polar, stripe, lemon-squeezy, paddle, dodo, none)
31
+ --frontend <types...> Frontend types
32
+ --backend <framework> Backend framework
33
+ --runtime <runtime> Runtime (bun, node, workers, none)
34
+ --api <type> API type (trpc, orpc, ts-rest, garph, none)
35
+ --addons <types...> Additional addons
54
36
  --examples <types...> Examples to include (todo, ai, none)
55
- --git Initialize git repository
56
- --no-git Skip git initialization
37
+ --git / --no-git Initialize git repository
57
38
  --package-manager <pm> Package manager (npm, pnpm, bun)
58
- --install Install dependencies
59
- --no-install Skip installing dependencies
60
- --db-setup <setup> Database setup (turso, d1, neon, supabase, prisma-postgres, mongodb-atlas, docker, none)
61
- --web-deploy <setup> Web deployment (workers, alchemy, none)
62
- --server-deploy <setup> Server deployment (workers, alchemy, none)
63
- --backend <framework> Backend framework (hono, express, elysia, next, convex, fastify, none)
64
- --runtime <runtime> Runtime (bun, node, workers, none)
65
- --api <type> API type (trpc, orpc, none)
39
+ --install / --no-install Install dependencies
40
+ --db-setup <setup> Database setup
66
41
  -h, --help Display help
67
42
  ```
68
43
 
69
44
  ## Examples
70
45
 
71
- Create a project with default configuration:
72
-
73
- ```bash
74
- npx create-better-t-stack --yes
75
- ```
76
-
77
- Create a project with specific options:
78
-
79
46
  ```bash
80
- npx create-better-t-stack --database postgres --orm drizzle --auth --addons pwa biome
81
- ```
47
+ # Default configuration
48
+ npx create-better-fullstack --yes
82
49
 
83
- Create a project with Elysia backend and Node.js runtime:
50
+ # With specific options
51
+ npx create-better-fullstack --database postgres --orm drizzle --auth better-auth --addons pwa biome
84
52
 
85
- ```bash
86
- npx create-better-t-stack --backend elysia --runtime node
87
- ```
53
+ # Elysia backend with Node.js
54
+ npx create-better-fullstack --backend elysia --runtime node
88
55
 
89
- Create a project with multiple frontend options (one web + one native):
90
-
91
- ```bash
92
- npx create-better-t-stack --frontend tanstack-router native-bare
56
+ # Multiple frontends (web + native)
57
+ npx create-better-fullstack --frontend tanstack-router native-bare
93
58
  ```
94
59
 
95
60
  ## Project Structure
96
61
 
97
- The created project follows a clean monorepo structure:
98
-
99
62
  ```
100
- my-better-t-app/
63
+ my-app/
101
64
  ├── apps/
102
65
  │ ├── web/ # Frontend application
103
66
  │ ├── server/ # Backend API
104
67
  │ ├── native/ # (optional) Mobile application
105
68
  │ └── docs/ # (optional) Documentation site
106
69
  ├── packages/ # Shared packages
107
- └── README.md # Auto-generated project documentation
70
+ └── README.md
108
71
  ```
109
-
110
- After project creation, you'll receive detailed instructions for next steps and additional setup requirements.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { o as createBtsCli } from "./src-CwAb8MVO.mjs";
2
+ import { o as createBtsCli } from "./src-BkBCdTQg.mjs";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.d.mts CHANGED
@@ -162,6 +162,16 @@ declare const router: {
162
162
  none: "none";
163
163
  opentelemetry: "opentelemetry";
164
164
  }>>;
165
+ cms: z.ZodOptional<z.ZodEnum<{
166
+ none: "none";
167
+ payload: "payload";
168
+ sanity: "sanity";
169
+ strapi: "strapi";
170
+ }>>;
171
+ caching: z.ZodOptional<z.ZodEnum<{
172
+ none: "none";
173
+ "upstash-redis": "upstash-redis";
174
+ }>>;
165
175
  frontend: z.ZodOptional<z.ZodArray<z.ZodEnum<{
166
176
  none: "none";
167
177
  "tanstack-router": "tanstack-router";
@@ -458,7 +468,7 @@ declare function createBtsCli(): trpc_cli0.TrpcCli;
458
468
  *
459
469
  * @example
460
470
  * ```typescript
461
- * import { create } from "create-better-t-stack";
471
+ * import { create } from "create-better-fullstack";
462
472
  *
463
473
  * const result = await create("my-app", {
464
474
  * frontend: ["tanstack-router"],
@@ -484,7 +494,7 @@ declare function builder(): Promise<void>;
484
494
  *
485
495
  * @example
486
496
  * ```typescript
487
- * import { createVirtual, EMBEDDED_TEMPLATES } from "create-better-t-stack";
497
+ * import { createVirtual, EMBEDDED_TEMPLATES } from "create-better-fullstack";
488
498
  *
489
499
  * const result = await createVirtual({
490
500
  * frontend: ["tanstack-router"],
@@ -510,7 +520,9 @@ type Animation = import__better_fullstack_types.Animation;
510
520
  type Auth = import__better_fullstack_types.Auth;
511
521
  type Backend = import__better_fullstack_types.Backend;
512
522
  type BetterTStackConfig = import__better_fullstack_types.BetterTStackConfig;
523
+ type CMS = import__better_fullstack_types.CMS;
513
524
  type CSSFramework = import__better_fullstack_types.CSSFramework;
525
+ type Caching = import__better_fullstack_types.Caching;
514
526
  type CreateInput = import__better_fullstack_types.CreateInput;
515
527
  type Database = import__better_fullstack_types.Database;
516
528
  type DatabaseSetup = import__better_fullstack_types.DatabaseSetup;
@@ -536,4 +548,4 @@ type ServerDeploy = import__better_fullstack_types.ServerDeploy;
536
548
  type Template = import__better_fullstack_types.Template;
537
549
  type UILibrary = import__better_fullstack_types.UILibrary;
538
550
  type WebDeploy = import__better_fullstack_types.WebDeploy;
539
- export { type API, type Addons, type Animation, type Auth, type Backend, type BetterTStackConfig, type CSSFramework, type CreateInput, type Database, type DatabaseSetup, type DirectoryConflict, EMBEDDED_TEMPLATES, type Ecosystem, type Effect, type Examples, type Frontend, type GeneratorOptions, type GeneratorResult, type InitResult, type Logging, type ORM, type PackageManager, type Payments, type Realtime, type Runtime, type RustApi, type RustCli, type RustFrontend, type RustLibraries, type RustOrm, type RustWebFramework, type ServerDeploy, TEMPLATE_COUNT, type Template, type UILibrary, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
551
+ export { type API, type Addons, type Animation, type Auth, type Backend, type BetterTStackConfig, type CMS, type CSSFramework, type Caching, type CreateInput, type Database, type DatabaseSetup, type DirectoryConflict, EMBEDDED_TEMPLATES, type Ecosystem, type Effect, type Examples, type Frontend, type GeneratorOptions, type GeneratorResult, type InitResult, type Logging, type ORM, type PackageManager, type Payments, type Realtime, type Runtime, type RustApi, type RustCli, type RustFrontend, type RustLibraries, type RustOrm, type RustWebFramework, type ServerDeploy, TEMPLATE_COUNT, type Template, type UILibrary, type VirtualDirectory, type VirtualFile, VirtualFileSystem, type VirtualFileTree, type VirtualNode, type WebDeploy, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-CwAb8MVO.mjs";
2
+ import { a as create, c as docs, d as sponsors, i as builder, l as generateVirtualProject, n as TEMPLATE_COUNT, o as createBtsCli, r as VirtualFileSystem, s as createVirtual, t as EMBEDDED_TEMPLATES, u as router } from "./src-BkBCdTQg.mjs";
3
3
 
4
4
  export { EMBEDDED_TEMPLATES, TEMPLATE_COUNT, VirtualFileSystem, builder, create, createBtsCli, createVirtual, docs, generateVirtualProject, router, sponsors };
@@ -1038,6 +1038,119 @@ async function getAddonsChoice(addons, frontends, auth) {
1038
1038
  return response;
1039
1039
  }
1040
1040
 
1041
+ //#endregion
1042
+ //#region src/prompts/ai.ts
1043
+ async function getAIChoice(ai) {
1044
+ if (ai !== void 0) return ai;
1045
+ const response = await navigableSelect({
1046
+ message: "Select AI SDK",
1047
+ options: [
1048
+ {
1049
+ value: "vercel-ai",
1050
+ label: "Vercel AI SDK",
1051
+ hint: "The AI Toolkit for TypeScript - supports OpenAI, Anthropic, Google, etc."
1052
+ },
1053
+ {
1054
+ value: "mastra",
1055
+ label: "Mastra",
1056
+ hint: "TypeScript-native AI agent framework with workflows"
1057
+ },
1058
+ {
1059
+ value: "voltagent",
1060
+ label: "VoltAgent",
1061
+ hint: "AI Agent framework with memory, workflows, and observability"
1062
+ },
1063
+ {
1064
+ value: "langgraph",
1065
+ label: "LangGraph.js",
1066
+ hint: "Graph-based agent orchestration with stateful workflows"
1067
+ },
1068
+ {
1069
+ value: "openai-agents",
1070
+ label: "OpenAI Agents SDK",
1071
+ hint: "Official multi-agent framework with handoffs and guardrails"
1072
+ },
1073
+ {
1074
+ value: "google-adk",
1075
+ label: "Google ADK",
1076
+ hint: "Code-first agent development kit for building AI agents"
1077
+ },
1078
+ {
1079
+ value: "modelfusion",
1080
+ label: "ModelFusion",
1081
+ hint: "Type-safe AI library for multi-provider text generation"
1082
+ },
1083
+ {
1084
+ value: "langchain",
1085
+ label: "LangChain",
1086
+ hint: "Build context-aware reasoning applications"
1087
+ },
1088
+ {
1089
+ value: "llamaindex",
1090
+ label: "LlamaIndex",
1091
+ hint: "Data framework for LLM applications"
1092
+ },
1093
+ {
1094
+ value: "none",
1095
+ label: "None",
1096
+ hint: "No AI SDK"
1097
+ }
1098
+ ],
1099
+ initialValue: "none"
1100
+ });
1101
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1102
+ return response;
1103
+ }
1104
+
1105
+ //#endregion
1106
+ //#region src/prompts/animation.ts
1107
+ async function getAnimationChoice(animation, frontends) {
1108
+ if (animation !== void 0) return animation;
1109
+ const { web } = splitFrontends(frontends);
1110
+ if (web.length === 0) return "none";
1111
+ const isReact = web.some((f) => [
1112
+ "tanstack-router",
1113
+ "react-router",
1114
+ "tanstack-start",
1115
+ "next",
1116
+ "redwood"
1117
+ ].includes(f));
1118
+ const options = [];
1119
+ if (isReact) options.push({
1120
+ value: "framer-motion",
1121
+ label: "Framer Motion",
1122
+ hint: "Production-ready declarative animations for React"
1123
+ }, {
1124
+ value: "react-spring",
1125
+ label: "React Spring",
1126
+ hint: "Physics-based animations for fluid interactions"
1127
+ });
1128
+ options.push({
1129
+ value: "gsap",
1130
+ label: "GSAP",
1131
+ hint: "Professional-grade animation engine for the web"
1132
+ }, {
1133
+ value: "auto-animate",
1134
+ label: "Auto Animate",
1135
+ hint: "Zero-config, drop-in animation utility"
1136
+ }, {
1137
+ value: "lottie",
1138
+ label: "Lottie",
1139
+ hint: "Render After Effects animations natively"
1140
+ }, {
1141
+ value: "none",
1142
+ label: "None",
1143
+ hint: "Skip animation library setup"
1144
+ });
1145
+ const response = await navigableSelect({
1146
+ message: "Select animation library",
1147
+ options,
1148
+ initialValue: "none"
1149
+ });
1150
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1151
+ return response;
1152
+ }
1153
+
1041
1154
  //#endregion
1042
1155
  //#region src/prompts/api.ts
1043
1156
  async function getApiChoice(Api, frontend, backend, astroIntegration) {
@@ -1226,6 +1339,63 @@ async function getBackendFrameworkChoice(backendFramework, frontends) {
1226
1339
  return response;
1227
1340
  }
1228
1341
 
1342
+ //#endregion
1343
+ //#region src/prompts/caching.ts
1344
+ async function getCachingChoice(caching, backend) {
1345
+ if (caching !== void 0) return caching;
1346
+ if (backend === "none" || backend === "convex") return "none";
1347
+ const response = await navigableSelect({
1348
+ message: "Select caching solution",
1349
+ options: [{
1350
+ value: "upstash-redis",
1351
+ label: "Upstash Redis",
1352
+ hint: "Serverless Redis with REST API for edge and serverless"
1353
+ }, {
1354
+ value: "none",
1355
+ label: "None",
1356
+ hint: "Skip caching layer setup"
1357
+ }],
1358
+ initialValue: "none"
1359
+ });
1360
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1361
+ return response;
1362
+ }
1363
+
1364
+ //#endregion
1365
+ //#region src/prompts/cms.ts
1366
+ async function getCMSChoice(cms, backend) {
1367
+ if (cms !== void 0) return cms;
1368
+ if (backend === "none" || backend === "convex") return "none";
1369
+ const response = await navigableSelect({
1370
+ message: "Select headless CMS",
1371
+ options: [
1372
+ {
1373
+ value: "payload",
1374
+ label: "Payload",
1375
+ hint: "TypeScript-first headless CMS with Next.js integration"
1376
+ },
1377
+ {
1378
+ value: "sanity",
1379
+ label: "Sanity",
1380
+ hint: "Real-time collaborative CMS with schema-as-code"
1381
+ },
1382
+ {
1383
+ value: "strapi",
1384
+ label: "Strapi",
1385
+ hint: "Open-source headless CMS with admin panel"
1386
+ },
1387
+ {
1388
+ value: "none",
1389
+ label: "None",
1390
+ hint: "Skip headless CMS setup"
1391
+ }
1392
+ ],
1393
+ initialValue: "none"
1394
+ });
1395
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1396
+ return response;
1397
+ }
1398
+
1229
1399
  //#endregion
1230
1400
  //#region src/prompts/css-framework.ts
1231
1401
  const CSS_FRAMEWORK_OPTIONS = {
@@ -1495,6 +1665,98 @@ async function getExamplesChoice(examples, database, frontends, backend, api) {
1495
1665
  return response;
1496
1666
  }
1497
1667
 
1668
+ //#endregion
1669
+ //#region src/prompts/file-upload.ts
1670
+ async function getFileUploadChoice(fileUpload, backend) {
1671
+ if (fileUpload !== void 0) return fileUpload;
1672
+ if (backend === "none" || backend === "convex") return "none";
1673
+ const response = await navigableSelect({
1674
+ message: "Select file upload solution",
1675
+ options: [
1676
+ {
1677
+ value: "uploadthing",
1678
+ label: "UploadThing",
1679
+ hint: "TypeScript-first file uploads with built-in validation"
1680
+ },
1681
+ {
1682
+ value: "filepond",
1683
+ label: "FilePond",
1684
+ hint: "Flexible file upload with image preview and drag & drop"
1685
+ },
1686
+ {
1687
+ value: "uppy",
1688
+ label: "Uppy",
1689
+ hint: "Modular file uploader with resumable uploads and plugins"
1690
+ },
1691
+ {
1692
+ value: "none",
1693
+ label: "None",
1694
+ hint: "Skip file upload integration"
1695
+ }
1696
+ ],
1697
+ initialValue: "none"
1698
+ });
1699
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1700
+ return response;
1701
+ }
1702
+
1703
+ //#endregion
1704
+ //#region src/prompts/forms.ts
1705
+ async function getFormsChoice(forms, frontends) {
1706
+ if (forms !== void 0) return forms;
1707
+ const { web } = splitFrontends(frontends);
1708
+ if (web.length === 0) return "none";
1709
+ const isReact = web.some((f) => [
1710
+ "tanstack-router",
1711
+ "react-router",
1712
+ "tanstack-start",
1713
+ "next",
1714
+ "redwood"
1715
+ ].includes(f));
1716
+ const isSolid = web.includes("solid");
1717
+ const isQwik = web.includes("qwik");
1718
+ const options = [];
1719
+ if (isReact) options.push({
1720
+ value: "react-hook-form",
1721
+ label: "React Hook Form",
1722
+ hint: "Performant, flexible form validation library"
1723
+ }, {
1724
+ value: "formik",
1725
+ label: "Formik",
1726
+ hint: "Popular form state management with Yup validation"
1727
+ }, {
1728
+ value: "final-form",
1729
+ label: "Final Form",
1730
+ hint: "Framework-agnostic form state management"
1731
+ }, {
1732
+ value: "conform",
1733
+ label: "Conform",
1734
+ hint: "Progressive enhancement forms with Zod validation"
1735
+ });
1736
+ options.push({
1737
+ value: "tanstack-form",
1738
+ label: "TanStack Form",
1739
+ hint: "Fully-typed, framework-agnostic form library"
1740
+ });
1741
+ if (isSolid || isQwik) options.push({
1742
+ value: "modular-forms",
1743
+ label: "Modular Forms",
1744
+ hint: "Type-safe forms for Solid and Qwik (3KB bundle)"
1745
+ });
1746
+ options.push({
1747
+ value: "none",
1748
+ label: "None",
1749
+ hint: "Build custom form handling"
1750
+ });
1751
+ const response = await navigableSelect({
1752
+ message: "Select form library",
1753
+ options,
1754
+ initialValue: isReact ? "react-hook-form" : "tanstack-form"
1755
+ });
1756
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1757
+ return response;
1758
+ }
1759
+
1498
1760
  //#endregion
1499
1761
  //#region src/prompts/frontend.ts
1500
1762
  async function getFrontendChoice(frontendOptions, backend, auth) {
@@ -1637,6 +1899,76 @@ async function getinstallChoice(install) {
1637
1899
  return response;
1638
1900
  }
1639
1901
 
1902
+ //#endregion
1903
+ //#region src/prompts/job-queue.ts
1904
+ async function getJobQueueChoice(jobQueue, backend) {
1905
+ if (jobQueue !== void 0) return jobQueue;
1906
+ if (backend === "none" || backend === "convex") return "none";
1907
+ const response = await navigableSelect({
1908
+ message: "Select job queue solution",
1909
+ options: [
1910
+ {
1911
+ value: "bullmq",
1912
+ label: "BullMQ",
1913
+ hint: "Redis-backed job queue for background tasks and scheduling"
1914
+ },
1915
+ {
1916
+ value: "trigger-dev",
1917
+ label: "Trigger.dev",
1918
+ hint: "Background jobs as code with serverless execution"
1919
+ },
1920
+ {
1921
+ value: "inngest",
1922
+ label: "Inngest",
1923
+ hint: "Event-driven functions with built-in queuing and scheduling"
1924
+ },
1925
+ {
1926
+ value: "temporal",
1927
+ label: "Temporal",
1928
+ hint: "Durable workflow orchestration for reliable distributed systems"
1929
+ },
1930
+ {
1931
+ value: "none",
1932
+ label: "None",
1933
+ hint: "Skip job queue/background worker setup"
1934
+ }
1935
+ ],
1936
+ initialValue: "none"
1937
+ });
1938
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1939
+ return response;
1940
+ }
1941
+
1942
+ //#endregion
1943
+ //#region src/prompts/logging.ts
1944
+ async function getLoggingChoice(logging, backend) {
1945
+ if (logging !== void 0) return logging;
1946
+ if (backend === "none" || backend === "convex") return "none";
1947
+ const response = await navigableSelect({
1948
+ message: "Select logging framework",
1949
+ options: [
1950
+ {
1951
+ value: "pino",
1952
+ label: "Pino",
1953
+ hint: "Fast JSON logger with minimal overhead"
1954
+ },
1955
+ {
1956
+ value: "winston",
1957
+ label: "Winston",
1958
+ hint: "Flexible logging library with multiple transports"
1959
+ },
1960
+ {
1961
+ value: "none",
1962
+ label: "None",
1963
+ hint: "Skip logging framework setup"
1964
+ }
1965
+ ],
1966
+ initialValue: "none"
1967
+ });
1968
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1969
+ return response;
1970
+ }
1971
+
1640
1972
  //#endregion
1641
1973
  //#region src/prompts/navigable-group.ts
1642
1974
  /**
@@ -1694,6 +2026,28 @@ async function navigableGroup(prompts, opts) {
1694
2026
  return results;
1695
2027
  }
1696
2028
 
2029
+ //#endregion
2030
+ //#region src/prompts/observability.ts
2031
+ async function getObservabilityChoice(observability, backend) {
2032
+ if (observability !== void 0) return observability;
2033
+ if (backend === "none" || backend === "convex") return "none";
2034
+ const response = await navigableSelect({
2035
+ message: "Select observability solution",
2036
+ options: [{
2037
+ value: "opentelemetry",
2038
+ label: "OpenTelemetry",
2039
+ hint: "Observability framework for traces, metrics, and logs"
2040
+ }, {
2041
+ value: "none",
2042
+ label: "None",
2043
+ hint: "Skip observability/tracing setup"
2044
+ }],
2045
+ initialValue: "none"
2046
+ });
2047
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
2048
+ return response;
2049
+ }
2050
+
1697
2051
  //#endregion
1698
2052
  //#region src/prompts/orm.ts
1699
2053
  const ormOptions = {
@@ -1805,6 +2159,56 @@ async function getPaymentsChoice(payments, auth, backend, frontends) {
1805
2159
  return response;
1806
2160
  }
1807
2161
 
2162
+ //#endregion
2163
+ //#region src/prompts/realtime.ts
2164
+ async function getRealtimeChoice(realtime, backend) {
2165
+ if (realtime !== void 0) return realtime;
2166
+ if (backend === "none" || backend === "convex") return "none";
2167
+ const response = await navigableSelect({
2168
+ message: "Select real-time solution",
2169
+ options: [
2170
+ {
2171
+ value: "socket-io",
2172
+ label: "Socket.IO",
2173
+ hint: "Real-time bidirectional communication with fallbacks"
2174
+ },
2175
+ {
2176
+ value: "partykit",
2177
+ label: "PartyKit",
2178
+ hint: "Edge-native multiplayer infrastructure on Cloudflare"
2179
+ },
2180
+ {
2181
+ value: "ably",
2182
+ label: "Ably",
2183
+ hint: "Real-time messaging platform with pub/sub and presence"
2184
+ },
2185
+ {
2186
+ value: "pusher",
2187
+ label: "Pusher",
2188
+ hint: "Real-time communication APIs with channels and events"
2189
+ },
2190
+ {
2191
+ value: "liveblocks",
2192
+ label: "Liveblocks",
2193
+ hint: "Collaboration infrastructure for multiplayer experiences"
2194
+ },
2195
+ {
2196
+ value: "yjs",
2197
+ label: "Y.js",
2198
+ hint: "CRDT library for real-time collaboration with conflict-free sync"
2199
+ },
2200
+ {
2201
+ value: "none",
2202
+ label: "None",
2203
+ hint: "Skip real-time/WebSocket integration"
2204
+ }
2205
+ ],
2206
+ initialValue: "none"
2207
+ });
2208
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
2209
+ return response;
2210
+ }
2211
+
1808
2212
  //#endregion
1809
2213
  //#region src/prompts/runtime.ts
1810
2214
  async function getRuntimeChoice(runtime, backend) {
@@ -1843,6 +2247,115 @@ async function getServerDeploymentChoice(deployment, runtime, backend, _webDeplo
1843
2247
  return "none";
1844
2248
  }
1845
2249
 
2250
+ //#endregion
2251
+ //#region src/prompts/state-management.ts
2252
+ async function getStateManagementChoice(stateManagement, frontends) {
2253
+ if (stateManagement !== void 0) return stateManagement;
2254
+ const { web } = splitFrontends(frontends);
2255
+ if (web.length === 0) return "none";
2256
+ const isReact = web.some((f) => [
2257
+ "tanstack-router",
2258
+ "react-router",
2259
+ "tanstack-start",
2260
+ "next",
2261
+ "redwood"
2262
+ ].includes(f));
2263
+ const options = [];
2264
+ if (isReact) options.push({
2265
+ value: "zustand",
2266
+ label: "Zustand",
2267
+ hint: "Lightweight state management with simple API"
2268
+ }, {
2269
+ value: "jotai",
2270
+ label: "Jotai",
2271
+ hint: "Primitive and flexible atomic state"
2272
+ }, {
2273
+ value: "redux-toolkit",
2274
+ label: "Redux Toolkit",
2275
+ hint: "Enterprise-standard state with excellent TS support"
2276
+ }, {
2277
+ value: "valtio",
2278
+ label: "Valtio",
2279
+ hint: "Proxy-based state management"
2280
+ }, {
2281
+ value: "legend-state",
2282
+ label: "Legend State",
2283
+ hint: "High-performance observable state for React"
2284
+ }, {
2285
+ value: "mobx",
2286
+ label: "MobX",
2287
+ hint: "Observable-based reactive state management"
2288
+ });
2289
+ options.push({
2290
+ value: "nanostores",
2291
+ label: "Nanostores",
2292
+ hint: "Tiny state manager (1KB) for all frameworks"
2293
+ }, {
2294
+ value: "xstate",
2295
+ label: "XState",
2296
+ hint: "State machines and statecharts for complex logic"
2297
+ }, {
2298
+ value: "tanstack-store",
2299
+ label: "TanStack Store",
2300
+ hint: "Framework-agnostic store powering TanStack ecosystem"
2301
+ }, {
2302
+ value: "none",
2303
+ label: "None",
2304
+ hint: "Skip state management setup"
2305
+ });
2306
+ const response = await navigableSelect({
2307
+ message: "Select state management",
2308
+ options,
2309
+ initialValue: "none"
2310
+ });
2311
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
2312
+ return response;
2313
+ }
2314
+
2315
+ //#endregion
2316
+ //#region src/prompts/testing.ts
2317
+ async function getTestingChoice(testing) {
2318
+ if (testing !== void 0) return testing;
2319
+ const response = await navigableSelect({
2320
+ message: "Select testing framework",
2321
+ options: [
2322
+ {
2323
+ value: "vitest",
2324
+ label: "Vitest",
2325
+ hint: "Blazing fast Vite-native unit test framework"
2326
+ },
2327
+ {
2328
+ value: "vitest-playwright",
2329
+ label: "Vitest + Playwright",
2330
+ hint: "Both unit and E2E testing for complete coverage"
2331
+ },
2332
+ {
2333
+ value: "playwright",
2334
+ label: "Playwright",
2335
+ hint: "End-to-end testing framework by Microsoft"
2336
+ },
2337
+ {
2338
+ value: "jest",
2339
+ label: "Jest",
2340
+ hint: "Classic testing framework with wide ecosystem"
2341
+ },
2342
+ {
2343
+ value: "cypress",
2344
+ label: "Cypress",
2345
+ hint: "E2E testing with time travel debugging"
2346
+ },
2347
+ {
2348
+ value: "none",
2349
+ label: "None",
2350
+ hint: "Skip testing framework setup"
2351
+ }
2352
+ ],
2353
+ initialValue: "vitest"
2354
+ });
2355
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
2356
+ return response;
2357
+ }
2358
+
1846
2359
  //#endregion
1847
2360
  //#region src/prompts/ui-library.ts
1848
2361
  const UI_LIBRARY_OPTIONS = {
@@ -1915,6 +2428,60 @@ async function getUILibraryChoice(uiLibrary, frontends) {
1915
2428
  return selected;
1916
2429
  }
1917
2430
 
2431
+ //#endregion
2432
+ //#region src/prompts/validation.ts
2433
+ async function getValidationChoice(validation) {
2434
+ if (validation !== void 0) return validation;
2435
+ const response = await navigableSelect({
2436
+ message: "Select validation library",
2437
+ options: [
2438
+ {
2439
+ value: "zod",
2440
+ label: "Zod",
2441
+ hint: "TypeScript-first schema validation (recommended)"
2442
+ },
2443
+ {
2444
+ value: "valibot",
2445
+ label: "Valibot",
2446
+ hint: "Smaller bundle alternative to Zod (~1KB)"
2447
+ },
2448
+ {
2449
+ value: "arktype",
2450
+ label: "ArkType",
2451
+ hint: "TypeScript-first validation, 2-4x faster than Zod"
2452
+ },
2453
+ {
2454
+ value: "typebox",
2455
+ label: "TypeBox",
2456
+ hint: "JSON Schema type builder for TypeScript"
2457
+ },
2458
+ {
2459
+ value: "typia",
2460
+ label: "Typia",
2461
+ hint: "Super-fast validation via compile-time transform"
2462
+ },
2463
+ {
2464
+ value: "runtypes",
2465
+ label: "Runtypes",
2466
+ hint: "Runtime type validation with composable validators"
2467
+ },
2468
+ {
2469
+ value: "effect-schema",
2470
+ label: "@effect/schema",
2471
+ hint: "Effect ecosystem schema validation with powerful transformations"
2472
+ },
2473
+ {
2474
+ value: "none",
2475
+ label: "None",
2476
+ hint: "Use Zod internally only (no additional library)"
2477
+ }
2478
+ ],
2479
+ initialValue: "zod"
2480
+ });
2481
+ if (isCancel$1(response)) return exitCancelled("Operation cancelled");
2482
+ return response;
2483
+ }
2484
+
1918
2485
  //#endregion
1919
2486
  //#region src/prompts/web-deploy.ts
1920
2487
  function hasWebFrontend(frontends) {
@@ -1980,6 +2547,19 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
1980
2547
  dbSetup: ({ results }) => getDBSetupChoice(results.database ?? "none", flags.dbSetup, results.orm, results.backend, results.runtime),
1981
2548
  webDeploy: ({ results }) => getDeploymentChoice(flags.webDeploy, results.runtime, results.backend, results.frontend),
1982
2549
  serverDeploy: ({ results }) => getServerDeploymentChoice(flags.serverDeploy, results.runtime, results.backend, results.webDeploy),
2550
+ ai: () => getAIChoice(flags.ai),
2551
+ validation: () => getValidationChoice(flags.validation),
2552
+ forms: ({ results }) => getFormsChoice(flags.forms, results.frontend),
2553
+ stateManagement: ({ results }) => getStateManagementChoice(flags.stateManagement, results.frontend),
2554
+ animation: ({ results }) => getAnimationChoice(flags.animation, results.frontend),
2555
+ testing: () => getTestingChoice(flags.testing),
2556
+ realtime: ({ results }) => getRealtimeChoice(flags.realtime, results.backend),
2557
+ jobQueue: ({ results }) => getJobQueueChoice(flags.jobQueue, results.backend),
2558
+ fileUpload: ({ results }) => getFileUploadChoice(flags.fileUpload, results.backend),
2559
+ logging: ({ results }) => getLoggingChoice(flags.logging, results.backend),
2560
+ observability: ({ results }) => getObservabilityChoice(flags.observability, results.backend),
2561
+ cms: ({ results }) => getCMSChoice(flags.cms, results.backend),
2562
+ caching: ({ results }) => getCachingChoice(flags.caching, results.backend),
1983
2563
  git: () => getGitChoice(flags.git),
1984
2564
  packageManager: () => getPackageManagerChoice(flags.packageManager),
1985
2565
  install: () => getinstallChoice(flags.install)
@@ -2009,19 +2589,19 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
2009
2589
  api: result.api,
2010
2590
  webDeploy: result.webDeploy,
2011
2591
  serverDeploy: result.serverDeploy,
2012
- ai: flags.ai ?? "none",
2013
- stateManagement: flags.stateManagement ?? "none",
2014
- validation: flags.validation ?? "zod",
2015
- forms: flags.forms ?? "react-hook-form",
2016
- testing: flags.testing ?? "vitest",
2017
- realtime: flags.realtime ?? "none",
2018
- jobQueue: flags.jobQueue ?? "none",
2019
- animation: flags.animation ?? "none",
2020
- fileUpload: flags.fileUpload ?? "none",
2021
- logging: flags.logging ?? "none",
2022
- observability: flags.observability ?? "none",
2023
- cms: flags.cms ?? "none",
2024
- caching: flags.caching ?? "none",
2592
+ ai: result.ai,
2593
+ stateManagement: result.stateManagement,
2594
+ validation: result.validation,
2595
+ forms: result.forms,
2596
+ testing: result.testing,
2597
+ realtime: result.realtime,
2598
+ jobQueue: result.jobQueue,
2599
+ animation: result.animation,
2600
+ fileUpload: result.fileUpload,
2601
+ logging: result.logging,
2602
+ observability: result.observability,
2603
+ cms: result.cms,
2604
+ caching: result.caching,
2025
2605
  ecosystem: flags.ecosystem ?? "typescript",
2026
2606
  rustWebFramework: flags.rustWebFramework ?? "none",
2027
2607
  rustFrontend: flags.rustFrontend ?? "none",
@@ -2099,7 +2679,7 @@ const getLatestCLIVersion = () => {
2099
2679
  */
2100
2680
  function isTelemetryEnabled() {
2101
2681
  const BTS_TELEMETRY_DISABLED = process.env.BTS_TELEMETRY_DISABLED;
2102
- const BTS_TELEMETRY = "0";
2682
+ const BTS_TELEMETRY = "1";
2103
2683
  if (BTS_TELEMETRY_DISABLED !== void 0) return BTS_TELEMETRY_DISABLED !== "1";
2104
2684
  if (BTS_TELEMETRY !== void 0) return BTS_TELEMETRY === "1";
2105
2685
  return true;
@@ -2193,11 +2773,11 @@ function generateReproducibleCommand(config) {
2193
2773
  flags.push(config.git ? "--git" : "--no-git");
2194
2774
  flags.push(`--package-manager ${config.packageManager}`);
2195
2775
  flags.push(config.install ? "--install" : "--no-install");
2196
- let baseCommand = "npx create-better-t-stack@latest";
2776
+ let baseCommand = "npx create-better-fullstack@latest";
2197
2777
  const pkgManager = config.packageManager;
2198
- if (pkgManager === "bun") baseCommand = "bun create better-t-stack@latest";
2199
- else if (pkgManager === "pnpm") baseCommand = "pnpm create better-t-stack@latest";
2200
- else if (pkgManager === "npm") baseCommand = "npx create-better-t-stack@latest";
2778
+ if (pkgManager === "bun") baseCommand = "bun create better-fullstack@latest";
2779
+ else if (pkgManager === "pnpm") baseCommand = "pnpm create better-fullstack@latest";
2780
+ else if (pkgManager === "npm") baseCommand = "npx create-better-fullstack@latest";
2201
2781
  const projectPathArg = config.relativePath ? ` ${config.relativePath}` : "";
2202
2782
  return `${baseCommand}${projectPathArg} ${flags.join(" ")}`;
2203
2783
  }
@@ -2295,31 +2875,24 @@ const TITLE_TEXT = `
2295
2875
  ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║
2296
2876
  ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
2297
2877
 
2298
- ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗
2299
- ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝
2300
- ██║ ███████╗ ██║ ███████║██║ █████╔╝
2301
- ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗
2302
- ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗
2303
- ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
2878
+ ███████╗██╗ ██╗██╗ ██╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗
2879
+ ██╔════╝██║ ██║██║ ██║ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝
2880
+ █████╗ ██║ ██║██║ ██║ ███████╗ ██║ ███████║██║ █████╔╝
2881
+ ██╔══╝ ██║ ██║██║ ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗
2882
+ ██║ ╚██████╔╝███████╗███████╗███████║ ██║ ██║ ██║╚██████╗██║ ██╗
2883
+ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
2304
2884
  `;
2305
- const catppuccinTheme = {
2306
- pink: "#F5C2E7",
2307
- mauve: "#CBA6F7",
2308
- red: "#F38BA8",
2309
- maroon: "#E78284",
2310
- peach: "#FAB387",
2311
- yellow: "#F9E2AF",
2312
- green: "#A6E3A1",
2313
- teal: "#94E2D5",
2314
- sky: "#89DCEB",
2315
- sapphire: "#74C7EC",
2316
- lavender: "#B4BEFE"
2885
+ const monochromeTheme = {
2886
+ white: "#FFFFFF",
2887
+ lightGray: "#E5E5E5",
2888
+ gray: "#A3A3A3",
2889
+ darkGray: "#737373"
2317
2890
  };
2318
2891
  const renderTitle = () => {
2319
2892
  const terminalWidth = process.stdout.columns || 80;
2320
2893
  const titleLines = TITLE_TEXT.split("\n");
2321
- if (terminalWidth < Math.max(...titleLines.map((line) => line.length))) console.log(gradient(Object.values(catppuccinTheme)).multiline(`Better Fullstack`));
2322
- else console.log(gradient(Object.values(catppuccinTheme)).multiline(TITLE_TEXT));
2894
+ if (terminalWidth < Math.max(...titleLines.map((line) => line.length))) console.log(gradient(Object.values(monochromeTheme)).multiline(`Better Fullstack`));
2895
+ else console.log(gradient(Object.values(monochromeTheme)).multiline(TITLE_TEXT));
2323
2896
  };
2324
2897
 
2325
2898
  //#endregion
@@ -2468,9 +3041,9 @@ function validateDatabaseOrmAuth(cfg, flags) {
2468
3041
  const has = (k) => flags ? flags.has(k) : true;
2469
3042
  if (has("orm") && has("database") && orm === "mongoose" && db !== "mongodb") exitWithError("Mongoose ORM requires MongoDB database. Please use '--database mongodb' or choose a different ORM.");
2470
3043
  if (has("orm") && has("database") && orm === "drizzle" && db === "mongodb") exitWithError("Drizzle ORM does not support MongoDB. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2471
- if (has("orm") && has("database") && orm === "typeorm" && db === "mongodb") exitWithError("TypeORM does not support MongoDB in Better-T-Stack. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
3044
+ if (has("orm") && has("database") && orm === "typeorm" && db === "mongodb") exitWithError("TypeORM does not support MongoDB in Better Fullstack. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2472
3045
  if (has("orm") && has("database") && orm === "kysely" && db === "mongodb") exitWithError("Kysely does not support MongoDB. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2473
- if (has("orm") && has("database") && orm === "mikroorm" && db === "mongodb") exitWithError("MikroORM does not support MongoDB in Better-T-Stack. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
3046
+ if (has("orm") && has("database") && orm === "mikroorm" && db === "mongodb") exitWithError("MikroORM does not support MongoDB in Better Fullstack. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2474
3047
  if (has("orm") && has("database") && orm === "sequelize" && db === "mongodb") exitWithError("Sequelize does not support MongoDB. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2475
3048
  if (has("database") && has("orm") && db === "mongodb" && orm && orm !== "mongoose" && orm !== "prisma" && orm !== "none") exitWithError("MongoDB database requires Mongoose or Prisma ORM. Please use '--orm mongoose' or '--orm prisma' or choose a different database.");
2476
3049
  if (has("database") && has("orm") && db && db !== "none" && orm === "none") exitWithError("Database selection requires an ORM. Please choose '--orm drizzle', '--orm prisma', '--orm typeorm', '--orm kysely', '--orm mikroorm', '--orm sequelize', or '--orm mongoose'.");
@@ -2781,7 +3354,7 @@ async function writeBtsConfig(projectConfig) {
2781
3354
  rustLibraries: projectConfig.rustLibraries
2782
3355
  };
2783
3356
  const baseContent = {
2784
- $schema: "https://r2.better-t-stack.dev/schema.json",
3357
+ $schema: "https://better-fullstack-web.vercel.app/schema.json",
2785
3358
  version: btsConfig.version,
2786
3359
  createdAt: btsConfig.createdAt,
2787
3360
  ecosystem: btsConfig.ecosystem,
@@ -2828,7 +3401,7 @@ async function writeBtsConfig(projectConfig) {
2828
3401
  eol: "\n"
2829
3402
  });
2830
3403
  configContent = JSONC.applyEdits(configContent, formatResult);
2831
- const finalContent = `// Better-T-Stack configuration file
3404
+ const finalContent = `// Better Fullstack configuration file
2832
3405
  // safe to delete
2833
3406
 
2834
3407
  ${configContent}`;
@@ -5079,7 +5652,7 @@ async function openUrl(url) {
5079
5652
 
5080
5653
  //#endregion
5081
5654
  //#region src/utils/sponsors.ts
5082
- const SPONSORS_JSON_URL = "https://sponsors.better-t-stack.dev/sponsors.json";
5655
+ const SPONSORS_JSON_URL = "https://better-fullstack-web.vercel.app/sponsors.json";
5083
5656
  async function fetchSponsors(url = SPONSORS_JSON_URL) {
5084
5657
  const s = spinner();
5085
5658
  s.start("Fetching sponsors…");
@@ -5148,6 +5721,8 @@ const router = os.router({
5148
5721
  animation: types_exports.AnimationSchema.optional(),
5149
5722
  logging: types_exports.LoggingSchema.optional(),
5150
5723
  observability: types_exports.ObservabilitySchema.optional(),
5724
+ cms: types_exports.CMSSchema.optional().describe("Headless CMS solution"),
5725
+ caching: types_exports.CachingSchema.optional().describe("Caching solution"),
5151
5726
  frontend: z.array(types_exports.FrontendSchema).optional(),
5152
5727
  addons: z.array(types_exports.AddonsSchema).optional(),
5153
5728
  examples: z.array(types_exports.ExamplesSchema).optional(),
@@ -5190,7 +5765,7 @@ const router = os.router({
5190
5765
  }
5191
5766
  }),
5192
5767
  docs: os.meta({ description: "Open Better Fullstack documentation" }).handler(async () => {
5193
- const DOCS_URL = "https://better-t-stack.dev/docs";
5768
+ const DOCS_URL = "https://better-fullstack-web.vercel.app/docs";
5194
5769
  try {
5195
5770
  await openUrl(DOCS_URL);
5196
5771
  log.success(pc.blue("Opened docs in your default browser."));
@@ -5199,7 +5774,7 @@ const router = os.router({
5199
5774
  }
5200
5775
  }),
5201
5776
  builder: os.meta({ description: "Open the web-based stack builder" }).handler(async () => {
5202
- const BUILDER_URL = "https://better-t-stack.dev/new";
5777
+ const BUILDER_URL = "https://better-fullstack-web.vercel.app/new";
5203
5778
  try {
5204
5779
  await openUrl(BUILDER_URL);
5205
5780
  log.success(pc.blue("Opened builder in your default browser."));
@@ -5212,7 +5787,7 @@ const caller = createRouterClient(router, { context: {} });
5212
5787
  function createBtsCli() {
5213
5788
  return createCli({
5214
5789
  router,
5215
- name: "create-better-t-stack",
5790
+ name: "create-better-fullstack",
5216
5791
  version: getLatestCLIVersion()
5217
5792
  });
5218
5793
  }
@@ -5222,7 +5797,7 @@ function createBtsCli() {
5222
5797
  *
5223
5798
  * @example
5224
5799
  * ```typescript
5225
- * import { create } from "create-better-t-stack";
5800
+ * import { create } from "create-better-fullstack";
5226
5801
  *
5227
5802
  * const result = await create("my-app", {
5228
5803
  * frontend: ["tanstack-router"],
@@ -5277,7 +5852,7 @@ async function builder() {
5277
5852
  *
5278
5853
  * @example
5279
5854
  * ```typescript
5280
- * import { createVirtual, EMBEDDED_TEMPLATES } from "create-better-t-stack";
5855
+ * import { createVirtual, EMBEDDED_TEMPLATES } from "create-better-fullstack";
5281
5856
  *
5282
5857
  * const result = await createVirtual({
5283
5858
  * frontend: ["tanstack-router"],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "1.0.0-canary.c9b74dcc",
4
- "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
3
+ "version": "1.1.0",
4
+ "description": "A CLI-first toolkit for building Full Stack applications. Skip the configuration. Ship the code.",
5
5
  "keywords": [
6
6
  "better-auth",
7
7
  "better-fullstack",
@@ -28,7 +28,7 @@
28
28
  "type-safety",
29
29
  "typescript"
30
30
  ],
31
- "homepage": "https://github.com/Marve10s/Better-Fullstack",
31
+ "homepage": "https://better-fullstack-web.vercel.app/",
32
32
  "license": "MIT",
33
33
  "author": "Marve10s",
34
34
  "repository": {
@@ -72,8 +72,8 @@
72
72
  "prepublishOnly": "npm run build"
73
73
  },
74
74
  "dependencies": {
75
- "@better-fullstack/template-generator": "1.0.0-canary.c9b74dcc",
76
- "@better-fullstack/types": "1.0.0-canary.c9b74dcc",
75
+ "@better-fullstack/template-generator": "^1.1.0",
76
+ "@better-fullstack/types": "^1.1.0",
77
77
  "@clack/core": "^0.5.0",
78
78
  "@clack/prompts": "^1.0.0-alpha.8",
79
79
  "@orpc/server": "^1.13.0",