Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions CATALOG_IMPLEMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Catalog Implementation Summary

## Overview
Implemented support for Bun and pnpm catalogs to reduce duplication of dependency versions across monorepo packages.

## What are Catalogs?
Catalogs allow you to define dependency versions once in a central location and reference them across multiple packages using the `catalog:` protocol. This ensures version consistency and makes updates easier.

## Implementation Details

### Files Created/Modified

1. **`apps/cli/src/utils/setup-catalogs.ts`** (NEW)
- Main implementation file for catalog functionality
- Scans all workspace packages for dependencies:
- apps/server
- apps/web
- packages/api
- packages/db
- packages/auth
- packages/backend (for Convex)
- Identifies duplicated dependencies (those appearing in 2+ packages)
- Creates catalog entries for Bun or pnpm
- Updates package.json files to use `catalog:` protocol

2. **`apps/cli/src/helpers/core/create-project.ts`** (MODIFIED)
- Added `setupCatalogs()` call after `updatePackageConfigurations()`
- Catalogs are set up after all dependencies are added but before deployment setup

3. **`apps/cli/package.json`** (MODIFIED)
- Added `yaml` dependency for pnpm-workspace.yaml parsing

4. **`apps/cli/test/catalogs.test.ts`** (NEW)
- Comprehensive test suite covering:
- Bun catalog setup
- pnpm catalog setup
- npm (no catalog) behavior
- Convex backend catalog support
- Selective cataloging (only duplicates)

## How It Works

### For Bun
- Catalogs are added to `package.json` under `workspaces.catalog`
- If `workspaces` is an array, it's converted to object format:

**Before (array format)**:
```json
{
"workspaces": ["apps/*", "packages/*"]
}
```

**After (object format with catalog)**:
```json
{
"workspaces": {
"packages": ["apps/*", "packages/*"],
"catalog": {
"dotenv": "^16.4.7",
"zod": "^4.1.11",
"tsdown": "^0.15.4"
}
}
}
```

### For pnpm
- Catalogs are added to `pnpm-workspace.yaml`:
```yaml
packages:
- "apps/*"
- "packages/*"
catalog:
dotenv: ^16.4.7
zod: ^4.1.11
tsdown: ^0.15.4
```

### For npm
- No catalogs are created (npm doesn't support this feature)
- Dependencies keep their actual version numbers

### Package References
- Package.json files in workspace packages use `catalog:` protocol:
```json
{
"dependencies": {
"dotenv": "catalog:",
"zod": "catalog:"
}
}
```

## Behavior

### When Catalogs Are Created
- Package manager is Bun or pnpm
- At least one dependency appears in multiple packages
- Works for both regular server backends (Hono, Elysia) and Convex backends

### What Gets Cataloged
- Only external dependencies (not workspace packages like `@project-name/db`)
- Only dependencies that appear in 2+ of these packages:
- apps/server
- apps/web
- packages/api
- packages/db
- packages/auth
- packages/backend (for Convex)

### What Doesn't Get Cataloged
- Workspace dependencies (those starting with `@project-name/`)
- Dependencies with `workspace:` protocol
- Dependencies appearing in only one package
- Any dependencies when npm is the package manager

## Benefits

1. **Version Consistency**: All packages use the same version of shared dependencies
2. **Easier Updates**: Update a dependency version in one place instead of multiple
3. **Reduced Duplication**: Less repetition in package.json files
4. **Better Maintenance**: Clear view of which dependencies are standardized

## Example Output

For a project using Bun with hono backend, better-auth, and trpc:

**Root package.json (Bun)**:
```json
{
"workspaces": {
"catalog": {
"dotenv": "^16.4.7",
"zod": "^4.1.11",
"tsdown": "^0.15.4"
}
}
}
```

**packages/db/package.json**:
```json
{
"dependencies": {
"dotenv": "catalog:",
"zod": "catalog:"
},
"devDependencies": {
"tsdown": "catalog:"
}
}
```

**packages/auth/package.json**:
```json
{
"dependencies": {
"dotenv": "catalog:",
"zod": "catalog:",
"@my-app/db": "workspace:*"
},
"devDependencies": {
"tsdown": "catalog:"
}
}
```

## Testing

Run tests with:
```bash
cd apps/cli
bun test catalogs.test.ts
```

Tests verify:
- Bun catalog creation and references
- pnpm catalog creation and references
- npm skips catalog creation
- Convex backend catalog support (packages/backend)
- Only duplicated dependencies are cataloged
- Web app dependencies are included in catalogs
178 changes: 178 additions & 0 deletions FULLSTACK_BACKEND_IMPLEMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Fullstack Backend Implementation

## Overview
Implemented `--backend self` option to support fullstack frameworks (Next.js, Nuxt, SvelteKit, TanStack Start) that have their own backend capabilities.

## Key Changes

### 1. Updated Backend Schema
**File:** `apps/cli/src/types.ts`
- Removed `"next"` from backend options (no longer needed as separate backend)
- Added `"self"` to backend options: `["hono", "express", "fastify", "elysia", "convex", "self", "none"]`

### 2. Updated Backend Prompt
**File:** `apps/cli/src/prompts/backend.ts`
- Shows "Self (Fullstack)" option when a fullstack-capable frontend is selected (next, nuxt, svelte, tanstack-start)
- Makes "self" the default when a fullstack frontend is chosen
- Hides "self" option when non-fullstack frontends are selected

### 3. Added Validation
**File:** `apps/cli/src/utils/compatibility-rules.ts`
- New function: `validateSelfBackendCompatibility()`
- Ensures `--backend self` only works with fullstack frontends
- Prevents using multiple frontends with `--backend self`
- Provides clear error messages

**File:** `apps/cli/src/utils/config-validation.ts`
- Added validation call in `validateFullConfig()`

### 4. Updated Prompts
**File:** `apps/cli/src/prompts/api.ts`
- Still prompts for API choice (tRPC, oRPC, or none)
- Fullstack frameworks can use tRPC/oRPC for type-safe client-server communication

**File:** `apps/cli/src/prompts/runtime.ts`
- Returns `"none"` when `backend === "self"` (fullstack frameworks handle their own runtime)

### 5. Updated Project Creation
**File:** `apps/cli/src/helpers/core/create-project.ts`
- Skips `apps/server` creation when `backend === "self"`
- Skips backend framework setup when `backend === "self"`
- Still creates packages (api, auth, db) for shared business logic

### 6. Updated Package Configuration
**File:** `apps/cli/src/helpers/core/project-config.ts`
- Skips `dev:server` script when `backend === "self"`
- Doesn't try to update `apps/server/package.json` when it doesn't exist

### 7. Updated Workspace Setup
**File:** `apps/cli/src/helpers/core/workspace-setup.ts`
- When `backend === "self"`, adds api/auth/db package dependencies to `apps/web` instead of `apps/server`
- Automatically handles missing `apps/server` directory

## Project Structure

### With `--backend self` (Fullstack)
```
my-app/
├── apps/
│ └── web/ # Fullstack app (Next/Nuxt/SvelteKit/TanStack Start)
│ └── package.json # Depends on @my-app/api, @my-app/auth, @my-app/db
├── packages/
│ ├── api/ # API layer / business logic
│ ├── auth/ # Auth configuration & logic
│ └── db/ # Database schema & queries
└── package.json
```

### With traditional backend (hono, express, etc.)
```
my-app/
├── apps/
│ ├── web/ # Frontend
│ └── server/ # Backend server
├── packages/
│ ├── api/ # API layer
│ ├── auth/ # Auth logic
│ └── db/ # Database layer
└── package.json
```

## Usage Examples

### Full Stack Next.js with tRPC
```bash
create-better-t-stack my-app --frontend next --backend self --api trpc --database postgres --orm drizzle --auth better-auth
```

### Full Stack Nuxt with oRPC
```bash
create-better-t-stack my-app --frontend nuxt --backend self --api orpc --database sqlite --orm drizzle
```

### Full Stack SvelteKit with oRPC
```bash
create-better-t-stack my-app --frontend svelte --backend self --api orpc --database postgres --orm prisma
```

### Full Stack TanStack Start with tRPC
```bash
create-better-t-stack my-app --frontend tanstack-start --backend self --api trpc --database mysql --orm drizzle
```

### Full Stack Next.js without API layer (using Server Actions only)
```bash
create-better-t-stack my-app --frontend next --backend self --api none --database postgres --orm drizzle
```

### Error Cases
```bash
# ❌ Error: self backend requires fullstack frontend
create-better-t-stack my-app --frontend tanstack-router --backend self

# ❌ Error: self backend requires single frontend
create-better-t-stack my-app --frontend next --frontend native-nativewind --backend self

# ❌ Error: self backend requires fullstack frontend
create-better-t-stack my-app --frontend solid --backend self
```

## Benefits

1. **Clear Separation**: Distinguishes between fullstack frameworks and separate backend servers
2. **No Duplication**: Avoids having both `apps/server` and fullstack framework handling backend
3. **Shared Packages**: Still maintains clean separation of concerns with packages/api, packages/auth, packages/db
4. **Better DX**: Makes intent explicit - you're choosing a fullstack architecture
5. **Maintainable**: Easier to understand and maintain than having "next" as both frontend and backend

## Behavior

### When `backend === "self"`
- ✅ Creates `apps/web` with fullstack framework
- ✅ Creates `packages/api`, `packages/auth`, `packages/db`
- ❌ Skips `apps/server` creation
- ❌ No `dev:server` script
- ✅ API prompts for choice (tRPC, oRPC, or none) - can use type-safe APIs!
- ✅ Runtime set to "none" (framework manages runtime)
- ✅ Web app depends on all workspace packages
- ✅ Catalog support works correctly

### Supported Fullstack Frontends
- **Next.js**: App Router with Server Actions, API Routes, Route Handlers
- **Nuxt**: Nuxt Server Routes and Server API
- **SvelteKit**: SvelteKit Endpoints and Form Actions
- **TanStack Start**: Server Functions and API Routes

## Testing

To test the implementation:

```bash
# Build CLI
cd apps/cli && bun run build

# Test fullstack setup
cd ../..
bun dist/cli.js test-next --frontend next --backend self --database postgres --orm drizzle

# Verify structure
ls -la test-next/apps # Should only have 'web'
ls -la test-next/packages # Should have 'api', 'auth', 'db'
```

## Migration Guide

### For existing projects using "next" as backend:
The old `--backend next` is no longer supported. Instead:

**Old:**
```bash
create-better-t-stack my-app --backend next
```

**New:**
```bash
create-better-t-stack my-app --frontend next --backend self
```

This makes the intent clearer - you're creating a fullstack Next.js app, not a separate Next.js backend server.
3 changes: 2 additions & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"tinyglobby": "^0.2.15",
"trpc-cli": "^0.11.0",
"ts-morph": "^27.0.0",
"yaml": "^2.7.0",
"zod": "^4.1.11"
},
"devDependencies": {
Expand All @@ -88,4 +89,4 @@
"typescript": "^5.9.2",
"vitest": "^3.2.4"
}
}
}
Loading