create-better-fullstack 1.6.2 → 1.6.3

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,6 +1,6 @@
1
1
  # Better Fullstack
2
2
 
3
- Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options — the CLI wires everything together.
3
+ Scaffold production-ready fullstack apps in seconds. Pick your stack from 425 options — the CLI wires everything together.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -31,7 +31,7 @@ Configure your stack visually — pick every option from a UI, preview your choi
31
31
 
32
32
  ## Features
33
33
 
34
- - **424 options** — frontend, backend, database, auth, payments, AI, DevOps, and more
34
+ - **425 options** — frontend, backend, database, auth, payments, AI, DevOps, and more
35
35
  - **5 ecosystems** — TypeScript, Rust, Python, Go, Java
36
36
  - **Visual builder** — configure your stack in the browser
37
37
  - **Wired for you** — every picked integration is preconfigured and working out of the box
package/dist/index.d.mts CHANGED
@@ -148,6 +148,7 @@ declare const router: {
148
148
  langchain: "langchain";
149
149
  llamaindex: "llamaindex";
150
150
  "tanstack-ai": "tanstack-ai";
151
+ "ai-cli": "ai-cli";
151
152
  }>>;
152
153
  realtime: z.ZodOptional<z.ZodEnum<{
153
154
  none: "none";
@@ -273,6 +274,7 @@ declare const router: {
273
274
  "tanstack-virtual": "tanstack-virtual";
274
275
  "tanstack-db": "tanstack-db";
275
276
  "tanstack-pacer": "tanstack-pacer";
277
+ "docker-compose": "docker-compose";
276
278
  }>>>;
277
279
  examples: z.ZodOptional<z.ZodArray<z.ZodEnum<{
278
280
  none: "none";
@@ -638,7 +640,7 @@ declare const router: {
638
640
  backend: "none" | "hono" | "express" | "fastify" | "elysia" | "fets" | "nestjs" | "adonisjs" | "nitro" | "encore" | "convex" | "self";
639
641
  runtime: "none" | "bun" | "node" | "workers";
640
642
  frontend: ("none" | "tanstack-router" | "react-router" | "react-vite" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "solid-start" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
641
- addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer")[];
643
+ addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer" | "docker-compose")[];
642
644
  examples: ("ai" | "none" | "chat-sdk" | "tanstack-showcase")[];
643
645
  auth: "none" | "better-auth" | "go-better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
644
646
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
@@ -650,7 +652,7 @@ declare const router: {
650
652
  api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
651
653
  webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
652
654
  serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
653
- ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
655
+ ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai" | "ai-cli";
654
656
  effect: "effect" | "none" | "effect-full";
655
657
  stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
656
658
  forms: "none" | "tanstack-form" | "react-hook-form" | "formik" | "final-form" | "conform" | "modular-forms";
@@ -734,7 +736,7 @@ declare const router: {
734
736
  backend: "none" | "hono" | "express" | "fastify" | "elysia" | "fets" | "nestjs" | "adonisjs" | "nitro" | "encore" | "convex" | "self";
735
737
  runtime: "none" | "bun" | "node" | "workers";
736
738
  frontend: ("none" | "tanstack-router" | "react-router" | "react-vite" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "solid-start" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
737
- addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer")[];
739
+ addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer" | "docker-compose")[];
738
740
  examples: ("ai" | "none" | "chat-sdk" | "tanstack-showcase")[];
739
741
  auth: "none" | "better-auth" | "go-better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
740
742
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
@@ -746,7 +748,7 @@ declare const router: {
746
748
  api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
747
749
  webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
748
750
  serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
749
- ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
751
+ ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai" | "ai-cli";
750
752
  effect: "effect" | "none" | "effect-full";
751
753
  stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
752
754
  forms: "none" | "tanstack-form" | "react-hook-form" | "formik" | "final-form" | "conform" | "modular-forms";
@@ -843,7 +845,7 @@ declare const router: {
843
845
  backend: "none" | "hono" | "express" | "fastify" | "elysia" | "fets" | "nestjs" | "adonisjs" | "nitro" | "encore" | "convex" | "self";
844
846
  runtime: "none" | "bun" | "node" | "workers";
845
847
  frontend: ("none" | "tanstack-router" | "react-router" | "react-vite" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "solid-start" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
846
- addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer")[];
848
+ addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer" | "docker-compose")[];
847
849
  examples: ("ai" | "none" | "chat-sdk" | "tanstack-showcase")[];
848
850
  auth: "none" | "better-auth" | "go-better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
849
851
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
@@ -855,7 +857,7 @@ declare const router: {
855
857
  api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
856
858
  webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
857
859
  serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
858
- ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
860
+ ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai" | "ai-cli";
859
861
  effect: "effect" | "none" | "effect-full";
860
862
  stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
861
863
  forms: "none" | "tanstack-form" | "react-hook-form" | "formik" | "final-form" | "conform" | "modular-forms";
@@ -939,7 +941,7 @@ declare const router: {
939
941
  backend: "none" | "hono" | "express" | "fastify" | "elysia" | "fets" | "nestjs" | "adonisjs" | "nitro" | "encore" | "convex" | "self";
940
942
  runtime: "none" | "bun" | "node" | "workers";
941
943
  frontend: ("none" | "tanstack-router" | "react-router" | "react-vite" | "tanstack-start" | "next" | "nuxt" | "native-bare" | "native-uniwind" | "native-unistyles" | "svelte" | "solid" | "solid-start" | "astro" | "qwik" | "angular" | "redwood" | "fresh")[];
942
- addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer")[];
944
+ addons: ("none" | "pwa" | "tauri" | "starlight" | "biome" | "lefthook" | "husky" | "ruler" | "mcp" | "skills" | "turborepo" | "fumadocs" | "ultracite" | "oxlint" | "opentui" | "wxt" | "msw" | "storybook" | "tanstack-query" | "tanstack-table" | "tanstack-virtual" | "tanstack-db" | "tanstack-pacer" | "docker-compose")[];
943
945
  examples: ("ai" | "none" | "chat-sdk" | "tanstack-showcase")[];
944
946
  auth: "none" | "better-auth" | "go-better-auth" | "clerk" | "nextauth" | "stack-auth" | "supabase-auth" | "auth0";
945
947
  payments: "none" | "polar" | "stripe" | "lemon-squeezy" | "paddle" | "dodo";
@@ -951,7 +953,7 @@ declare const router: {
951
953
  api: "none" | "trpc" | "orpc" | "ts-rest" | "garph" | "graphql-yoga";
952
954
  webDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
953
955
  serverDeploy: "none" | "docker" | "cloudflare" | "fly" | "railway" | "sst" | "vercel";
954
- ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai";
956
+ ai: "none" | "langgraph" | "langchain" | "llamaindex" | "vercel-ai" | "mastra" | "voltagent" | "openai-agents" | "google-adk" | "modelfusion" | "tanstack-ai" | "ai-cli";
955
957
  effect: "effect" | "none" | "effect-full";
956
958
  stateManagement: "none" | "zustand" | "jotai" | "nanostores" | "redux-toolkit" | "mobx" | "xstate" | "valtio" | "tanstack-store" | "legend-state";
957
959
  forms: "none" | "tanstack-form" | "react-hook-form" | "formik" | "final-form" | "conform" | "modular-forms";
@@ -1065,6 +1067,7 @@ declare const router: {
1065
1067
  "tanstack-virtual": "tanstack-virtual";
1066
1068
  "tanstack-db": "tanstack-db";
1067
1069
  "tanstack-pacer": "tanstack-pacer";
1070
+ "docker-compose": "docker-compose";
1068
1071
  }>>>;
1069
1072
  webDeploy: z.ZodOptional<z.ZodEnum<{
1070
1073
  none: "none";
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import z from "zod";
10
10
  import envPaths from "env-paths";
11
11
  import fs from "fs-extra";
12
12
  import path from "node:path";
13
- import { allowedApisForFrontends, getCompatibleAddons, getCompatibleCSSFrameworks, getCompatibleUILibraries, getLocalWebDevPort, hasWebStyling, isExampleAIAllowed, isExampleChatSdkAllowed, isFrontendAllowedWithBackend, isWebFrontend, requiresChatSdkVercelAIForSelection, splitFrontends, validateAddonCompatibility } from "@better-fullstack/types";
13
+ import { allowedApisForFrontends, getCompatibleAddons, getCompatibleCSSFrameworks, getCompatibleUILibraries, getLocalWebDevPort, hasDockerComposeCompatibleFrontend, hasWebStyling, isExampleAIAllowed, isExampleChatSdkAllowed, isFrontendAllowedWithBackend, isWebFrontend, requiresChatSdkVercelAIForSelection, splitFrontends, validateAddonCompatibility } from "@better-fullstack/types";
14
14
  import { ECOSYSTEM_GROUPS, EMBEDDED_TEMPLATES, EMBEDDED_TEMPLATES as EMBEDDED_TEMPLATES$1, TEMPLATE_COUNT, VirtualFileSystem, VirtualFileSystem as VirtualFileSystem$1, checkAllVersions, generateCliReport, generateVirtualProject, generateVirtualProject as generateVirtualProject$1, listEcosystems, processAddonTemplates, processAddonsDeps, validatePreflightConfig } from "@better-fullstack/template-generator";
15
15
  import gradient from "gradient-string";
16
16
  import path$1 from "path";
@@ -693,16 +693,51 @@ function validateWebDeployRequiresWebFrontend(webDeploy, hasWebFrontendFlag) {
693
693
  function validateServerDeployRequiresBackend(serverDeploy, backend) {
694
694
  if (serverDeploy && serverDeploy !== "none" && (!backend || backend === "none")) exitWithError("'--server-deploy' requires a backend. Please select a backend or set '--server-deploy none'.");
695
695
  }
696
- function validateAddonCompatibility$1(addon, frontend, _auth) {
697
- return validateAddonCompatibility(addon, frontend, _auth);
696
+ function validateAddonCompatibility$1(addon, frontend, _auth, backend, runtime, ecosystem, rustFrontend, javaWebFramework, database) {
697
+ const baseCompatibility = validateAddonCompatibility(addon, frontend, _auth);
698
+ if (!baseCompatibility.isCompatible) return baseCompatibility;
699
+ if (addon === "docker-compose") {
700
+ if (backend === "convex") return {
701
+ isCompatible: false,
702
+ reason: "docker-compose is not compatible with Convex backend (managed service)"
703
+ };
704
+ if (runtime === "workers") return {
705
+ isCompatible: false,
706
+ reason: "docker-compose is not compatible with Cloudflare Workers runtime"
707
+ };
708
+ if (ecosystem === "typescript" && !hasDockerComposeCompatibleFrontend(frontend)) return {
709
+ isCompatible: false,
710
+ reason: "Docker Compose currently supports Next.js, TanStack Router, React Router, React Vite, Solid, or Astro"
711
+ };
712
+ if (ecosystem === "typescript" && backend === "self" && !frontend.includes("next")) return {
713
+ isCompatible: false,
714
+ reason: "Docker Compose self-backend support currently requires Next.js"
715
+ };
716
+ if (ecosystem === "rust" && rustFrontend && rustFrontend !== "none") return {
717
+ isCompatible: false,
718
+ reason: "Docker Compose for Rust currently supports server-only projects"
719
+ };
720
+ if (ecosystem === "java" && javaWebFramework && javaWebFramework !== "spring-boot") return {
721
+ isCompatible: false,
722
+ reason: "Docker Compose for Java currently requires Spring Boot"
723
+ };
724
+ if (ecosystem === "python" && database && database !== "none" && database !== "sqlite" && database !== "postgres") return {
725
+ isCompatible: false,
726
+ reason: "Docker Compose for Python ORM projects currently supports SQLite defaults or Postgres"
727
+ };
728
+ }
729
+ return { isCompatible: true };
698
730
  }
699
- function getCompatibleAddons$1(allAddons, frontend, existingAddons = [], auth) {
700
- return getCompatibleAddons(allAddons, frontend, existingAddons, auth);
731
+ function getCompatibleAddons$1(allAddons, frontend, existingAddons = [], auth, backend, runtime) {
732
+ return getCompatibleAddons(allAddons, frontend, existingAddons, auth).filter((addon) => {
733
+ const { isCompatible } = validateAddonCompatibility$1(addon, frontend, auth, backend, runtime);
734
+ return isCompatible;
735
+ });
701
736
  }
702
- function validateAddonsAgainstFrontends(addons = [], frontends = [], auth) {
737
+ function validateAddonsAgainstFrontends(addons = [], frontends = [], auth, backend, runtime, ecosystem, rustFrontend, javaWebFramework, database) {
703
738
  for (const addon of addons) {
704
739
  if (addon === "none") continue;
705
- const { isCompatible, reason } = validateAddonCompatibility$1(addon, frontends, auth);
740
+ const { isCompatible, reason } = validateAddonCompatibility$1(addon, frontends, auth, backend, runtime, ecosystem, rustFrontend, javaWebFramework, database);
706
741
  if (!isCompatible) exitWithError(`Incompatible addon/frontend combination: ${reason}`);
707
742
  }
708
743
  }
@@ -1147,6 +1182,10 @@ function getAddonDisplay(addon) {
1147
1182
  label = "TanStack Pacer";
1148
1183
  hint = "Debounce, throttle, rate-limit & queue utilities (Beta)";
1149
1184
  break;
1185
+ case "docker-compose":
1186
+ label = "Docker Compose";
1187
+ hint = "Containerize your app for deployment";
1188
+ break;
1150
1189
  default:
1151
1190
  label = addon;
1152
1191
  hint = `Add ${addon}`;
@@ -1171,7 +1210,8 @@ const ADDON_GROUPS = {
1171
1210
  "tauri",
1172
1211
  "opentui",
1173
1212
  "wxt",
1174
- "ruler"
1213
+ "ruler",
1214
+ "docker-compose"
1175
1215
  ],
1176
1216
  Integrations: ["msw", "storybook"],
1177
1217
  "AI Agents": ["mcp", "skills"],
@@ -1183,7 +1223,13 @@ const ADDON_GROUPS = {
1183
1223
  "tanstack-pacer"
1184
1224
  ]
1185
1225
  };
1186
- async function getAddonsChoice(addons, frontends, auth) {
1226
+ function validateAddonCompatibilityForPrompt(addon, frontends, auth, backend, runtime) {
1227
+ return validateAddonCompatibility$1(addon, frontends, auth, backend, runtime);
1228
+ }
1229
+ function getCompatibleAddonsForPrompt(allAddons, frontends, existingAddons = [], auth, backend, runtime) {
1230
+ return getCompatibleAddons$1(allAddons, frontends, existingAddons, auth, backend, runtime);
1231
+ }
1232
+ async function getAddonsChoice(addons, frontends, auth, backend, runtime) {
1187
1233
  if (addons !== void 0) return addons;
1188
1234
  const allAddons = types_exports.AddonsSchema.options.filter((addon) => addon !== "none");
1189
1235
  const groupedOptions = {
@@ -1196,7 +1242,7 @@ async function getAddonsChoice(addons, frontends, auth) {
1196
1242
  };
1197
1243
  const frontendsArray = frontends || [];
1198
1244
  for (const addon of allAddons) {
1199
- const { isCompatible } = validateAddonCompatibility$1(addon, frontendsArray, auth);
1245
+ const { isCompatible } = validateAddonCompatibilityForPrompt(addon, frontendsArray, auth, backend, runtime);
1200
1246
  if (!isCompatible) continue;
1201
1247
  const { label, hint } = getAddonDisplay(addon);
1202
1248
  const option = {
@@ -1229,7 +1275,7 @@ async function getAddonsChoice(addons, frontends, auth) {
1229
1275
  if (isCancel$1(response)) return exitCancelled("Operation cancelled");
1230
1276
  return response;
1231
1277
  }
1232
- async function getAddonsToAdd(frontend, existingAddons = [], auth) {
1278
+ async function getAddonsToAdd(frontend, existingAddons = [], auth, backend, runtime) {
1233
1279
  const groupedOptions = {
1234
1280
  Tooling: [],
1235
1281
  Documentation: [],
@@ -1239,7 +1285,7 @@ async function getAddonsToAdd(frontend, existingAddons = [], auth) {
1239
1285
  TanStack: []
1240
1286
  };
1241
1287
  const frontendArray = frontend || [];
1242
- const compatibleAddons = getCompatibleAddons$1(types_exports.AddonsSchema.options.filter((addon) => addon !== "none"), frontendArray, existingAddons, auth);
1288
+ const compatibleAddons = getCompatibleAddonsForPrompt(types_exports.AddonsSchema.options.filter((addon) => addon !== "none"), frontendArray, existingAddons, auth, backend, runtime);
1243
1289
  for (const addon of compatibleAddons) {
1244
1290
  const { label, hint } = getAddonDisplay(addon);
1245
1291
  const option = {
@@ -1752,6 +1798,11 @@ const AI_PROMPT_OPTIONS = [
1752
1798
  label: "TanStack AI",
1753
1799
  hint: "Unified LLM interface for AI-powered apps (Alpha)"
1754
1800
  },
1801
+ {
1802
+ value: "ai-cli",
1803
+ label: "AI CLI",
1804
+ hint: "Agent-native terminal CLI for generating text, images, and video"
1805
+ },
1755
1806
  {
1756
1807
  value: "none",
1757
1808
  label: "None",
@@ -5623,7 +5674,7 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
5623
5674
  return getRuntimeChoice(flags.runtime, results.backend);
5624
5675
  },
5625
5676
  database: ({ results }) => {
5626
- if (results.ecosystem !== "typescript") return Promise.resolve("none");
5677
+ if (results.ecosystem !== "typescript") return Promise.resolve(results.ecosystem === "python" ? flags.database ?? "none" : "none");
5627
5678
  return getDatabaseChoice(flags.database, results.backend, results.runtime);
5628
5679
  },
5629
5680
  orm: ({ results }) => {
@@ -5652,8 +5703,11 @@ async function gatherConfig(flags, projectName, projectDir, relativePath) {
5652
5703
  return getEffectChoice(flags.effect);
5653
5704
  },
5654
5705
  addons: ({ results }) => {
5655
- if (results.ecosystem !== "typescript") return Promise.resolve([]);
5656
- return getAddonsChoice(flags.addons, results.frontend, results.auth);
5706
+ if (results.ecosystem !== "typescript") {
5707
+ const nonTypeScriptAddons = (flags.addons ?? []).filter((addon) => addon === "docker-compose");
5708
+ return Promise.resolve(nonTypeScriptAddons);
5709
+ }
5710
+ return getAddonsChoice(flags.addons, results.frontend, results.auth, results.backend, results.runtime);
5657
5711
  },
5658
5712
  examples: ({ results }) => {
5659
5713
  if (results.ecosystem !== "typescript") return Promise.resolve([]);
@@ -7095,7 +7149,7 @@ function validateFullConfig(config, providedFlags, options) {
7095
7149
  suggestions: ["Use --server-deploy fly or --server-deploy railway for NestJS/AdonisJS", "Switch to a serverless-compatible backend like Hono or Express"]
7096
7150
  });
7097
7151
  if (config.addons && config.addons.length > 0) {
7098
- validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
7152
+ validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth, config.backend, config.runtime, config.ecosystem, config.rustFrontend, config.javaWebFramework, config.database);
7099
7153
  config.addons = [...new Set(config.addons)];
7100
7154
  }
7101
7155
  validateExamplesCompatibility(config.examples ?? [], config.backend, config.frontend ?? [], config.runtime, config.ai);
@@ -7114,7 +7168,7 @@ function validateConfigForProgrammaticUse(config) {
7114
7168
  validateApiFrontendCompatibility(config.api, config.frontend, config.astroIntegration);
7115
7169
  validateJavaConstraints(config);
7116
7170
  validatePaymentsCompatibility(config.payments, config.auth, config.backend, config.frontend);
7117
- if (config.addons && config.addons.length > 0) validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth);
7171
+ if (config.addons && config.addons.length > 0) validateAddonsAgainstFrontends(config.addons, config.frontend, config.auth, config.backend, config.runtime, config.ecosystem, config.rustFrontend, config.javaWebFramework, config.database);
7118
7172
  validateExamplesCompatibility(config.examples ?? [], config.backend, config.frontend ?? [], config.runtime, config.ai);
7119
7173
  validateAIFrontendCompatibility(config.ai, config.frontend ?? []);
7120
7174
  validateUILibraryFrontendCompatibility(config.uiLibrary, config.frontend ?? [], config.astroIntegration);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-better-fullstack",
3
- "version": "1.6.2",
4
- "description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options — the CLI wires everything together.",
3
+ "version": "1.6.3",
4
+ "description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 425 options — the CLI wires everything together.",
5
5
  "keywords": [
6
6
  "algolia",
7
7
  "angular",
@@ -127,8 +127,8 @@
127
127
  "prepublishOnly": "npm run build"
128
128
  },
129
129
  "dependencies": {
130
- "@better-fullstack/template-generator": "^1.6.2",
131
- "@better-fullstack/types": "^1.6.2",
130
+ "@better-fullstack/template-generator": "^1.6.3",
131
+ "@better-fullstack/types": "^1.6.3",
132
132
  "@clack/core": "^0.5.0",
133
133
  "@clack/prompts": "^1.2.0",
134
134
  "@orpc/server": "^1.14.0",