diff --git a/.changeset/eager-lizards-lose.md b/.changeset/eager-lizards-lose.md new file mode 100644 index 0000000..3cf5d37 --- /dev/null +++ b/.changeset/eager-lizards-lose.md @@ -0,0 +1,5 @@ +--- +"create-better-t-stack": patch +--- + +generate better readme diff --git a/apps/cli/README.md b/apps/cli/README.md index f592b6a..4131859 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -27,12 +27,12 @@ Follow the prompts to configure your project or use the `--yes` flag for default | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **TypeScript** | End-to-end type safety across all parts of your application | | **Frontend** | • React with TanStack Router
• React with React Router
• React with TanStack Start (SSR)
• Next.js
• SvelteKit
• Nuxt (Vue)
• SolidJS
• React Native with NativeWind (via Expo)
• React Native with Unistyles (via Expo)
• None | -| **Backend** | • Hono
• Express
• Elysia
• Next.js API routes
• Convex
• Fastify
• None | +| **Backend** | • Hono
• Express
• Elysia
• Next.js API routes
• Convex
• Fastify
• None | | **API Layer** | • tRPC (type-safe APIs)
• oRPC (OpenAPI-compatible type-safe APIs)
• None | -| **Runtime** | • Bun
• Node.js | +| **Runtime** | • Bun
• Node.js
• Cloudflare Workers
• None | | **Database** | • SQLite
• PostgreSQL
• MySQL
• MongoDB
• None | | **ORM** | • Drizzle (TypeScript-first)
• Prisma (feature-rich)
• Mongoose (for MongoDB)
• None | -| **Database Setup** | • Turso (SQLite)
• Neon (PostgreSQL)
• Prisma Postgres (via Prisma Accelerate)
• MongoDB Atlas
• None (manual setup) | +| **Database Setup** | • Turso (SQLite)
• Cloudflare D1 (SQLite)
• Neon (PostgreSQL)
• Supabase (PostgreSQL)
• Prisma Postgres (via Prisma Accelerate)
• MongoDB Atlas
• None (manual setup) | | **Authentication** | Better-Auth (email/password, with more options coming soon) | | **Styling** | Tailwind CSS with shadcn/ui components | | **Addons** | • PWA support
• Tauri (desktop applications)
• Starlight (documentation site)
• Biome (linting and formatting)
• Husky (Git hooks)
• Turborepo (optimized builds) | @@ -59,9 +59,9 @@ Options: --package-manager Package manager (npm, pnpm, bun) --install Install dependencies --no-install Skip installing dependencies - --db-setup Database setup (turso, neon, prisma-postgres, mongodb-atlas, none) + --db-setup Database setup (turso, d1, neon, supabase, prisma-postgres, mongodb-atlas, none) --backend Backend framework (hono, express, elysia, next, convex, fastify, none) - --runtime Runtime (bun, node, none) + --runtime Runtime (bun, node, workers, none) --api API type (trpc, orpc, none) -h, --help Display help ``` @@ -104,6 +104,12 @@ Create a project with Turso database setup: npx create-better-t-stack my-app --database sqlite --orm drizzle --db-setup turso ``` +Create a project with Supabase PostgreSQL setup: + +```bash +npx create-better-t-stack my-app --database postgres --orm drizzle --db-setup supabase --auth +``` + Create a project with Convex backend: ```bash @@ -116,10 +122,48 @@ Create a project with documentation site: npx create-better-t-stack my-app --addons starlight ``` +Create a minimal TypeScript project with no backend: + +```bash +npx create-better-t-stack my-app --backend none --frontend tanstack-router +``` + +Create a backend-only project with no frontend: + +```bash +npx create-better-t-stack my-app --frontend none --backend hono --database postgres --orm drizzle +``` + +Create a simple frontend-only project: + +```bash +npx create-better-t-stack my-app --backend none --frontend next --addons none --examples none +``` + +Create a Cloudflare Workers project: + +```bash +npx create-better-t-stack my-app --backend hono --runtime workers --database sqlite --orm drizzle --db-setup d1 +``` + +Create a minimal API-only project: + +```bash +npx create-better-t-stack my-app --frontend none --backend hono --api trpc --database none --addons none +``` + ## Compatibility Notes - **Convex backend**: Automatically disables authentication, database, ORM, and API options - **Backend 'none'**: If selected, this option will force related options like API, ORM, database, authentication, and runtime to 'none'. Examples will also be disabled (set to none/empty). +- **Frontend 'none'**: Creates a backend-only project. When selected, PWA, Tauri, and certain examples may be disabled. +- **API 'none'**: Disables tRPC/oRPC setup. Can be used with backend frameworks for REST APIs or custom API implementations. +- **Database 'none'**: Disables database setup. Automatically sets ORM to 'none' and disables authentication. +- **ORM 'none'**: Can be used when you want to handle database operations manually or use a different ORM. +- **Runtime 'none'**: Only available with Convex backend or when backend is 'none'. +- **Cloudflare Workers runtime**: Only compatible with Hono backend, Drizzle ORM (or no ORM), and SQLite database (with D1 setup). Not compatible with MongoDB. +- **Addons 'none'**: Skips all addons (PWA, Tauri, Starlight, Biome, Husky, Turborepo). +- **Examples 'none'**: Skips all example implementations (todo, AI chat). - **SvelteKit, Nuxt, and SolidJS** frontends are only compatible with oRPC API layer - **PWA support** requires React with TanStack Router, React Router, or SolidJS - **Tauri desktop app** requires React (TanStack Router/React Router), Nuxt, SvelteKit, or SolidJS diff --git a/apps/cli/src/constants.ts b/apps/cli/src/constants.ts index a960922..cec798a 100644 --- a/apps/cli/src/constants.ts +++ b/apps/cli/src/constants.ts @@ -96,7 +96,7 @@ export const dependencyVersionMap = { "@trpc/server": "^11.4.2", "@trpc/client": "^11.4.2", - convex: "^1.23.0", + convex: "^1.25.0", "@convex-dev/react-query": "^0.0.0-alpha.8", "convex-svelte": "^0.0.11", diff --git a/apps/cli/src/helpers/project-generation/create-readme.ts b/apps/cli/src/helpers/project-generation/create-readme.ts index d4b43b7..dffb5b7 100644 --- a/apps/cli/src/helpers/project-generation/create-readme.ts +++ b/apps/cli/src/helpers/project-generation/create-readme.ts @@ -38,15 +38,10 @@ function generateReadmeContent(options: ProjectConfig): string { const isConvex = backend === "convex"; const hasReactRouter = frontend.includes("react-router"); - const hasTanstackRouter = frontend.includes("tanstack-router"); const hasNative = frontend.includes("native-nativewind") || frontend.includes("native-unistyles"); - const hasNext = frontend.includes("next"); - const hasTanstackStart = frontend.includes("tanstack-start"); const hasSvelte = frontend.includes("svelte"); - const hasSolid = frontend.includes("solid"); - const hasNuxt = frontend.includes("nuxt"); const packageManagerRunCmd = packageManager === "npm" ? "npm run" : packageManager; @@ -56,27 +51,18 @@ function generateReadmeContent(options: ProjectConfig): string { webPort = "5173"; } + const stackDescription = generateStackDescription( + frontend, + backend, + api, + isConvex, + ); + return `# ${projectName} -This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack that combines ${ - hasTanstackRouter - ? "React, TanStack Router" - : hasReactRouter - ? "React, React Router" - : hasNext - ? "Next.js" - : hasTanstackStart - ? "React, TanStack Start" - : hasSvelte - ? "SvelteKit" - : hasNuxt - ? "Nuxt" - : hasSolid - ? "SolidJS" - : "" - }, ${backend[0].toUpperCase() + backend.slice(1)}${ - isConvex ? "" : `, ${api.toUpperCase()}` - }, and more. +This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack${ + stackDescription ? ` that combines ${stackDescription}` : "" + }. ## Features @@ -119,23 +105,7 @@ Then, run the development server: ${packageManagerRunCmd} dev \`\`\` -${ - hasTanstackRouter || - hasReactRouter || - hasNext || - hasTanstackStart || - hasSvelte || - hasNuxt || - hasSolid - ? `Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the web application.` - : "" -} -${hasNative ? "Use the Expo Go app to run the mobile application.\n" : ""} -${ - isConvex - ? "Your app will connect to the Convex cloud backend automatically." - : "The API is running at [http://localhost:3000](http://localhost:3000)." -} +${generateRunningInstructions(frontend, backend, webPort, hasNative, isConvex)} ${ addons.includes("pwa") && hasReactRouter @@ -146,49 +116,14 @@ ${ ## Project Structure \`\`\` -${projectName}/ -├── apps/ -${ - hasTanstackRouter || - hasReactRouter || - hasNext || - hasTanstackStart || - hasSvelte || - hasNuxt || - hasSolid - ? `│ ├── web/ # Frontend application (${ - hasTanstackRouter - ? "React + TanStack Router" - : hasReactRouter - ? "React + React Router" - : hasNext - ? "Next.js" - : hasTanstackStart - ? "React + TanStack Start" - : hasSvelte - ? "SvelteKit" - : hasNuxt - ? "Nuxt" - : hasSolid - ? "SolidJS" - : "" - })\n` - : "" -}${ - hasNative - ? "│ ├── native/ # Mobile application (React Native, Expo)\n" - : "" -}${ - addons.includes("starlight") - ? "│ ├── docs/ # Documentation site (Astro Starlight)\n" - : "" -}${ - isConvex - ? "├── packages/\n│ └── backend/ # Convex backend functions and schema\n" - : `│ └── server/ # Backend API (${ - backend[0].toUpperCase() + backend.slice(1) - }, ${api.toUpperCase()})` -} +${generateProjectStructure( + projectName, + frontend, + backend, + addons, + isConvex, + api, +)} \`\`\` ## Available Scripts @@ -205,6 +140,181 @@ ${generateScriptsList( `; } +function generateStackDescription( + frontend: Frontend[], + backend: string, + api: API, + isConvex: boolean, +): string { + const parts: string[] = []; + + const hasTanstackRouter = frontend.includes("tanstack-router"); + const hasReactRouter = frontend.includes("react-router"); + const hasNext = frontend.includes("next"); + const hasTanstackStart = frontend.includes("tanstack-start"); + const hasSvelte = frontend.includes("svelte"); + const hasNuxt = frontend.includes("nuxt"); + const hasSolid = frontend.includes("solid"); + const hasFrontendNone = frontend.length === 0 || frontend.includes("none"); + + if (!hasFrontendNone) { + if (hasTanstackRouter) { + parts.push("React, TanStack Router"); + } else if (hasReactRouter) { + parts.push("React, React Router"); + } else if (hasNext) { + parts.push("Next.js"); + } else if (hasTanstackStart) { + parts.push("React, TanStack Start"); + } else if (hasSvelte) { + parts.push("SvelteKit"); + } else if (hasNuxt) { + parts.push("Nuxt"); + } else if (hasSolid) { + parts.push("SolidJS"); + } + } + + if (backend !== "none") { + parts.push(backend[0].toUpperCase() + backend.slice(1)); + } + + if (!isConvex && api !== "none") { + parts.push(api.toUpperCase()); + } + + return parts.length > 0 ? `${parts.join(", ")}, and more` : ""; +} + +function generateRunningInstructions( + frontend: Frontend[], + backend: string, + webPort: string, + hasNative: boolean, + isConvex: boolean, +): string { + const instructions: string[] = []; + + const hasFrontendNone = frontend.length === 0 || frontend.includes("none"); + const isBackendNone = backend === "none"; + + if (!hasFrontendNone) { + const hasTanstackRouter = frontend.includes("tanstack-router"); + const hasReactRouter = frontend.includes("react-router"); + const hasNext = frontend.includes("next"); + const hasTanstackStart = frontend.includes("tanstack-start"); + const hasSvelte = frontend.includes("svelte"); + const hasNuxt = frontend.includes("nuxt"); + const hasSolid = frontend.includes("solid"); + + if ( + hasTanstackRouter || + hasReactRouter || + hasNext || + hasTanstackStart || + hasSvelte || + hasNuxt || + hasSolid + ) { + instructions.push( + `Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the web application.`, + ); + } + } + + if (hasNative) { + instructions.push("Use the Expo Go app to run the mobile application."); + } + + if (isConvex) { + instructions.push( + "Your app will connect to the Convex cloud backend automatically.", + ); + } else if (!isBackendNone) { + instructions.push( + "The API is running at [http://localhost:3000](http://localhost:3000).", + ); + } + + return instructions.join("\n"); +} + +function generateProjectStructure( + projectName: string, + frontend: Frontend[], + backend: string, + addons: Addons[], + isConvex: boolean, + api: API, +): string { + const structure: string[] = [`${projectName}/`, "├── apps/"]; + + const hasFrontendNone = frontend.length === 0 || frontend.includes("none"); + const isBackendNone = backend === "none"; + + if (!hasFrontendNone) { + const hasTanstackRouter = frontend.includes("tanstack-router"); + const hasReactRouter = frontend.includes("react-router"); + const hasNext = frontend.includes("next"); + const hasTanstackStart = frontend.includes("tanstack-start"); + const hasSvelte = frontend.includes("svelte"); + const hasNuxt = frontend.includes("nuxt"); + const hasSolid = frontend.includes("solid"); + + if ( + hasTanstackRouter || + hasReactRouter || + hasNext || + hasTanstackStart || + hasSvelte || + hasNuxt || + hasSolid + ) { + let frontendType = ""; + if (hasTanstackRouter) frontendType = "React + TanStack Router"; + else if (hasReactRouter) frontendType = "React + React Router"; + else if (hasNext) frontendType = "Next.js"; + else if (hasTanstackStart) frontendType = "React + TanStack Start"; + else if (hasSvelte) frontendType = "SvelteKit"; + else if (hasNuxt) frontendType = "Nuxt"; + else if (hasSolid) frontendType = "SolidJS"; + + structure.push( + `│ ├── web/ # Frontend application (${frontendType})`, + ); + } + } + + const hasNative = + frontend.includes("native-nativewind") || + frontend.includes("native-unistyles"); + if (hasNative) { + structure.push( + "│ ├── native/ # Mobile application (React Native, Expo)", + ); + } + + if (addons.includes("starlight")) { + structure.push( + "│ ├── docs/ # Documentation site (Astro Starlight)", + ); + } + + if (isConvex) { + structure.push("├── packages/"); + structure.push( + "│ └── backend/ # Convex backend functions and schema", + ); + } else if (!isBackendNone) { + const backendName = backend[0].toUpperCase() + backend.slice(1); + const apiName = api !== "none" ? api.toUpperCase() : ""; + const backendDesc = apiName ? `${backendName}, ${apiName}` : backendName; + structure.push(`│ └── server/ # Backend API (${backendDesc})`); + } + + return structure.join("\n"); +} + function generateFeaturesList( database: Database, auth: boolean, @@ -216,6 +326,7 @@ function generateFeaturesList( api: API, ): string { const isConvex = backend === "convex"; + const isBackendNone = backend === "none"; const hasTanstackRouter = frontend.includes("tanstack-router"); const hasReactRouter = frontend.includes("react-router"); const hasNative = @@ -226,29 +337,34 @@ function generateFeaturesList( const hasSvelte = frontend.includes("svelte"); const hasNuxt = frontend.includes("nuxt"); const hasSolid = frontend.includes("solid"); + const hasFrontendNone = frontend.length === 0 || frontend.includes("none"); const addonsList = [ "- **TypeScript** - For type safety and improved developer experience", ]; - if (hasTanstackRouter) { - addonsList.push( - "- **TanStack Router** - File-based routing with full type safety", - ); - } else if (hasReactRouter) { - addonsList.push("- **React Router** - Declarative routing for React"); - } else if (hasNext) { - addonsList.push("- **Next.js** - Full-stack React framework"); - } else if (hasTanstackStart) { - addonsList.push( - "- **TanStack Start** - SSR framework with TanStack Router", - ); - } else if (hasSvelte) { - addonsList.push("- **SvelteKit** - Web framework for building Svelte apps"); - } else if (hasNuxt) { - addonsList.push("- **Nuxt** - The Intuitive Vue Framework"); - } else if (hasSolid) { - addonsList.push("- **SolidJS** - Simple and performant reactivity"); + if (!hasFrontendNone) { + if (hasTanstackRouter) { + addonsList.push( + "- **TanStack Router** - File-based routing with full type safety", + ); + } else if (hasReactRouter) { + addonsList.push("- **React Router** - Declarative routing for React"); + } else if (hasNext) { + addonsList.push("- **Next.js** - Full-stack React framework"); + } else if (hasTanstackStart) { + addonsList.push( + "- **TanStack Start** - SSR framework with TanStack Router", + ); + } else if (hasSvelte) { + addonsList.push( + "- **SvelteKit** - Web framework for building Svelte apps", + ); + } else if (hasNuxt) { + addonsList.push("- **Nuxt** - The Intuitive Vue Framework"); + } else if (hasSolid) { + addonsList.push("- **SolidJS** - Simple and performant reactivity"); + } } if (hasNative) { @@ -256,14 +372,16 @@ function generateFeaturesList( addonsList.push("- **Expo** - Tools for React Native development"); } - addonsList.push( - "- **TailwindCSS** - Utility-first CSS for rapid UI development", - "- **shadcn/ui** - Reusable UI components", - ); + if (!hasFrontendNone) { + addonsList.push( + "- **TailwindCSS** - Utility-first CSS for rapid UI development", + "- **shadcn/ui** - Reusable UI components", + ); + } if (isConvex) { addonsList.push("- **Convex** - Reactive backend-as-a-service platform"); - } else { + } else if (!isBackendNone) { if (backend === "hono") { addonsList.push("- **Hono** - Lightweight, performant server framework"); } else if (backend === "express") { @@ -284,25 +402,38 @@ function generateFeaturesList( ); } - addonsList.push( - `- **${runtime === "bun" ? "Bun" : "Node.js"}** - Runtime environment`, - ); + if (runtime !== "none") { + addonsList.push( + `- **${ + runtime === "bun" ? "Bun" : runtime === "node" ? "Node.js" : runtime + }** - Runtime environment`, + ); + } } if (database !== "none" && !isConvex) { + const ormName = + orm === "drizzle" + ? "Drizzle" + : orm === "prisma" + ? "Prisma" + : orm === "mongoose" + ? "Mongoose" + : "ORM"; + const dbName = + database === "sqlite" + ? "SQLite/Turso" + : database === "postgres" + ? "PostgreSQL" + : database === "mysql" + ? "MySQL" + : database === "mongodb" + ? "MongoDB" + : "Database"; + addonsList.push( - `- **${ - orm === "drizzle" ? "Drizzle" : orm === "prisma" ? "Prisma" : "Mongoose" - }** - TypeScript-first ORM`, - `- **${ - database === "sqlite" - ? "SQLite/Turso" - : database === "postgres" - ? "PostgreSQL" - : database === "mysql" - ? "MySQL" - : "MongoDB" - }** - Database engine`, + `- **${ormName}** - TypeScript-first ORM`, + `- **${dbName}** - Database engine`, ); } @@ -333,7 +464,7 @@ function generateFeaturesList( function generateDatabaseSetup( database: Database, - auth: boolean, + _auth: boolean, packageManagerRunCmd: string, orm: ORM, ): string { @@ -345,7 +476,11 @@ function generateDatabaseSetup( if (database === "sqlite") { setup += `This project uses SQLite${ - orm === "drizzle" ? " with Drizzle ORM" : " with Prisma" + orm === "drizzle" + ? " with Drizzle ORM" + : orm === "prisma" + ? " with Prisma" + : ` with ${orm}` }. 1. Start the local SQLite database: @@ -357,7 +492,11 @@ cd apps/server && ${packageManagerRunCmd} db:local `; } else if (database === "postgres") { setup += `This project uses PostgreSQL${ - orm === "drizzle" ? " with Drizzle ORM" : " with Prisma" + orm === "drizzle" + ? " with Drizzle ORM" + : orm === "prisma" + ? " with Prisma" + : ` with ${orm}` }. 1. Make sure you have a PostgreSQL database set up. @@ -365,7 +504,11 @@ cd apps/server && ${packageManagerRunCmd} db:local `; } else if (database === "mysql") { setup += `This project uses MySQL${ - orm === "drizzle" ? " with Drizzle ORM" : " with Prisma" + orm === "drizzle" + ? " with Drizzle ORM" + : orm === "prisma" + ? " with Prisma" + : ` with ${orm}` }. 1. Make sure you have a MySQL database set up. @@ -373,7 +516,11 @@ cd apps/server && ${packageManagerRunCmd} db:local `; } else if (database === "mongodb") { setup += `This project uses MongoDB ${ - orm === "mongoose" ? "with Mongoose" : "with Prisma ORM" + orm === "mongoose" + ? "with Mongoose" + : orm === "prisma" + ? "with Prisma ORM" + : `with ${orm}` }. 1. Make sure you have MongoDB set up. @@ -382,7 +529,7 @@ cd apps/server && ${packageManagerRunCmd} db:local } setup += ` -${auth ? "3" : "3"}. ${ +3. ${ orm === "prisma" ? `Generate the Prisma client and push the schema: \`\`\`bash @@ -413,15 +560,18 @@ function generateScriptsList( backend: string, ): string { const isConvex = backend === "convex"; + const isBackendNone = backend === "none"; let scripts = `- \`${packageManagerRunCmd} dev\`: Start all applications in development mode -- \`${packageManagerRunCmd} build\`: Build all applications +- \`${packageManagerRunCmd} build\`: Build all applications`; + + scripts += ` - \`${packageManagerRunCmd} dev:web\`: Start only the web application`; if (isConvex) { scripts += ` - \`${packageManagerRunCmd} dev:setup\`: Setup and configure your Convex project`; - } else { + } else if (!isBackendNone) { scripts += ` - \`${packageManagerRunCmd} dev:server\`: Start only the server`; } diff --git a/apps/cli/src/helpers/project-generation/post-installation.ts b/apps/cli/src/helpers/project-generation/post-installation.ts index 3e71773..d7b0792 100644 --- a/apps/cli/src/helpers/project-generation/post-installation.ts +++ b/apps/cli/src/helpers/project-generation/post-installation.ts @@ -96,6 +96,11 @@ export function displayPostInstallInstructions( output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup ${pc.dim( "(this will guide you through Convex project setup)", )}\n`; + output += `${pc.cyan( + `${stepCounter++}.`, + )} Copy environment variables from ${pc.white( + "packages/backend/.env.local", + )} \nto ${pc.white("apps/*/.env")}\n`; output += `${pc.cyan(`${stepCounter++}.`)} ${runCmd} dev\n\n`; } else { if (runtime !== "workers") { diff --git a/apps/cli/src/helpers/project-generation/project-config.ts b/apps/cli/src/helpers/project-generation/project-config.ts index 9cda063..e4fc9a7 100644 --- a/apps/cli/src/helpers/project-generation/project-config.ts +++ b/apps/cli/src/helpers/project-generation/project-config.ts @@ -68,7 +68,7 @@ async function updateRootPackageJson( scripts["dev:web"] = "turbo -F web dev"; scripts["dev:server"] = serverDevScript; if (options.backend === "convex") { - scripts["dev:setup"] = `turbo -F ${backendPackageName} setup`; + scripts["dev:setup"] = `turbo -F ${backendPackageName} dev:setup`; } if (needsDbScripts) { scripts["db:push"] = `turbo -F ${backendPackageName} db:push`; @@ -89,7 +89,7 @@ async function updateRootPackageJson( scripts["dev:web"] = "pnpm --filter web dev"; scripts["dev:server"] = serverDevScript; if (options.backend === "convex") { - scripts["dev:setup"] = `pnpm --filter ${backendPackageName} setup`; + scripts["dev:setup"] = `pnpm --filter ${backendPackageName} dev:setup`; } if (needsDbScripts) { scripts["db:push"] = `pnpm --filter ${backendPackageName} db:push`; @@ -114,7 +114,8 @@ async function updateRootPackageJson( scripts["dev:web"] = "npm run dev --workspace web"; scripts["dev:server"] = serverDevScript; if (options.backend === "convex") { - scripts["dev:setup"] = `npm run setup --workspace ${backendPackageName}`; + scripts["dev:setup"] = + `npm run dev:setup --workspace ${backendPackageName}`; } if (needsDbScripts) { scripts["db:push"] = `npm run db:push --workspace ${backendPackageName}`; @@ -140,7 +141,7 @@ async function updateRootPackageJson( scripts["dev:web"] = "bun run --filter web dev"; scripts["dev:server"] = serverDevScript; if (options.backend === "convex") { - scripts["dev:setup"] = `bun run --filter ${backendPackageName} setup`; + scripts["dev:setup"] = `bun run --filter ${backendPackageName} dev:setup`; } if (needsDbScripts) { scripts["db:push"] = `bun run --filter ${backendPackageName} db:push`; diff --git a/apps/cli/templates/addons/turborepo/turbo.json.hbs b/apps/cli/templates/addons/turborepo/turbo.json.hbs index b418466..c8d9335 100644 --- a/apps/cli/templates/addons/turborepo/turbo.json.hbs +++ b/apps/cli/templates/addons/turborepo/turbo.json.hbs @@ -17,7 +17,7 @@ "cache": false, "persistent": true }{{#if (eq backend "convex")}}, - "setup": { + "dev:setup": { "cache": false, "persistent": true } diff --git a/apps/cli/templates/backend/convex/packages/backend/package.json.hbs b/apps/cli/templates/backend/convex/packages/backend/package.json.hbs index 3fb4edb..b3184f5 100644 --- a/apps/cli/templates/backend/convex/packages/backend/package.json.hbs +++ b/apps/cli/templates/backend/convex/packages/backend/package.json.hbs @@ -3,7 +3,7 @@ "version": "1.0.0", "scripts": { "dev": "convex dev", - "setup": "convex dev --configure --until-success" + "dev:setup": "convex dev --configure --until-success" }, "author": "", "license": "ISC", @@ -12,6 +12,6 @@ "typescript": "^5.8.3" }, "dependencies": { - "convex": "^1.23.0" + "convex": "^1.25.0" } } diff --git a/apps/web/src/app/(home)/showcase/page.tsx b/apps/web/src/app/(home)/showcase/page.tsx index bdde3ae..6b7f26b 100644 --- a/apps/web/src/app/(home)/showcase/page.tsx +++ b/apps/web/src/app/(home)/showcase/page.tsx @@ -34,8 +34,10 @@ const showcaseProjects = [ { title: "Screenshothis", description: "Your All-in-One Screenshot Solution", - imageUrl: "https://api.screenshothis.com/v1/screenshots/take?api_key=ss_live_NQJgRXqHcKPwnoMTuQmgiwLIGbVfihjpMyQhgsaMyNBHTyesvrxpYNXmdgcnxipc&url=https%3A%2F%2Fscreenshothis.com%2F&width=1200&height=630&device_scale_factor=0.75&block_ads=true&block_cookie_banners=true&block_trackers=true&prefers_color_scheme=light&prefers_reduced_motion=reduce&is_cached=true&cache_key=cfb06bf3616b1d03bdf455628a3830120e2080dd", - liveUrl: "https://screenshothis.com?utm_source=better-t-stack&utm_medium=showcase&utm_campaign=referer", + imageUrl: + "https://api.screenshothis.com/v1/screenshots/take?api_key=ss_live_NQJgRXqHcKPwnoMTuQmgiwLIGbVfihjpMyQhgsaMyNBHTyesvrxpYNXmdgcnxipc&url=https%3A%2F%2Fscreenshothis.com%2F&width=1200&height=630&device_scale_factor=0.75&block_ads=true&block_cookie_banners=true&block_trackers=true&prefers_color_scheme=light&prefers_reduced_motion=reduce&is_cached=true&cache_key=cfb06bf3616b1d03bdf455628a3830120e2080dd", + liveUrl: + "https://screenshothis.com?utm_source=better-t-stack&utm_medium=showcase&utm_campaign=referer", tags: [ "oRPC", "TanStack Start (devinxi)",