diff --git a/.gitignore b/.gitignore index aa8cc7916..883bce3ba 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ build dist .output .nitro +.astro # Debug @@ -58,6 +59,7 @@ templates-binary # Auto-generated at build time (avoids merge conflicts) packages/template-generator/src/templates.generated.ts +apps/web/public/docs/ # Ralph (autonomous agent loop) scripts/ralph/ diff --git a/AGENTS.md b/AGENTS.md index 46b4f917e..687301d93 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -39,6 +39,8 @@ See `docs/guidelines/` for deeper reference on these topics: - Surprise worth remembering: prompt-interactivity helpers can pick up ambient `process.env.CI` through destructuring defaults and make tests fail only on GitHub Actions. When injecting prompt environment state in `apps/cli`, resolve CI defaults explicitly so `ci: undefined` remains an override instead of silently inheriting the runner environment. - Surprise worth remembering: addon setup helpers can bypass the shared prompt-environment guard if they call Clack prompts directly. For scripted scaffolds (`bun create ... --addons ...`, smoke tests, `create()` silent mode), ensure addon-specific setup paths like `mcp` and `ultracite` fall back to deterministic defaults instead of prompting, or they can exit before `bts.jsonc` is written. - Surprise worth remembering: TanStack Start route generation in `apps/web` only reads ignore settings from `tanstackStart({ router: ... })` in `apps/web/vite.config.ts`, not from top-level plugin options. Any `createFileRoute` scratch/design file left in `apps/web/src/routes` will be pulled into `routeTree.gen.ts` and build output unless it matches `routeFileIgnorePrefix`/`routeFileIgnorePattern`. +- Surprise worth remembering: docs content for `apps/web` lives in `apps/web/content/docs`, so `import.meta.glob` calls from `apps/web/src/lib/docs/*` must use `../../../content/docs/**` paths or the docs registry can build empty and `/docs` will 404 in preview. +- Surprise worth remembering: TanStack Start loaders must stay serializable. In `apps/web/src/routes/docs/*`, do not return the MDX `Component` from `getPage()` in loader data; return slug/frontmatter only and resolve the page component inside the route component. - Surprise worth remembering: `packages/template-generator/tsconfig.json` includes only `src/**/*`, so tests added under `packages/template-generator/test/` are not covered by the package's normal TypeScript check unless you add a dedicated test tsconfig or expand the include set. - Surprise worth remembering: ecosystem additions can still miss `apps/web/src/lib/stack-search-schema.ts`, which used to hardcode the web URL `ecosystem` enum separately from `@better-fullstack/types`. When adding or renaming ecosystems, keep that parser on the shared `EcosystemSchema` so pre-commit `apps/web` typecheck does not fail after the main stack wiring looks complete. - Surprise worth remembering: `.github/workflows/release.yaml` should keep Bun pinned for deterministic release verification, but the actual package publish path is safer through `npm publish` on Node 24. The release job's `bun publish` steps started failing on npm with a misleading 404 for `@better-fullstack/*`, while npm's current publish flow can use trusted publishing/OIDC when configured and still fall back to `NPM_TOKEN`. Treat Bun or publish-tooling changes there as release-sensitive. diff --git a/README.md b/README.md index 7eb0f2e0c..98f3f3c56 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@
-**Scaffold production-ready fullstack apps in seconds. Pick your stack from 340+ options — the CLI wires everything together.** +**Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options — the CLI wires everything together.**
@@ -34,8 +34,8 @@ Most scaffolding tools lock you into one framework and one opinion. Better Fullstack doesn't. -- **340+ options** — frontend, backend, database, auth, payments, AI, DevOps, and more -- **4 ecosystems** — TypeScript, Rust, Python, Go — with more coming +- **424 options** — frontend, backend, database, auth, payments, AI, DevOps, and more +- **5 ecosystems** — TypeScript, Rust, Python, Go, Java — with more coming - **Visual builder** — configure your stack in the browser, get a ready-to-run CLI command - **Wired for you** — no manual glue code; every picked integration is preconfigured and working out of the box @@ -58,6 +58,10 @@ Configure your stack visually — pick every option from a UI, preview your choi ### 💻 CLI +```bash +npm create better-fullstack@latest +``` + ```bash bun create better-fullstack@latest ``` @@ -74,6 +78,8 @@ npx create-better-fullstack@latest yarn create better-fullstack@latest ``` +Bun is only required when you choose Bun as the generated app runtime or package manager. Node.js with npm works for Node-based projects. + @@ -100,7 +106,7 @@ yarn create better-fullstack@latest ## 🧩 The Stack
-Ecosystems — TypeScript · Rust · Python · Go +Ecosystems — TypeScript · Rust · Python · Go · Java
| | | @@ -109,6 +115,7 @@ yarn create better-fullstack@latest | **Rust** | Axum · Actix Web · Leptos · Dioxus · SeaORM · SQLx · tonic · async-graphql | | **Python** | FastAPI · Django · SQLAlchemy · SQLModel · Pydantic · LangChain · CrewAI · Celery | | **Go** | Gin · Echo · GORM · sqlc · gRPC · Cobra · BubbleTea · Zap | +| **Java** | Spring Boot · Maven · Gradle · Spring Data JPA · Spring Security · JUnit · Testcontainers |
diff --git a/apps/cli/README.md b/apps/cli/README.md index 66b6bbecd..1041f486d 100644 --- a/apps/cli/README.md +++ b/apps/cli/README.md @@ -1,23 +1,28 @@ # Better Fullstack -Scaffold production-ready fullstack apps in seconds. Pick your stack from 270+ options — the CLI wires everything together. +Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options — the CLI wires everything together. ## Quick Start ```bash -# Using bun (recommended) -bun create better-fullstack@latest +# Using npm +npm create better-fullstack@latest + +# Using npx +npx create-better-fullstack@latest # Using pnpm pnpm create better-fullstack@latest -# Using npm -npx create-better-fullstack@latest +# Using bun +bun create better-fullstack@latest # Using yarn yarn create better-fullstack@latest ``` +Bun is required only when the generated project selects Bun as its runtime or package manager. Node.js with npm is enough for Node-based projects. + ## Web Builder Configure your stack visually — pick every option from a UI, preview your choices, and get a ready-to-run command. @@ -26,8 +31,8 @@ Configure your stack visually — pick every option from a UI, preview your choi ## Features -- **270+ options** — frontend, backend, database, auth, payments, AI, DevOps, and more -- **4 ecosystems** — TypeScript, Rust, Python, Go +- **424 options** — frontend, backend, database, auth, payments, AI, DevOps, and more +- **5 ecosystems** — TypeScript, Rust, Python, Go, Java - **Visual builder** — configure your stack in the browser - **Wired for you** — every picked integration is preconfigured and working out of the box @@ -37,7 +42,7 @@ Configure your stack visually — pick every option from a UI, preview your choi --yes # Accept all defaults --yolo # Scaffold a random stack — good for exploring --template # Use a preset (t3, mern, pern, uniwind) ---ecosystem # Start in rust, python, or go mode +--ecosystem # Start in typescript, rust, python, go, or java mode --version-channel # Dependency channel: stable, latest, beta --no-git # Skip git initialization --no-install # Skip dependency installation diff --git a/apps/cli/package.json b/apps/cli/package.json index 669b5c639..43f3a235a 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "create-better-fullstack", "version": "1.6.0", - "description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 340+ options — the CLI wires everything together.", + "description": "Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options — the CLI wires everything together.", "keywords": [ "algolia", "angular", diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index ae5888759..dd3267bff 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -144,6 +144,7 @@ import { type JavaAuth, JavaTestingLibrariesSchema, type JavaTestingLibraries, + OPTION_CATEGORY_METADATA, AiDocsSchema, type AiDocs, ShadcnBaseSchema, @@ -160,10 +161,15 @@ import { openUrl } from "./utils/open-url"; import { renderTitle } from "./utils/render-title"; import { displaySponsors, fetchSponsors } from "./utils/sponsors"; +const OPTION_ENTRY_COUNT = Object.values(OPTION_CATEGORY_METADATA).reduce( + (sum, metadata) => sum + metadata.options.length, + 0, +); + export const router = os.router({ create: os .meta({ - description: "Scaffold a new Better Fullstack project from 270+ compatible stack options", + description: `Scaffold a new Better Fullstack project from ${OPTION_ENTRY_COUNT} compatible stack options`, default: true, negateBooleans: true, }) diff --git a/apps/cli/src/mcp.ts b/apps/cli/src/mcp.ts index c7cdc7253..9826f9813 100644 --- a/apps/cli/src/mcp.ts +++ b/apps/cli/src/mcp.ts @@ -42,6 +42,7 @@ import { LoggingSchema, ObservabilitySchema, ORMSchema, + OPTION_CATEGORY_METADATA, PackageManagerSchema, PaymentsSchema, type ProjectConfig, @@ -79,7 +80,12 @@ import z from "zod"; import { readBtsConfig, writeBtsConfig } from "./utils/bts-config"; import { getLatestCLIVersion } from "./utils/get-latest-cli-version"; -const INSTRUCTIONS = `Better-Fullstack scaffolds fullstack projects across TypeScript, Rust, Go, Python, and Java ecosystems with 270+ configurable options. +const OPTION_ENTRY_COUNT = Object.values(OPTION_CATEGORY_METADATA).reduce( + (sum, metadata) => sum + metadata.options.length, + 0, +); + +const INSTRUCTIONS = `Better-Fullstack scaffolds fullstack projects across TypeScript, Rust, Go, Python, and Java ecosystems with ${OPTION_ENTRY_COUNT} configurable options. RECOMMENDED WORKFLOW: 1. Call bfs_get_guidance to understand field semantics, required fields, and workflow rules. diff --git a/apps/web/content/docs/ai/mcp.mdx b/apps/web/content/docs/ai/mcp.mdx new file mode 100644 index 000000000..0b0b50aba --- /dev/null +++ b/apps/web/content/docs/ai/mcp.mdx @@ -0,0 +1,41 @@ +--- +title: MCP +description: Connect Better Fullstack to MCP-compatible AI coding agents. +--- + +The MCP server lets agents scaffold projects through structured tool calls instead of guessing CLI flags. + +## Start the server + +```npm +npx create-better-fullstack@latest mcp +``` + +## Recommended tool order + +1. `bfs_get_guidance` +2. `bfs_get_schema` +3. `bfs_check_compatibility` +4. `bfs_plan_project` +5. `bfs_create_project` + +For existing projects: + +1. `bfs_plan_addition` +2. `bfs_add_feature` + +## Important rules + +- Dependency installation is skipped in MCP mode. +- Array fields include `frontend`, `addons`, `examples`, `aiDocs`, `rustLibraries`, `pythonAi`, `javaLibraries`, and `javaTestingLibraries`. +- `none` means “skip this feature.” +- TypeScript fields are ignored for Rust, Python, Go, and Java projects. +- Always validate compatibility before creating. + +## Agent prompt + +Use this prompt when you want an agent to create a project: + +```text +Use Better Fullstack MCP. First inspect guidance and schema, then validate the stack, then dry-run it. Only create the project after the dry-run succeeds. Skip dependency installation and tell me the exact commands to install, test, and run the project. +``` diff --git a/apps/web/content/docs/ai/meta.json b/apps/web/content/docs/ai/meta.json new file mode 100644 index 000000000..091f8075d --- /dev/null +++ b/apps/web/content/docs/ai/meta.json @@ -0,0 +1,5 @@ +{ + "title": "AI Agents", + "defaultOpen": true, + "pages": ["overview", "mcp"] +} diff --git a/apps/web/content/docs/ai/overview.mdx b/apps/web/content/docs/ai/overview.mdx new file mode 100644 index 000000000..e70fc22f1 --- /dev/null +++ b/apps/web/content/docs/ai/overview.mdx @@ -0,0 +1,48 @@ +--- +title: AI Agents +description: How AI coding agents should use Better Fullstack safely and quickly. +--- + +Better Fullstack is designed to work well with AI coding agents. Agents should use structured inputs, validate compatibility, preview output, and create projects only after the stack is clear. + +## Preferred workflow + +1. Determine the target ecosystem first: `typescript`, `rust`, `python`, `go`, or `java`. +2. Fetch valid schema/options. +3. Validate the requested stack. +4. Preview the generated file tree. +5. Scaffold with dependency installation disabled. +6. Tell the user the exact install and run commands. + +## CLI-first workflow + +For agents without MCP access: + +```npm +npm create better-fullstack@latest my-app -- \ + --ecosystem typescript \ + --frontend next \ + --backend self \ + --runtime none \ + --database postgres \ + --orm drizzle \ + --auth better-auth \ + --ai-docs agents-md \ + --no-install +``` + +## MCP workflow + +For MCP-compatible agents, use the Better Fullstack MCP server. It exposes tools for schema lookup, compatibility checks, dry-run previews, project creation, and feature additions. + +Read the [MCP guide](/docs/ai/mcp/) for setup. + +## Generated AI docs + +Use `--ai-docs` to generate project-local context files: + +```bash +--ai-docs agents-md claude-md cursorrules +``` + +Agents should update those files when they change project structure, dependencies, or workflows. diff --git a/apps/web/content/docs/cli/add.mdx b/apps/web/content/docs/cli/add.mdx new file mode 100644 index 000000000..3907fe886 --- /dev/null +++ b/apps/web/content/docs/cli/add.mdx @@ -0,0 +1,25 @@ +--- +title: Add Features +description: Add supported addons and deployment targets to existing Better Fullstack projects. +--- + +The `add` command reads the generated `bts.jsonc` file and applies supported additions to an existing project. + +```npm +npm create better-fullstack@latest add -- --addons mcp skills +``` + +## What it can add + +- AI-agent configuration through the `mcp` addon. +- Curated coding-agent skills through the `skills` addon. +- Documentation addons such as Starlight or Fumadocs when supported by the selected stack. +- Deployment target configuration where available. + +## Recommended workflow + +1. Commit or stash your current work. +2. Run `add` with explicit flags. +3. Review generated file changes. +4. Install dependencies if the addon introduced new packages. +5. Run the project’s test or typecheck command. diff --git a/apps/web/content/docs/cli/create.mdx b/apps/web/content/docs/cli/create.mdx new file mode 100644 index 000000000..855a3bebd --- /dev/null +++ b/apps/web/content/docs/cli/create.mdx @@ -0,0 +1,65 @@ +--- +title: Create Command +description: How to use create-better-fullstack to scaffold new projects. +--- + +The create command scaffolds a project from your selected stack. + +```npm +npm create better-fullstack@latest [project-name] -- [flags] +``` + +With `npm create`, pass Better Fullstack flags after `--`. The other launchers above pass flags directly. + +## Common flags + +| Flag | Purpose | +| --- | --- | +| `--dry-run` | Preview generated files without writing them. | +| `--yes` | Accept defaults. Do not combine with explicit stack flags. | +| `--template ` | Use a preset such as `t3`, `mern`, `pern`, or `uniwind`. | +| `--ecosystem ` | Start with `typescript`, `rust`, `python`, `go`, or `java`. | +| `--runtime ` | Choose the TypeScript server runtime, such as `node`, `bun`, or `none`. | +| `--ai-docs ` | Generate AI context files such as `agents-md` or `claude-md`. | +| `--addons ` | Add optional features such as `mcp`, `skills`, `turborepo`, or `starlight`. | +| `--no-install` | Skip dependency installation. Recommended for automation. | +| `--no-git` | Skip Git initialization. | +| `--package-manager ` | Choose dependency installation commands for generated projects: `npm`, `pnpm`, `yarn`, or `bun`. | + +## Explicit TypeScript example + +```npm +npm create better-fullstack@latest my-app -- \ + --frontend tanstack-router \ + --backend hono \ + --runtime node \ + --database sqlite \ + --orm drizzle \ + --api orpc \ + --auth better-auth \ + --package-manager npm \ + --addons turborepo \ + --ai-docs agents-md \ + --no-install +``` + +Bun is not required for this example because it selects `--runtime node` and `--package-manager npm`. If you select `--runtime bun` or `--package-manager bun`, install Bun before running the generated project commands. + +## Explicit Java example + +```npm +npm create better-fullstack@latest my-api -- \ + --ecosystem java \ + --java-web-framework spring-boot \ + --java-build-tool maven \ + --java-orm spring-data-jpa \ + --java-auth spring-security \ + --java-libraries spring-actuator flyway springdoc-openapi \ + --java-testing-libraries junit5 mockito testcontainers \ + --ai-docs agents-md \ + --no-install +``` + +## Automation rule + +For scripts and AI agents, use explicit flags and `--no-install`, then run installation after reviewing the generated files. diff --git a/apps/web/content/docs/cli/meta.json b/apps/web/content/docs/cli/meta.json new file mode 100644 index 000000000..55914b8fc --- /dev/null +++ b/apps/web/content/docs/cli/meta.json @@ -0,0 +1,5 @@ +{ + "title": "CLI", + "defaultOpen": true, + "pages": ["create", "add"] +} diff --git a/apps/web/content/docs/ecosystems/go.mdx b/apps/web/content/docs/ecosystems/go.mdx new file mode 100644 index 000000000..1d5539b13 --- /dev/null +++ b/apps/web/content/docs/ecosystems/go.mdx @@ -0,0 +1,228 @@ +--- +title: Go +description: API, service, and CLI projects with web frameworks, ORMs, gRPC, command-line tools, logging, and auth helpers. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +API, service, and CLI projects with web frameworks, ORMs, gRPC, command-line tools, logging, and auth helpers. + +This page is generated from the shared option metadata. It currently includes **75 options** across **15 categories**. + +## Prerequisites + +- Go toolchain +- Git + +## Create command + +```npm +npm create better-fullstack@latest my-go-api -- \ + --ecosystem go \ + --go-web-framework gin \ + --go-orm gorm \ + --go-logging zap \ + --no-install +``` + +## Categories + +### Go Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `gin` | Gin | `gin` | — | +| `echo` | Echo | `echo` | — | +| `fiber` | Fiber | `fiber` | — | +| `chi` | Chi | `chi` | — | +| `none` | None | `none` | — | + +### Go ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `gorm` | GORM | `gorm` | — | +| `sqlc` | sqlc | `sqlc` | — | +| `ent` | Ent | `ent` | — | +| `none` | None | `none` | — | + +### Go API + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `grpc-go` | gRPC-Go | `grpc-go` | — | +| `none` | None | `none` | — | + +### Go CLI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cobra` | Cobra | `cobra` | — | +| `bubbletea` | Bubble Tea | `bubbletea` | — | +| `none` | None | `none` | — | + +### Go Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zap` | Zap | `zap` | — | +| `zerolog` | Zerolog | `zerolog` | — | +| `slog` | slog | `slog` | — | +| `none` | None | `none` | — | + +### Go Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `casbin` | Casbin | `casbin` | — | +| `jwt` | golang-jwt | `jwt` | — | +| `none` | None | `none` | — | + +### Auth + +Authentication providers and auth libraries. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `better-auth` | Better-Auth | `better-auth` | — | +| `go-better-auth` | GoBetterAuth | `go-better-auth` | — | +| `clerk` | Clerk | `clerk` | — | +| `nextauth` | Auth.js (NextAuth) | `nextauth` | — | +| `stack-auth` | Stack Auth | `stack-auth` | — | +| `supabase-auth` | Supabase Auth | `supabase-auth` | — | +| `auth0` | Auth0 | `auth0` | — | +| `none` | No Auth | `none` | — | + +### Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +### AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +### Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +### Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +### Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +### App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +### Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +### Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/ecosystems/index.mdx b/apps/web/content/docs/ecosystems/index.mdx new file mode 100644 index 000000000..b044d4f8b --- /dev/null +++ b/apps/web/content/docs/ecosystems/index.mdx @@ -0,0 +1,114 @@ +--- +title: Ecosystems +description: Supported language ecosystems and their generated option groups. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Better Fullstack supports multiple language ecosystems from the same CLI and builder workflow. + +| Ecosystem | Scope | Options | +| --- | --- | --- | +| [TypeScript](/docs/ecosystems/typescript/) | Fullstack web, mobile, desktop, API, and worker projects with the broadest set of integrations. | 252 | +| [Rust](/docs/ecosystems/rust/) | Backend, CLI, WebAssembly frontend, GraphQL, gRPC, database, logging, caching, and auth scaffolds. | 81 | +| [Python](/docs/ecosystems/python/) | API and AI-oriented projects with web frameworks, ORMs, validation, task queues, GraphQL, and quality tooling. | 73 | +| [Go](/docs/ecosystems/go/) | API, service, and CLI projects with web frameworks, ORMs, gRPC, command-line tools, logging, and auth helpers. | 75 | +| [Java](/docs/ecosystems/java/) | Spring Boot and plain Java projects with Maven or Gradle wrappers, ORM, auth, application libraries, and testing libraries. | 63 | + +## Default CLI baseline + +The default project configuration below is generated from the shared default config with `npm` as the package manager. Runtime and package manager are separate choices; select `runtime: "node"` when you do not want a Bun runtime project. + +```json +{ + "projectName": "my-app", + "relativePath": "my-app", + "ecosystem": "typescript", + "database": "sqlite", + "orm": "drizzle", + "backend": "hono", + "runtime": "bun", + "frontend": [ + "tanstack-router" + ], + "addons": [ + "turborepo" + ], + "examples": [], + "auth": "better-auth", + "payments": "none", + "email": "none", + "fileUpload": "none", + "effect": "none", + "git": true, + "packageManager": "npm", + "versionChannel": "stable", + "install": true, + "dbSetup": "none", + "api": "trpc", + "webDeploy": "none", + "serverDeploy": "none", + "astroIntegration": "none", + "ai": "none", + "stateManagement": "none", + "forms": "react-hook-form", + "testing": "vitest", + "cssFramework": "tailwind", + "uiLibrary": "shadcn-ui", + "shadcnBase": "radix", + "shadcnStyle": "nova", + "shadcnIconLibrary": "lucide", + "shadcnColorTheme": "neutral", + "shadcnBaseColor": "neutral", + "shadcnFont": "inter", + "shadcnRadius": "default", + "validation": "zod", + "realtime": "none", + "jobQueue": "none", + "animation": "none", + "logging": "none", + "observability": "none", + "featureFlags": "none", + "analytics": "none", + "cms": "none", + "caching": "none", + "i18n": "none", + "search": "none", + "fileStorage": "none", + "rustWebFramework": "none", + "rustFrontend": "none", + "rustOrm": "none", + "rustApi": "none", + "rustCli": "none", + "rustLibraries": [], + "rustLogging": "tracing", + "rustErrorHandling": "anyhow-thiserror", + "rustCaching": "none", + "rustAuth": "none", + "pythonWebFramework": "fastapi", + "pythonOrm": "sqlalchemy", + "pythonValidation": "pydantic", + "pythonAi": [], + "pythonAuth": "none", + "pythonTaskQueue": "none", + "pythonGraphql": "none", + "pythonQuality": "ruff", + "goWebFramework": "gin", + "goOrm": "gorm", + "goApi": "none", + "goCli": "none", + "goLogging": "zap", + "goAuth": "none", + "javaWebFramework": "spring-boot", + "javaBuildTool": "maven", + "javaOrm": "none", + "javaAuth": "none", + "javaLibraries": [], + "javaTestingLibraries": [ + "junit5" + ], + "aiDocs": [ + "claude-md" + ] +} +``` \ No newline at end of file diff --git a/apps/web/content/docs/ecosystems/java.mdx b/apps/web/content/docs/ecosystems/java.mdx new file mode 100644 index 000000000..6f4eb0b80 --- /dev/null +++ b/apps/web/content/docs/ecosystems/java.mdx @@ -0,0 +1,212 @@ +--- +title: Java +description: Spring Boot and plain Java projects with Maven or Gradle wrappers, ORM, auth, application libraries, and testing libraries. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Spring Boot and plain Java projects with Maven or Gradle wrappers, ORM, auth, application libraries, and testing libraries. + +This page is generated from the shared option metadata. It currently includes **63 options** across **14 categories**. + +## Prerequisites + +- Java 21 +- Git + +## Create command + +```npm +npm create better-fullstack@latest my-java-api -- \ + --ecosystem java \ + --java-web-framework spring-boot \ + --java-build-tool maven \ + --java-orm spring-data-jpa \ + --java-auth spring-security \ + --java-libraries spring-actuator flyway springdoc-openapi \ + --java-testing-libraries junit5 mockito testcontainers \ + --no-install +``` + +## Categories + +### Java Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-boot` | Spring Boot | `spring-boot` | — | +| `none` | None | `none` | — | + +### Java Build Tool + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `maven` | Maven | `maven` | — | +| `gradle` | Gradle | `gradle` | — | +| `none` | None | `none` | — | + +### Java ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-data-jpa` | Spring Data JPA | `spring-data-jpa` | — | +| `none` | None | `none` | — | + +### Java Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-security` | Spring Security | `spring-security` | — | +| `none` | None | `none` | — | + +### Java Libraries + +Java application libraries emitted into Maven and Gradle templates. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-actuator` | Spring Boot Actuator | `spring-actuator` | — | +| `spring-validation` | Spring Validation | `spring-validation` | — | +| `flyway` | Flyway | `flyway` | — | +| `none` | None | `none` | — | + +### Java Testing Libraries + +Java testing libraries emitted into Maven and Gradle templates. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `junit5` | JUnit 5 | `junit5` | — | +| `mockito` | Mockito | `mockito` | — | +| `testcontainers` | Testcontainers | `testcontainers` | — | +| `none` | None | `none` | — | + +### Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +### AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +### Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +### Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +### Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +### App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +### Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +### Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/ecosystems/meta.json b/apps/web/content/docs/ecosystems/meta.json new file mode 100644 index 000000000..fa4c2a151 --- /dev/null +++ b/apps/web/content/docs/ecosystems/meta.json @@ -0,0 +1,5 @@ +{ + "title": "Ecosystems", + "defaultOpen": true, + "pages": ["index", "typescript", "rust", "python", "go", "java"] +} diff --git a/apps/web/content/docs/ecosystems/python.mdx b/apps/web/content/docs/ecosystems/python.mdx new file mode 100644 index 000000000..80dd4037a --- /dev/null +++ b/apps/web/content/docs/ecosystems/python.mdx @@ -0,0 +1,235 @@ +--- +title: Python +description: API and AI-oriented projects with web frameworks, ORMs, validation, task queues, GraphQL, and quality tooling. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +API and AI-oriented projects with web frameworks, ORMs, validation, task queues, GraphQL, and quality tooling. + +This page is generated from the shared option metadata. It currently includes **73 options** across **16 categories**. + +## Prerequisites + +- Python +- uv +- Git + +## Create command + +```npm +npm create better-fullstack@latest my-python-api -- \ + --ecosystem python \ + --python-web-framework fastapi \ + --python-orm sqlalchemy \ + --python-validation pydantic \ + --python-quality ruff \ + --no-install +``` + +## Categories + +### Python Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `fastapi` | FastAPI | `fastapi` | — | +| `django` | Django | `django` | — | +| `flask` | Flask | `flask` | — | +| `litestar` | Litestar | `litestar` | — | +| `none` | None | `none` | — | + +### Python ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `sqlalchemy` | SQLAlchemy | `sqlalchemy` | — | +| `sqlmodel` | SQLModel | `sqlmodel` | — | +| `tortoise-orm` | Tortoise ORM | `tortoise-orm` | — | +| `none` | None | `none` | — | + +### Python Validation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `pydantic` | Pydantic | `pydantic` | — | +| `none` | None | `none` | — | + +### Python AI + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `langchain` | LangChain | `langchain` | — | +| `llamaindex` | LlamaIndex | `llamaindex` | — | +| `openai-sdk` | OpenAI SDK | `openai-sdk` | — | +| `anthropic-sdk` | Anthropic SDK | `anthropic-sdk` | — | +| `langgraph` | LangGraph | `langgraph` | — | +| `crewai` | CrewAI | `crewai` | — | +| `none` | None | `none` | — | + +### Python Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `authlib` | Authlib | `authlib` | — | +| `jwt` | JWT (python-jose) | `jwt` | — | +| `none` | None | `none` | — | + +### Python Task Queue + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `celery` | Celery | `celery` | — | +| `none` | None | `none` | — | + +### Python Graphql + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `strawberry` | Strawberry | `strawberry` | — | +| `none` | None | `none` | — | + +### Python Quality + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ruff` | Ruff | `ruff` | — | +| `none` | None | `none` | — | + +### Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +### AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +### Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +### Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +### Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +### App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +### Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +### Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/ecosystems/rust.mdx b/apps/web/content/docs/ecosystems/rust.mdx new file mode 100644 index 000000000..5a010b919 --- /dev/null +++ b/apps/web/content/docs/ecosystems/rust.mdx @@ -0,0 +1,258 @@ +--- +title: Rust +description: Backend, CLI, WebAssembly frontend, GraphQL, gRPC, database, logging, caching, and auth scaffolds. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Backend, CLI, WebAssembly frontend, GraphQL, gRPC, database, logging, caching, and auth scaffolds. + +This page is generated from the shared option metadata. It currently includes **81 options** across **18 categories**. + +## Prerequisites + +- Rust toolchain +- Cargo +- Git + +## Create command + +```npm +npm create better-fullstack@latest my-rust-api -- \ + --ecosystem rust \ + --rust-web-framework axum \ + --rust-orm sea-orm \ + --rust-libraries serde validator \ + --no-install +``` + +## Categories + +### Rust Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `axum` | Axum | `axum` | — | +| `actix-web` | Actix-web | `actix-web` | — | +| `rocket` | Rocket | `rocket` | — | +| `none` | None | `none` | — | + +### Rust Frontend + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `leptos` | Leptos | `leptos` | — | +| `dioxus` | Dioxus | `dioxus` | — | +| `none` | None | `none` | — | + +### Rust ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `sea-orm` | SeaORM | `sea-orm` | — | +| `sqlx` | SQLx | `sqlx` | — | +| `diesel` | Diesel | `diesel` | — | +| `none` | None | `none` | — | + +### Rust API + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tonic` | Tonic | `tonic` | — | +| `async-graphql` | async-graphql | `async-graphql` | — | +| `none` | None | `none` | — | + +### Rust CLI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `clap` | Clap | `clap` | — | +| `ratatui` | Ratatui | `ratatui` | — | +| `none` | None | `none` | — | + +### Rust Libraries + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `serde` | Serde | `serde` | — | +| `validator` | Validator | `validator` | — | +| `jsonwebtoken` | jsonwebtoken | `jsonwebtoken` | — | +| `argon2` | Argon2 | `argon2` | — | +| `tokio-test` | Tokio Test | `tokio-test` | — | +| `mockall` | Mockall | `mockall` | — | +| `none` | None | `none` | — | + +### Rust Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tracing` | Tracing | `tracing` | — | +| `env-logger` | env_logger | `env-logger` | — | +| `none` | None | `none` | — | + +### Rust Error Handling + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `anyhow-thiserror` | anyhow + thiserror | `anyhow-thiserror` | — | +| `eyre` | eyre + color-eyre | `eyre` | — | +| `none` | None | `none` | — | + +### Rust Caching + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `moka` | Moka | `moka` | — | +| `redis` | Redis | `redis` | — | +| `none` | None | `none` | — | + +### Rust Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `oauth2` | OAuth2 | `oauth2` | — | +| `none` | None | `none` | — | + +### Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +### AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +### Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +### Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +### Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +### App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +### Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +### Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/ecosystems/typescript.mdx b/apps/web/content/docs/ecosystems/typescript.mdx new file mode 100644 index 000000000..2a86f794d --- /dev/null +++ b/apps/web/content/docs/ecosystems/typescript.mdx @@ -0,0 +1,611 @@ +--- +title: TypeScript +description: Fullstack web, mobile, desktop, API, and worker projects with the broadest set of integrations. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Fullstack web, mobile, desktop, API, and worker projects with the broadest set of integrations. + +This page is generated from the shared option metadata. It currently includes **252 options** across **39 categories**. + +## Prerequisites + +- Node.js 20+ +- npm, pnpm, Yarn, or Bun +- Git + +## Create command + +```npm +npm create better-fullstack@latest my-app -- \ + --frontend tanstack-router \ + --backend hono \ + --runtime node \ + --database sqlite \ + --orm drizzle \ + --api orpc \ + --auth better-auth \ + --package-manager npm \ + --addons turborepo \ + --no-install +``` + +## Categories + +### Web Frontend + +Browser-facing frontend frameworks and app routers. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tanstack-router` | Tanstack Router | `tanstack-router` | — | +| `react-router` | React Router | `react-router` | — | +| `react-vite` | React + Vite | `react-vite` | — | +| `tanstack-start` | Tanstack Start | `tanstack-start` | — | +| `next` | Next.js | `next` | — | +| `nuxt` | Nuxt | `nuxt` | — | +| `svelte` | SvelteKit | `svelte` | sveltekit | +| `solid` | Solid | `solid` | — | +| `solid-start` | Solid Start | `solid-start` | — | +| `astro` | Astro | `astro` | — | +| `qwik` | Qwik | `qwik` | — | +| `angular` | Angular | `angular` | — | +| `redwood` | RedwoodJS | `redwood` | — | +| `fresh` | Fresh | `fresh` | — | +| `none` | None | `none` | — | + +### Native Frontend + +React Native and Expo targets. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `native-bare` | Expo + Bare | `native-bare` | — | +| `native-uniwind` | Expo + Uniwind | `native-uniwind` | — | +| `native-unistyles` | Expo + Unistyles | `native-unistyles` | — | +| `none` | None | `none` | — | + +### Backend + +Server frameworks and fullstack self-backend modes. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `hono` | Hono | `hono` | — | +| `express` | Express | `express` | — | +| `fastify` | Fastify | `fastify` | — | +| `elysia` | Elysia | `elysia` | — | +| `fets` | feTS | `fets` | — | +| `nestjs` | NestJS | `nestjs` | — | +| `adonisjs` | Adonisjs | `adonisjs` | — | +| `nitro` | Nitro | `nitro` | — | +| `encore` | Encore.ts | `encore` | — | +| `convex` | Convex | `convex` | — | +| `self-next` | Fullstack Next.js | `self` | — | +| `self-tanstack-start` | Fullstack TanStack Start | `self` | — | +| `self-astro` | Fullstack Astro | `self` | — | +| `self-nuxt` | Fullstack Nuxt | `self` | — | +| `self-svelte` | Fullstack SvelteKit | `self` | self-sveltekit | +| `self-solid-start` | Fullstack SolidStart | `self` | — | +| `none` | None | `none` | — | + +### Runtime + +JavaScript runtime selection for generated TypeScript services. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `bun` | Bun | `bun` | — | +| `node` | Node.js | `node` | — | +| `workers` | Cloudflare Workers | `workers` | — | +| `none` | None | `none` | — | + +### Database + +Database engines used by generated app templates. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `none` | None | `none` | — | +| `sqlite` | SQLite | `sqlite` | — | +| `postgres` | PostgreSQL | `postgres` | — | +| `mysql` | Mysql | `mysql` | — | +| `mongodb` | MongoDB | `mongodb` | — | +| `edgedb` | EdgeDB | `edgedb` | — | +| `redis` | Redis | `redis` | — | + +### ORM + +Database access libraries and ORMs. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `drizzle` | Drizzle | `drizzle` | — | +| `prisma` | Prisma | `prisma` | — | +| `mongoose` | Mongoose | `mongoose` | — | +| `typeorm` | TypeORM | `typeorm` | — | +| `kysely` | Kysely | `kysely` | — | +| `mikroorm` | MikroORM | `mikroorm` | — | +| `sequelize` | Sequelize | `sequelize` | — | +| `none` | None | `none` | — | + +### DB Setup + +Optional database provisioning helpers. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turso` | Turso | `turso` | — | +| `neon` | Neon Postgres | `neon` | — | +| `prisma-postgres` | Prisma PostgreSQL | `prisma-postgres` | — | +| `planetscale` | PlanetScale | `planetscale` | — | +| `mongodb-atlas` | MongoDB Atlas | `mongodb-atlas` | — | +| `supabase` | Supabase | `supabase` | — | +| `upstash` | Upstash | `upstash` | — | +| `d1` | Cloudflare D1 | `d1` | — | +| `docker` | Docker | `docker` | — | +| `none` | None | `none` | — | + +### API + +API layers and type-safe transport choices. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `trpc` | tRPC | `trpc` | — | +| `orpc` | oRPC | `orpc` | — | +| `ts-rest` | Ts Rest | `ts-rest` | — | +| `garph` | Garph | `garph` | — | +| `graphql-yoga` | GraphQL Yoga | `graphql-yoga` | — | +| `none` | None | `none` | — | + +### Auth + +Authentication providers and auth libraries. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `better-auth` | Better-Auth | `better-auth` | — | +| `go-better-auth` | GoBetterAuth | `go-better-auth` | — | +| `clerk` | Clerk | `clerk` | — | +| `nextauth` | Auth.js (NextAuth) | `nextauth` | — | +| `stack-auth` | Stack Auth | `stack-auth` | — | +| `supabase-auth` | Supabase Auth | `supabase-auth` | — | +| `auth0` | Auth0 | `auth0` | — | +| `none` | No Auth | `none` | — | + +### Payments + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `polar` | Polar | `polar` | — | +| `stripe` | Stripe | `stripe` | — | +| `lemon-squeezy` | Lemon Squeezy | `lemon-squeezy` | — | +| `paddle` | Paddle | `paddle` | — | +| `dodo` | Dodo Payments | `dodo` | — | +| `none` | None | `none` | — | + +### Email + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `react-email` | React Email | `react-email` | — | +| `resend` | Resend | `resend` | — | +| `nodemailer` | Nodemailer | `nodemailer` | — | +| `postmark` | Postmark | `postmark` | — | +| `sendgrid` | SendGrid | `sendgrid` | — | +| `aws-ses` | AWS SES | `aws-ses` | — | +| `mailgun` | Mailgun | `mailgun` | — | +| `plunk` | Plunk | `plunk` | — | +| `none` | None | `none` | — | + +### File Upload + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `uploadthing` | UploadThing | `uploadthing` | — | +| `filepond` | FilePond | `filepond` | — | +| `uppy` | Uppy | `uppy` | — | +| `none` | None | `none` | — | + +### AI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `vercel-ai` | Vercel AI SDK | `vercel-ai` | — | +| `mastra` | Mastra | `mastra` | — | +| `voltagent` | VoltAgent | `voltagent` | — | +| `langgraph` | LangGraph.js | `langgraph` | — | +| `openai-agents` | OpenAI Agents SDK | `openai-agents` | — | +| `google-adk` | Google ADK | `google-adk` | — | +| `modelfusion` | ModelFusion | `modelfusion` | — | +| `langchain` | LangChain | `langchain` | — | +| `llamaindex` | LlamaIndex | `llamaindex` | — | +| `tanstack-ai` | TanStack AI | `tanstack-ai` | — | +| `none` | None | `none` | — | + +### State Management + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zustand` | Zustand | `zustand` | — | +| `jotai` | Jotai | `jotai` | — | +| `nanostores` | Nanostores | `nanostores` | — | +| `redux-toolkit` | Redux Toolkit | `redux-toolkit` | — | +| `mobx` | Mobx | `mobx` | — | +| `xstate` | XState | `xstate` | — | +| `valtio` | Valtio | `valtio` | — | +| `tanstack-store` | Tanstack Store | `tanstack-store` | — | +| `legend-state` | Legend State | `legend-state` | — | +| `none` | None | `none` | — | + +### Forms + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tanstack-form` | TanStack Form | `tanstack-form` | — | +| `react-hook-form` | React Hook Form | `react-hook-form` | — | +| `formik` | Formik | `formik` | — | +| `final-form` | Final Form | `final-form` | — | +| `conform` | Conform | `conform` | — | +| `modular-forms` | Modular Forms | `modular-forms` | — | +| `none` | None | `none` | — | + +### Validation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zod` | Zod | `zod` | — | +| `valibot` | Valibot | `valibot` | — | +| `arktype` | ArkType | `arktype` | — | +| `typebox` | TypeBox | `typebox` | — | +| `typia` | Typia | `typia` | — | +| `runtypes` | Runtypes | `runtypes` | — | +| `effect-schema` | @effect/schema | `effect-schema` | — | +| `none` | None | `none` | — | + +### Testing + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `vitest` | Vitest | `vitest` | — | +| `playwright` | Playwright | `playwright` | — | +| `vitest-playwright` | Vitest + Playwright | `vitest-playwright` | — | +| `jest` | Jest | `jest` | — | +| `cypress` | Cypress | `cypress` | — | +| `none` | None | `none` | — | + +### Realtime + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `socket-io` | Socket.IO | `socket-io` | — | +| `partykit` | Partykit | `partykit` | — | +| `ably` | Ably | `ably` | — | +| `pusher` | Pusher | `pusher` | — | +| `liveblocks` | Liveblocks | `liveblocks` | — | +| `yjs` | Y.js | `yjs` | — | +| `none` | None | `none` | — | + +### Job Queue + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `bullmq` | BullMQ | `bullmq` | — | +| `trigger-dev` | Trigger.dev | `trigger-dev` | — | +| `inngest` | Inngest | `inngest` | — | +| `temporal` | Temporal | `temporal` | — | +| `none` | None | `none` | — | + +### Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `pino` | Pino | `pino` | — | +| `winston` | Winston | `winston` | — | +| `none` | None | `none` | — | + +### Observability + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `opentelemetry` | OpenTelemetry | `opentelemetry` | — | +| `sentry` | Sentry | `sentry` | — | +| `grafana` | Grafana | `grafana` | — | +| `none` | None | `none` | — | + +### Feature Flags + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `growthbook` | GrowthBook | `growthbook` | — | +| `posthog` | PostHog | `posthog` | — | +| `none` | None | `none` | — | + +### Analytics + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `plausible` | Plausible | `plausible` | — | +| `umami` | Umami | `umami` | — | +| `none` | None | `none` | — | + +### Cms + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `payload` | Payload | `payload` | — | +| `sanity` | Sanity | `sanity` | — | +| `strapi` | Strapi | `strapi` | — | +| `tinacms` | TinaCMS | `tinacms` | — | +| `none` | None | `none` | — | + +### Caching + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `upstash-redis` | Upstash Redis | `upstash-redis` | — | +| `none` | None | `none` | — | + +### I18n + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `i18next` | i18next | `i18next` | — | +| `next-intl` | next-intl | `next-intl` | — | +| `none` | None | `none` | — | + +### Search + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `meilisearch` | Meilisearch | `meilisearch` | — | +| `typesense` | Typesense | `typesense` | — | +| `elasticsearch` | Elasticsearch | `elasticsearch` | — | +| `algolia` | Algolia | `algolia` | — | +| `none` | None | `none` | — | + +### File Storage + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `s3` | S3 | `s3` | — | +| `r2` | R2 | `r2` | — | +| `none` | None | `none` | — | + +### Animation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `framer-motion` | Framer Motion | `framer-motion` | — | +| `gsap` | Gsap | `gsap` | — | +| `react-spring` | React Spring | `react-spring` | — | +| `auto-animate` | Auto Animate | `auto-animate` | — | +| `lottie` | Lottie | `lottie` | — | +| `none` | None | `none` | — | + +### Css Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tailwind` | Tailwind CSS | `tailwind` | — | +| `scss` | SCSS | `scss` | — | +| `less` | Less | `less` | — | +| `postcss-only` | PostCSS Only | `postcss-only` | — | +| `none` | None | `none` | — | + +### Ui Library + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `shadcn-ui` | shadcn/ui | `shadcn-ui` | — | +| `daisyui` | daisyUI | `daisyui` | — | +| `radix-ui` | Radix UI | `radix-ui` | — | +| `headless-ui` | Headless UI | `headless-ui` | — | +| `park-ui` | Park UI | `park-ui` | — | +| `chakra-ui` | Chakra UI | `chakra-ui` | — | +| `nextui` | NextUI | `nextui` | — | +| `mantine` | Mantine | `mantine` | — | +| `base-ui` | Base UI | `base-ui` | — | +| `ark-ui` | Ark UI | `ark-ui` | — | +| `react-aria` | React Aria | `react-aria` | — | +| `none` | None | `none` | — | + +### Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +### AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +### Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +### Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +### Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +### App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +### Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +### Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/getting-started/first-project.mdx b/apps/web/content/docs/getting-started/first-project.mdx new file mode 100644 index 000000000..d9e268eb9 --- /dev/null +++ b/apps/web/content/docs/getting-started/first-project.mdx @@ -0,0 +1,75 @@ +--- +title: First Project +description: Scaffold, inspect, install, and run a Better Fullstack project. +--- + +This flow creates a project, lets you inspect the generated files, then installs dependencies. + +Use the package-manager tabs to copy the launcher that matches your workflow. + +## 1. Preview the project + +Use `--dry-run` when you want to see what will be generated before writing files. + +```npm +npm create better-fullstack@latest my-app -- --dry-run +``` + +## 2. Scaffold the project + +Run the CLI interactively: + +```npm +npm create better-fullstack@latest my-app +``` + +Or pass explicit choices: + +```npm +npm create better-fullstack@latest my-app -- \ + --frontend next \ + --backend self \ + --runtime node \ + --database postgres \ + --orm drizzle \ + --auth better-auth \ + --api trpc +``` + +## 3. Install dependencies + +If you selected `--no-install`, install manually inside the generated project with the package manager selected for that project: + +```npm +cd my-app +npm install +``` + +The runtime choice is separate. A Node runtime project can install with npm, pnpm, Yarn, or Bun; a Bun runtime project requires Bun to run server code. + +For non-TypeScript ecosystems, use the ecosystem’s package manager or generated wrapper: + +```bash +cargo build +uv sync +go mod tidy +./mvnw test +./gradlew test +``` + +## 4. Read the project context + +Generated projects include: + +- `bts.jsonc` with the selected stack. +- A reproducible command printed by the CLI. +- Optional AI docs such as `Agents.md`, `CLAUDE.md`, or `.cursorrules`. +- Framework-specific readme and commands. + +## 5. Add features later + +Inside a generated project, use the `add` command for supported addons and deployment targets: + +```npm +npm create better-fullstack@latest add -- --addons mcp skills +``` diff --git a/apps/web/content/docs/getting-started/installation.mdx b/apps/web/content/docs/getting-started/installation.mdx new file mode 100644 index 000000000..5845f5643 --- /dev/null +++ b/apps/web/content/docs/getting-started/installation.mdx @@ -0,0 +1,88 @@ +--- +title: Installation +description: Required tools and package-manager setup before using Better Fullstack. +--- + +Before scaffolding projects, install the runtime and tools required by the ecosystem you plan to use. + +## Required for everyone + +### Node.js + +Install Node.js 20 or newer. The CLI is published to npm, and most generated TypeScript tooling relies on the Node.js ecosystem. + +- [Download Node.js](https://nodejs.org/en/download) +- [Node.js package manager guide](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) + +### Git + +Install Git if you want the CLI to initialize a repository or if you plan to use generated projects with normal source-control workflows. + +- [Download Git](https://git-scm.com/downloads) + +### A package manager + +Better Fullstack supports npm, pnpm, Yarn, and Bun. Use the one you already have unless your stack explicitly chooses Bun. + +There are three separate choices: + +| Concept | What it controls | Examples | +| --- | --- | --- | +| CLI launcher | How you run the scaffold command | `npm create`, `npx`, `pnpm create`, `bun create`, `yarn create` | +| JavaScript runtime | How generated TypeScript server code runs | `node`, `bun`, or `none` for frontend-only/static stacks | +| Project package manager | How dependencies are installed in the generated project | `npm`, `pnpm`, `yarn`, or `bun` | + +Node + npm is enough for Node-based projects. Use the tabs to see equivalent commands for other package managers: + +```npm +npm create better-fullstack@latest my-app +``` + +When you pass flags through `npm create`, add `--` before Better Fullstack flags: + +```npm +npm create better-fullstack@latest my-app -- --frontend next --runtime node +``` + +Bun is required only when you select Bun as the generated app runtime, choose Bun as the generated project package manager, or work inside this repository. + +## Ecosystem tools + +Install these only when you scaffold projects for that ecosystem. + +| Ecosystem | Required tools | Links | +| --- | --- | --- | +| TypeScript | Node.js plus your package manager; Bun only for Bun runtime/package-manager choices | [Node.js](https://nodejs.org/) · [Bun](https://bun.sh/) | +| Rust | Rust toolchain and Cargo | [Install Rust](https://www.rust-lang.org/tools/install) | +| Python | Python and uv | [Python](https://www.python.org/downloads/) · [uv](https://docs.astral.sh/uv/) | +| Go | Go toolchain | [Download Go](https://go.dev/dl/) | +| Java | Java 21; generated Maven/Gradle wrappers handle the build tool | [Eclipse Temurin](https://adoptium.net/temurin/releases/) · [Java downloads](https://www.oracle.com/java/technologies/downloads/) | + +## Verify your machine + +Run the commands relevant to your stack: + +```bash +node --version +git --version +``` + +```npm +npm --version +``` + +```bash +rustc --version +python --version +uv --version +go version +java -version +``` + +## Non-interactive setup + +For CI and AI-agent workflows, prefer explicit flags and skip dependency installation until after the project is created: + +```npm +npm create better-fullstack@latest my-app -- --no-install --no-git --ai-docs agents-md +``` diff --git a/apps/web/content/docs/getting-started/meta.json b/apps/web/content/docs/getting-started/meta.json new file mode 100644 index 000000000..e632bff36 --- /dev/null +++ b/apps/web/content/docs/getting-started/meta.json @@ -0,0 +1,5 @@ +{ + "title": "Getting Started", + "defaultOpen": true, + "pages": ["installation", "first-project"] +} diff --git a/apps/web/content/docs/index.mdx b/apps/web/content/docs/index.mdx new file mode 100644 index 000000000..c7b56bdaf --- /dev/null +++ b/apps/web/content/docs/index.mdx @@ -0,0 +1,75 @@ +--- +title: Get Started +description: Install the required tools and scaffold your first Better Fullstack project. +--- + +Start here when you want a project generated quickly with explicit, reproducible stack choices. + +## 1. Install the required tools + +Everyone needs Node.js 20 or newer and Git. Bun is optional unless you choose Bun as the project runtime or package manager. + +- [Download Node.js](https://nodejs.org/en/download) +- [Download Git](https://git-scm.com/downloads) +- [Install Bun](https://bun.sh/docs/installation) + +```bash +node --version +git --version +``` + +If you plan to use Bun, verify it too: + +```bash +bun --version +``` + +For Rust, Python, Go, or Java projects, install the matching ecosystem toolchain before running generated project commands. The CLI can still be launched with Node.js even when the generated app targets another ecosystem. + +| Ecosystem | Tooling | +| --- | --- | +| TypeScript | Node.js plus npm, pnpm, Yarn, or Bun | +| Rust | Rust toolchain and Cargo | +| Python | Python and uv | +| Go | Go toolchain | +| Java | Java 21; generated Maven or Gradle wrappers handle builds | + +## 2. Create a project + +Use the interactive flow when exploring choices. Select your preferred package manager to run the create package: + +```npm +npm create better-fullstack@latest my-app +``` + +Use explicit flags when you already know the stack: + +```npm +npm create better-fullstack@latest my-app -- \ + --frontend next \ + --backend self \ + --runtime node \ + --database postgres \ + --orm drizzle \ + --auth better-auth \ + --api trpc +``` + +## 3. Inspect before installing + +For CI and AI-agent workflows, scaffold first and install dependencies after you inspect the generated files. + +```npm +npm create better-fullstack@latest my-app -- --no-install --no-git --ai-docs agents-md +cd my-app +npm install +``` + +Use `bun install`, `pnpm install`, or `yarn install` instead when the generated project was configured for that package manager. Generated projects include `bts.jsonc`, a reproducible command, framework scripts, and optional AI documentation files. + +## 4. Next steps + +- Read [Installation](/docs/getting-started/installation/) for ecosystem prerequisites. +- Read [First Project](/docs/getting-started/first-project/) for dry-runs, install flow, and generated project context. +- Open [CLI Create](/docs/cli/create/) for the non-interactive command surface. +- Open [Ecosystems](/docs/ecosystems/) to compare TypeScript, Rust, Python, Go, and Java support. diff --git a/apps/web/content/docs/meta.json b/apps/web/content/docs/meta.json new file mode 100644 index 000000000..7d20e1f81 --- /dev/null +++ b/apps/web/content/docs/meta.json @@ -0,0 +1,16 @@ +{ + "title": "Better Fullstack", + "pages": [ + "index", + "---Start Here---", + "getting-started", + "---CLI---", + "cli", + "---Ecosystems---", + "ecosystems", + "---AI Agents---", + "ai", + "---Reference---", + "reference" + ] +} diff --git a/apps/web/content/docs/reference/llms.mdx b/apps/web/content/docs/reference/llms.mdx new file mode 100644 index 000000000..730c91b85 --- /dev/null +++ b/apps/web/content/docs/reference/llms.mdx @@ -0,0 +1,21 @@ +--- +title: Generated llms.txt +description: Machine-readable project context for AI agents. +--- + +Better Fullstack publishes an `llms.txt` file for AI agents and search tools. + +- Site-level file: [`/llms.txt`](https://better-fullstack.dev/llms.txt) +- Docs-specific file: [`/docs/llms.txt`](https://better-fullstack.dev/docs/llms.txt) + +The docs-specific file is generated from the same metadata used to build the option reference pages. + +## Why it exists + +`llms.txt` gives agents a compact, text-first overview of: + +- What Better Fullstack does. +- Supported ecosystems. +- Important pages. +- Recommended CLI and MCP workflows. +- Links to dynamic option reference pages. diff --git a/apps/web/content/docs/reference/meta.json b/apps/web/content/docs/reference/meta.json new file mode 100644 index 000000000..7d1bdcc6f --- /dev/null +++ b/apps/web/content/docs/reference/meta.json @@ -0,0 +1,5 @@ +{ + "title": "Reference", + "defaultOpen": true, + "pages": ["options", "llms"] +} diff --git a/apps/web/content/docs/reference/options/go.mdx b/apps/web/content/docs/reference/options/go.mdx new file mode 100644 index 000000000..7af1cda88 --- /dev/null +++ b/apps/web/content/docs/reference/options/go.mdx @@ -0,0 +1,81 @@ +--- +title: "Go Options" +description: "Go-ecosystem categories: web framework, ORM, API, CLI, logging, auth." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Categories applied when scaffolding a Go project. + +This page covers **21 options** across **6 categories**. + +Use CLI values in commands and MCP payloads. + +## Go Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `gin` | Gin | `gin` | — | +| `echo` | Echo | `echo` | — | +| `fiber` | Fiber | `fiber` | — | +| `chi` | Chi | `chi` | — | +| `none` | None | `none` | — | + +## Go ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `gorm` | GORM | `gorm` | — | +| `sqlc` | sqlc | `sqlc` | — | +| `ent` | Ent | `ent` | — | +| `none` | None | `none` | — | + +## Go API + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `grpc-go` | gRPC-Go | `grpc-go` | — | +| `none` | None | `none` | — | + +## Go CLI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cobra` | Cobra | `cobra` | — | +| `bubbletea` | Bubble Tea | `bubbletea` | — | +| `none` | None | `none` | — | + +## Go Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zap` | Zap | `zap` | — | +| `zerolog` | Zerolog | `zerolog` | — | +| `slog` | slog | `slog` | — | +| `none` | None | `none` | — | + +## Go Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `casbin` | Casbin | `casbin` | — | +| `jwt` | golang-jwt | `jwt` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/reference/options/index.mdx b/apps/web/content/docs/reference/options/index.mdx new file mode 100644 index 000000000..3ab9d0e77 --- /dev/null +++ b/apps/web/content/docs/reference/options/index.mdx @@ -0,0 +1,21 @@ +--- +title: Options +description: Generated reference for Better Fullstack stack options. +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +This reference is generated from `packages/types/src/option-metadata.ts`. It currently includes **424 option entries** across **82 categories**, grouped into focused sub-pages. + +Use CLI values in commands and MCP payloads. Some builder-only labels normalize to the same CLI value. + +| Section | Scope | Categories | Options | +| --- | --- | --- | --- | +| [Core Stack](/docs/reference/options/stack/) | Framework, runtime, database, ORM, API, and auth options. | 10 | 84 | +| [Services & Integrations](/docs/reference/options/services/) | Payments, email, file upload, realtime, jobs, search, CMS, AI, analytics. | 13 | 66 | +| [UI, Forms & State](/docs/reference/options/ui/) | CSS frameworks, UI libraries, state management, forms, validation, animation. | 15 | 108 | +| [Tooling, Deploy & Ops](/docs/reference/options/tooling/) | Testing, logging, observability, code quality, deploy targets, package manager. | 14 | 66 | +| [Rust Options](/docs/reference/options/rust/) | Rust-ecosystem categories: web framework, ORM, API, CLI, libraries, auth. | 10 | 35 | +| [Python Options](/docs/reference/options/python/) | Python-ecosystem categories: web framework, ORM, validation, AI, quality. | 8 | 27 | +| [Go Options](/docs/reference/options/go/) | Go-ecosystem categories: web framework, ORM, API, CLI, logging, auth. | 6 | 21 | +| [Java Options](/docs/reference/options/java/) | Java-ecosystem categories: web framework, build tool, ORM, auth, libraries. | 6 | 17 | diff --git a/apps/web/content/docs/reference/options/java.mdx b/apps/web/content/docs/reference/options/java.mdx new file mode 100644 index 000000000..673eafcdf --- /dev/null +++ b/apps/web/content/docs/reference/options/java.mdx @@ -0,0 +1,79 @@ +--- +title: "Java Options" +description: "Java-ecosystem categories: web framework, build tool, ORM, auth, libraries." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Categories applied when scaffolding a Java project. + +This page covers **17 options** across **6 categories**. + +Use CLI values in commands and MCP payloads. + +## Java Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-boot` | Spring Boot | `spring-boot` | — | +| `none` | None | `none` | — | + +## Java Build Tool + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `maven` | Maven | `maven` | — | +| `gradle` | Gradle | `gradle` | — | +| `none` | None | `none` | — | + +## Java ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-data-jpa` | Spring Data JPA | `spring-data-jpa` | — | +| `none` | None | `none` | — | + +## Java Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-security` | Spring Security | `spring-security` | — | +| `none` | None | `none` | — | + +## Java Libraries + +Java application libraries emitted into Maven and Gradle templates. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `spring-actuator` | Spring Boot Actuator | `spring-actuator` | — | +| `spring-validation` | Spring Validation | `spring-validation` | — | +| `flyway` | Flyway | `flyway` | — | +| `none` | None | `none` | — | + +## Java Testing Libraries + +Java testing libraries emitted into Maven and Gradle templates. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `junit5` | JUnit 5 | `junit5` | — | +| `mockito` | Mockito | `mockito` | — | +| `testcontainers` | Testcontainers | `testcontainers` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/reference/options/meta.json b/apps/web/content/docs/reference/options/meta.json new file mode 100644 index 000000000..5154595c1 --- /dev/null +++ b/apps/web/content/docs/reference/options/meta.json @@ -0,0 +1,5 @@ +{ + "title": "Options", + "defaultOpen": true, + "pages": ["index", "stack", "services", "ui", "tooling", "rust", "python", "go", "java"] +} diff --git a/apps/web/content/docs/reference/options/python.mdx b/apps/web/content/docs/reference/options/python.mdx new file mode 100644 index 000000000..bd1beac21 --- /dev/null +++ b/apps/web/content/docs/reference/options/python.mdx @@ -0,0 +1,103 @@ +--- +title: "Python Options" +description: "Python-ecosystem categories: web framework, ORM, validation, AI, quality." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Categories applied when scaffolding a Python project. + +This page covers **27 options** across **8 categories**. + +Use CLI values in commands and MCP payloads. + +## Python Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `fastapi` | FastAPI | `fastapi` | — | +| `django` | Django | `django` | — | +| `flask` | Flask | `flask` | — | +| `litestar` | Litestar | `litestar` | — | +| `none` | None | `none` | — | + +## Python ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `sqlalchemy` | SQLAlchemy | `sqlalchemy` | — | +| `sqlmodel` | SQLModel | `sqlmodel` | — | +| `tortoise-orm` | Tortoise ORM | `tortoise-orm` | — | +| `none` | None | `none` | — | + +## Python Validation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `pydantic` | Pydantic | `pydantic` | — | +| `none` | None | `none` | — | + +## Python AI + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `langchain` | LangChain | `langchain` | — | +| `llamaindex` | LlamaIndex | `llamaindex` | — | +| `openai-sdk` | OpenAI SDK | `openai-sdk` | — | +| `anthropic-sdk` | Anthropic SDK | `anthropic-sdk` | — | +| `langgraph` | LangGraph | `langgraph` | — | +| `crewai` | CrewAI | `crewai` | — | +| `none` | None | `none` | — | + +## Python Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `authlib` | Authlib | `authlib` | — | +| `jwt` | JWT (python-jose) | `jwt` | — | +| `none` | None | `none` | — | + +## Python Task Queue + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `celery` | Celery | `celery` | — | +| `none` | None | `none` | — | + +## Python Graphql + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `strawberry` | Strawberry | `strawberry` | — | +| `none` | None | `none` | — | + +## Python Quality + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ruff` | Ruff | `ruff` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/reference/options/rust.mdx b/apps/web/content/docs/reference/options/rust.mdx new file mode 100644 index 000000000..c13a7d455 --- /dev/null +++ b/apps/web/content/docs/reference/options/rust.mdx @@ -0,0 +1,127 @@ +--- +title: "Rust Options" +description: "Rust-ecosystem categories: web framework, ORM, API, CLI, libraries, auth." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Categories applied when scaffolding a Rust project. + +This page covers **35 options** across **10 categories**. + +Use CLI values in commands and MCP payloads. + +## Rust Web Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `axum` | Axum | `axum` | — | +| `actix-web` | Actix-web | `actix-web` | — | +| `rocket` | Rocket | `rocket` | — | +| `none` | None | `none` | — | + +## Rust Frontend + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `leptos` | Leptos | `leptos` | — | +| `dioxus` | Dioxus | `dioxus` | — | +| `none` | None | `none` | — | + +## Rust ORM + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `sea-orm` | SeaORM | `sea-orm` | — | +| `sqlx` | SQLx | `sqlx` | — | +| `diesel` | Diesel | `diesel` | — | +| `none` | None | `none` | — | + +## Rust API + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tonic` | Tonic | `tonic` | — | +| `async-graphql` | async-graphql | `async-graphql` | — | +| `none` | None | `none` | — | + +## Rust CLI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `clap` | Clap | `clap` | — | +| `ratatui` | Ratatui | `ratatui` | — | +| `none` | None | `none` | — | + +## Rust Libraries + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `serde` | Serde | `serde` | — | +| `validator` | Validator | `validator` | — | +| `jsonwebtoken` | jsonwebtoken | `jsonwebtoken` | — | +| `argon2` | Argon2 | `argon2` | — | +| `tokio-test` | Tokio Test | `tokio-test` | — | +| `mockall` | Mockall | `mockall` | — | +| `none` | None | `none` | — | + +## Rust Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tracing` | Tracing | `tracing` | — | +| `env-logger` | env_logger | `env-logger` | — | +| `none` | None | `none` | — | + +## Rust Error Handling + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `anyhow-thiserror` | anyhow + thiserror | `anyhow-thiserror` | — | +| `eyre` | eyre + color-eyre | `eyre` | — | +| `none` | None | `none` | — | + +## Rust Caching + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `moka` | Moka | `moka` | — | +| `redis` | Redis | `redis` | — | +| `none` | None | `none` | — | + +## Rust Auth + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `oauth2` | OAuth2 | `oauth2` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/reference/options/services.mdx b/apps/web/content/docs/reference/options/services.mdx new file mode 100644 index 000000000..cca7a6e90 --- /dev/null +++ b/apps/web/content/docs/reference/options/services.mdx @@ -0,0 +1,182 @@ +--- +title: "Services & Integrations" +description: "Payments, email, file upload, realtime, jobs, search, CMS, AI, analytics." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Third-party capabilities that get wired into the generated project. + +This page covers **66 options** across **13 categories**. + +Use CLI values in commands and MCP payloads. + +## Payments + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `polar` | Polar | `polar` | — | +| `stripe` | Stripe | `stripe` | — | +| `lemon-squeezy` | Lemon Squeezy | `lemon-squeezy` | — | +| `paddle` | Paddle | `paddle` | — | +| `dodo` | Dodo Payments | `dodo` | — | +| `none` | None | `none` | — | + +## Email + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `react-email` | React Email | `react-email` | — | +| `resend` | Resend | `resend` | — | +| `nodemailer` | Nodemailer | `nodemailer` | — | +| `postmark` | Postmark | `postmark` | — | +| `sendgrid` | SendGrid | `sendgrid` | — | +| `aws-ses` | AWS SES | `aws-ses` | — | +| `mailgun` | Mailgun | `mailgun` | — | +| `plunk` | Plunk | `plunk` | — | +| `none` | None | `none` | — | + +## File Upload + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `uploadthing` | UploadThing | `uploadthing` | — | +| `filepond` | FilePond | `filepond` | — | +| `uppy` | Uppy | `uppy` | — | +| `none` | None | `none` | — | + +## File Storage + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `s3` | S3 | `s3` | — | +| `r2` | R2 | `r2` | — | +| `none` | None | `none` | — | + +## Realtime + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `socket-io` | Socket.IO | `socket-io` | — | +| `partykit` | Partykit | `partykit` | — | +| `ably` | Ably | `ably` | — | +| `pusher` | Pusher | `pusher` | — | +| `liveblocks` | Liveblocks | `liveblocks` | — | +| `yjs` | Y.js | `yjs` | — | +| `none` | None | `none` | — | + +## Job Queue + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `bullmq` | BullMQ | `bullmq` | — | +| `trigger-dev` | Trigger.dev | `trigger-dev` | — | +| `inngest` | Inngest | `inngest` | — | +| `temporal` | Temporal | `temporal` | — | +| `none` | None | `none` | — | + +## Caching + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `upstash-redis` | Upstash Redis | `upstash-redis` | — | +| `none` | None | `none` | — | + +## I18n + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `i18next` | i18next | `i18next` | — | +| `next-intl` | next-intl | `next-intl` | — | +| `none` | None | `none` | — | + +## Search + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `meilisearch` | Meilisearch | `meilisearch` | — | +| `typesense` | Typesense | `typesense` | — | +| `elasticsearch` | Elasticsearch | `elasticsearch` | — | +| `algolia` | Algolia | `algolia` | — | +| `none` | None | `none` | — | + +## Cms + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `payload` | Payload | `payload` | — | +| `sanity` | Sanity | `sanity` | — | +| `strapi` | Strapi | `strapi` | — | +| `tinacms` | TinaCMS | `tinacms` | — | +| `none` | None | `none` | — | + +## AI + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `vercel-ai` | Vercel AI SDK | `vercel-ai` | — | +| `mastra` | Mastra | `mastra` | — | +| `voltagent` | VoltAgent | `voltagent` | — | +| `langgraph` | LangGraph.js | `langgraph` | — | +| `openai-agents` | OpenAI Agents SDK | `openai-agents` | — | +| `google-adk` | Google ADK | `google-adk` | — | +| `modelfusion` | ModelFusion | `modelfusion` | — | +| `langchain` | LangChain | `langchain` | — | +| `llamaindex` | LlamaIndex | `llamaindex` | — | +| `tanstack-ai` | TanStack AI | `tanstack-ai` | — | +| `none` | None | `none` | — | + +## Analytics + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `plausible` | Plausible | `plausible` | — | +| `umami` | Umami | `umami` | — | +| `none` | None | `none` | — | + +## Feature Flags + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `growthbook` | GrowthBook | `growthbook` | — | +| `posthog` | PostHog | `posthog` | — | +| `none` | None | `none` | — | diff --git a/apps/web/content/docs/reference/options/stack.mdx b/apps/web/content/docs/reference/options/stack.mdx new file mode 100644 index 000000000..6cb468492 --- /dev/null +++ b/apps/web/content/docs/reference/options/stack.mdx @@ -0,0 +1,185 @@ +--- +title: "Core Stack" +description: "Framework, runtime, database, ORM, API, and auth options." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Pick the frontend, backend, data, and auth building blocks for a TypeScript project. + +This page covers **84 options** across **10 categories**. + +Use CLI values in commands and MCP payloads. + +## API + +API layers and type-safe transport choices. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `trpc` | tRPC | `trpc` | — | +| `orpc` | oRPC | `orpc` | — | +| `ts-rest` | Ts Rest | `ts-rest` | — | +| `garph` | Garph | `garph` | — | +| `graphql-yoga` | GraphQL Yoga | `graphql-yoga` | — | +| `none` | None | `none` | — | + +## Web Frontend + +Browser-facing frontend frameworks and app routers. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tanstack-router` | Tanstack Router | `tanstack-router` | — | +| `react-router` | React Router | `react-router` | — | +| `react-vite` | React + Vite | `react-vite` | — | +| `tanstack-start` | Tanstack Start | `tanstack-start` | — | +| `next` | Next.js | `next` | — | +| `nuxt` | Nuxt | `nuxt` | — | +| `svelte` | SvelteKit | `svelte` | sveltekit | +| `solid` | Solid | `solid` | — | +| `solid-start` | Solid Start | `solid-start` | — | +| `astro` | Astro | `astro` | — | +| `qwik` | Qwik | `qwik` | — | +| `angular` | Angular | `angular` | — | +| `redwood` | RedwoodJS | `redwood` | — | +| `fresh` | Fresh | `fresh` | — | +| `none` | None | `none` | — | + +## Native Frontend + +React Native and Expo targets. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `native-bare` | Expo + Bare | `native-bare` | — | +| `native-uniwind` | Expo + Uniwind | `native-uniwind` | — | +| `native-unistyles` | Expo + Unistyles | `native-unistyles` | — | +| `none` | None | `none` | — | + +## Astro Integration + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `react` | React | `react` | — | +| `vue` | Vue | `vue` | — | +| `svelte` | Svelte | `svelte` | — | +| `solid` | Solid | `solid` | — | +| `none` | None | `none` | — | + +## Runtime + +JavaScript runtime selection for generated TypeScript services. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `bun` | Bun | `bun` | — | +| `node` | Node.js | `node` | — | +| `workers` | Cloudflare Workers | `workers` | — | +| `none` | None | `none` | — | + +## Backend + +Server frameworks and fullstack self-backend modes. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `hono` | Hono | `hono` | — | +| `express` | Express | `express` | — | +| `fastify` | Fastify | `fastify` | — | +| `elysia` | Elysia | `elysia` | — | +| `fets` | feTS | `fets` | — | +| `nestjs` | NestJS | `nestjs` | — | +| `adonisjs` | Adonisjs | `adonisjs` | — | +| `nitro` | Nitro | `nitro` | — | +| `encore` | Encore.ts | `encore` | — | +| `convex` | Convex | `convex` | — | +| `self-next` | Fullstack Next.js | `self` | — | +| `self-tanstack-start` | Fullstack TanStack Start | `self` | — | +| `self-astro` | Fullstack Astro | `self` | — | +| `self-nuxt` | Fullstack Nuxt | `self` | — | +| `self-svelte` | Fullstack SvelteKit | `self` | self-sveltekit | +| `self-solid-start` | Fullstack SolidStart | `self` | — | +| `none` | None | `none` | — | + +## Database + +Database engines used by generated app templates. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `none` | None | `none` | — | +| `sqlite` | SQLite | `sqlite` | — | +| `postgres` | PostgreSQL | `postgres` | — | +| `mysql` | Mysql | `mysql` | — | +| `mongodb` | MongoDB | `mongodb` | — | +| `edgedb` | EdgeDB | `edgedb` | — | +| `redis` | Redis | `redis` | — | + +## ORM + +Database access libraries and ORMs. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `drizzle` | Drizzle | `drizzle` | — | +| `prisma` | Prisma | `prisma` | — | +| `mongoose` | Mongoose | `mongoose` | — | +| `typeorm` | TypeORM | `typeorm` | — | +| `kysely` | Kysely | `kysely` | — | +| `mikroorm` | MikroORM | `mikroorm` | — | +| `sequelize` | Sequelize | `sequelize` | — | +| `none` | None | `none` | — | + +## DB Setup + +Optional database provisioning helpers. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turso` | Turso | `turso` | — | +| `neon` | Neon Postgres | `neon` | — | +| `prisma-postgres` | Prisma PostgreSQL | `prisma-postgres` | — | +| `planetscale` | PlanetScale | `planetscale` | — | +| `mongodb-atlas` | MongoDB Atlas | `mongodb-atlas` | — | +| `supabase` | Supabase | `supabase` | — | +| `upstash` | Upstash | `upstash` | — | +| `d1` | Cloudflare D1 | `d1` | — | +| `docker` | Docker | `docker` | — | +| `none` | None | `none` | — | + +## Auth + +Authentication providers and auth libraries. + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `better-auth` | Better-Auth | `better-auth` | — | +| `go-better-auth` | GoBetterAuth | `go-better-auth` | — | +| `clerk` | Clerk | `clerk` | — | +| `nextauth` | Auth.js (NextAuth) | `nextauth` | — | +| `stack-auth` | Stack Auth | `stack-auth` | — | +| `supabase-auth` | Supabase Auth | `supabase-auth` | — | +| `auth0` | Auth0 | `auth0` | — | +| `none` | No Auth | `none` | — | diff --git a/apps/web/content/docs/reference/options/tooling.mdx b/apps/web/content/docs/reference/options/tooling.mdx new file mode 100644 index 000000000..7a131c043 --- /dev/null +++ b/apps/web/content/docs/reference/options/tooling.mdx @@ -0,0 +1,194 @@ +--- +title: "Tooling, Deploy & Ops" +description: "Testing, logging, observability, code quality, deploy targets, package manager." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Everything around the app: CI, deploy, logs, docs, and workflow helpers. + +This page covers **66 options** across **14 categories**. + +Use CLI values in commands and MCP payloads. + +## Web Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +## Server Deploy + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `cloudflare` | Cloudflare | `cloudflare` | — | +| `fly` | Fly.io | `fly` | — | +| `railway` | Railway | `railway` | — | +| `docker` | Docker | `docker` | — | +| `sst` | SST | `sst` | — | +| `vercel` | Vercel | `vercel` | — | +| `none` | None | `none` | — | + +## Logging + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `pino` | Pino | `pino` | — | +| `winston` | Winston | `winston` | — | +| `none` | None | `none` | — | + +## Observability + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `opentelemetry` | OpenTelemetry | `opentelemetry` | — | +| `sentry` | Sentry | `sentry` | — | +| `grafana` | Grafana | `grafana` | — | +| `none` | None | `none` | — | + +## Testing + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `vitest` | Vitest | `vitest` | — | +| `playwright` | Playwright | `playwright` | — | +| `vitest-playwright` | Vitest + Playwright | `vitest-playwright` | — | +| `jest` | Jest | `jest` | — | +| `cypress` | Cypress | `cypress` | — | +| `none` | None | `none` | — | + +## Code Quality + +Linting, formatting, hooks, and code-quality tooling. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `biome` | Biome | `biome` | — | +| `oxlint` | Oxlint | `oxlint` | — | +| `ultracite` | Ultracite | `ultracite` | — | +| `lefthook` | Lefthook | `lefthook` | — | +| `husky` | Husky | `husky` | — | +| `ruler` | Ruler | `ruler` | — | + +## Documentation + +Documentation-site addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `starlight` | Starlight | `starlight` | — | +| `fumadocs` | Fumadocs | `fumadocs` | — | + +## App Platforms + +Platform, monorepo, MCP, skills, desktop, PWA, and UI data addons. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `turborepo` | Turborepo | `turborepo` | — | +| `pwa` | PWA | `pwa` | — | +| `tauri` | Tauri | `tauri` | — | +| `wxt` | WXT | `wxt` | — | +| `opentui` | OpenTUI | `opentui` | — | +| `mcp` | MCP | `mcp` | — | +| `skills` | Skills | `skills` | — | +| `msw` | MSW | `msw` | — | +| `storybook` | Storybook | `storybook` | — | +| `tanstack-query` | TanStack Query | `tanstack-query` | — | +| `tanstack-table` | TanStack Table | `tanstack-table` | — | +| `tanstack-virtual` | TanStack Virtual | `tanstack-virtual` | — | +| `tanstack-db` | TanStack DB | `tanstack-db` | — | +| `tanstack-pacer` | TanStack Pacer | `tanstack-pacer` | — | + +## Package Manager + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `npm` | Npm | `npm` | — | +| `pnpm` | Pnpm | `pnpm` | — | +| `bun` | Bun | `bun` | — | +| `yarn` | Yarn | `yarn` | — | + +## Version Channel + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `stable` | Stable | `stable` | — | +| `latest` | Latest | `latest` | — | +| `beta` | Beta | `beta` | — | + +## Examples + + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `ai` | AI Example | `ai` | — | +| `chat-sdk` | Chat SDK Bots | `chat-sdk` | — | + +## AI Docs + +Project-local documentation files for AI coding agents. + +Selection: **multiple** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `claude-md` | CLAUDE.md | `claude-md` | — | +| `agents-md` | Agents.md | `agents-md` | — | +| `cursorrules` | .cursorrules | `cursorrules` | — | +| `none` | None | `none` | — | + +## Git + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `true` | Git | `true` | — | +| `false` | No Git | `false` | — | + +## Install + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `true` | Install Dependencies | `true` | — | +| `false` | Skip Install | `false` | — | diff --git a/apps/web/content/docs/reference/options/ui.mdx b/apps/web/content/docs/reference/options/ui.mdx new file mode 100644 index 000000000..efb3b8c2f --- /dev/null +++ b/apps/web/content/docs/reference/options/ui.mdx @@ -0,0 +1,240 @@ +--- +title: "UI, Forms & State" +description: "CSS frameworks, UI libraries, state management, forms, validation, animation." +--- + +{/* Generated by apps/docs/scripts/generate-docs.ts. Do not edit by hand. */} + +Frontend layer choices for styling, interaction, and data flow. + +This page covers **108 options** across **15 categories**. + +Use CLI values in commands and MCP payloads. + +## State Management + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zustand` | Zustand | `zustand` | — | +| `jotai` | Jotai | `jotai` | — | +| `nanostores` | Nanostores | `nanostores` | — | +| `redux-toolkit` | Redux Toolkit | `redux-toolkit` | — | +| `mobx` | Mobx | `mobx` | — | +| `xstate` | XState | `xstate` | — | +| `valtio` | Valtio | `valtio` | — | +| `tanstack-store` | Tanstack Store | `tanstack-store` | — | +| `legend-state` | Legend State | `legend-state` | — | +| `none` | None | `none` | — | + +## Forms + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tanstack-form` | TanStack Form | `tanstack-form` | — | +| `react-hook-form` | React Hook Form | `react-hook-form` | — | +| `formik` | Formik | `formik` | — | +| `final-form` | Final Form | `final-form` | — | +| `conform` | Conform | `conform` | — | +| `modular-forms` | Modular Forms | `modular-forms` | — | +| `none` | None | `none` | — | + +## Validation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `zod` | Zod | `zod` | — | +| `valibot` | Valibot | `valibot` | — | +| `arktype` | ArkType | `arktype` | — | +| `typebox` | TypeBox | `typebox` | — | +| `typia` | Typia | `typia` | — | +| `runtypes` | Runtypes | `runtypes` | — | +| `effect-schema` | @effect/schema | `effect-schema` | — | +| `none` | None | `none` | — | + +## Animation + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `framer-motion` | Framer Motion | `framer-motion` | — | +| `gsap` | Gsap | `gsap` | — | +| `react-spring` | React Spring | `react-spring` | — | +| `auto-animate` | Auto Animate | `auto-animate` | — | +| `lottie` | Lottie | `lottie` | — | +| `none` | None | `none` | — | + +## Css Framework + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `tailwind` | Tailwind CSS | `tailwind` | — | +| `scss` | SCSS | `scss` | — | +| `less` | Less | `less` | — | +| `postcss-only` | PostCSS Only | `postcss-only` | — | +| `none` | None | `none` | — | + +## Ui Library + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `shadcn-ui` | shadcn/ui | `shadcn-ui` | — | +| `daisyui` | daisyUI | `daisyui` | — | +| `radix-ui` | Radix UI | `radix-ui` | — | +| `headless-ui` | Headless UI | `headless-ui` | — | +| `park-ui` | Park UI | `park-ui` | — | +| `chakra-ui` | Chakra UI | `chakra-ui` | — | +| `nextui` | NextUI | `nextui` | — | +| `mantine` | Mantine | `mantine` | — | +| `base-ui` | Base UI | `base-ui` | — | +| `ark-ui` | Ark UI | `ark-ui` | — | +| `react-aria` | React Aria | `react-aria` | — | +| `none` | None | `none` | — | + +## Backend Libraries + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `effect` | Effect (Core) | `effect` | — | +| `effect-full` | Effect Full | `effect-full` | — | +| `none` | None | `none` | — | + +## Effect + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `effect` | Effect (Core) | `effect` | — | +| `effect-full` | Effect Full | `effect-full` | — | +| `none` | None | `none` | — | + +## Shadcn Base + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `radix` | Radix UI | `radix` | — | +| `base` | Base UI | `base` | — | + +## Shadcn Style + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `vega` | Vega | `vega` | — | +| `nova` | Nova | `nova` | — | +| `maia` | Maia | `maia` | — | +| `lyra` | Lyra | `lyra` | — | +| `mira` | Mira | `mira` | — | + +## Shadcn Icon Library + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `lucide` | Lucide | `lucide` | — | +| `tabler` | Tabler Icons | `tabler` | — | +| `hugeicons` | HugeIcons | `hugeicons` | — | +| `phosphor` | Phosphor Icons | `phosphor` | — | +| `remixicon` | Remix Icon | `remixicon` | — | + +## Shadcn Color Theme + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `neutral` | Neutral | `neutral` | — | +| `stone` | Stone | `stone` | — | +| `zinc` | Zinc | `zinc` | — | +| `gray` | Gray | `gray` | — | +| `amber` | Amber | `amber` | — | +| `blue` | Blue | `blue` | — | +| `cyan` | Cyan | `cyan` | — | +| `emerald` | Emerald | `emerald` | — | +| `fuchsia` | Fuchsia | `fuchsia` | — | +| `green` | Green | `green` | — | +| `indigo` | Indigo | `indigo` | — | +| `lime` | Lime | `lime` | — | +| `orange` | Orange | `orange` | — | +| `pink` | Pink | `pink` | — | +| `purple` | Purple | `purple` | — | +| `red` | Red | `red` | — | +| `rose` | Rose | `rose` | — | +| `sky` | Sky | `sky` | — | +| `teal` | Teal | `teal` | — | +| `violet` | Violet | `violet` | — | +| `yellow` | Yellow | `yellow` | — | + +## Shadcn Base Color + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `neutral` | Neutral | `neutral` | — | +| `stone` | Stone | `stone` | — | +| `zinc` | Zinc | `zinc` | — | +| `gray` | Gray | `gray` | — | + +## Shadcn Font + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `inter` | Inter | `inter` | — | +| `geist` | Geist | `geist` | — | +| `noto-sans` | Noto Sans | `noto-sans` | — | +| `nunito-sans` | Nunito Sans | `nunito-sans` | — | +| `figtree` | Figtree | `figtree` | — | +| `roboto` | Roboto | `roboto` | — | +| `raleway` | Raleway | `raleway` | — | +| `dm-sans` | DM Sans | `dm-sans` | — | +| `public-sans` | Public Sans | `public-sans` | — | +| `outfit` | Outfit | `outfit` | — | +| `jetbrains-mono` | JetBrains Mono | `jetbrains-mono` | — | +| `geist-mono` | Geist Mono | `geist-mono` | — | + +## Shadcn Radius + + +Selection: **single** + +| Option | Label | CLI value | Aliases | +| --- | --- | --- | --- | +| `default` | Default | `default` | — | +| `none` | None | `none` | — | +| `small` | Small | `small` | — | +| `medium` | Medium | `medium` | — | +| `large` | Large | `large` | — | diff --git a/apps/web/package.json b/apps/web/package.json index 541fb38a2..319d0f787 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -25,7 +25,11 @@ "@better-fullstack/backend": "workspace:*", "@better-fullstack/template-generator": "workspace:*", "@better-fullstack/types": "workspace:*", + "@mdx-js/react": "^3.1.1", + "@mdx-js/rollup": "^3.1.1", "@number-flow/react": "^0.5.10", + "@orama/orama": "^3.1.18", + "@shikijs/rehype": "^4.0.2", "@shikijs/transformers": "^3.20.0", "@tanstack/react-router": "^1.168.23", "@tanstack/react-start": "^1.167.42", @@ -40,7 +44,10 @@ "culori": "^4.0.2", "date-fns": "^4.1.0", "geist": "^1.7.0", + "gray-matter": "^4.0.3", "lucide-react": "^0.562.0", + "mdast-util-to-string": "^4.0.0", + "mdast-util-toc": "^7.1.0", "motion": "^12.38.0", "papaparse": "^5.5.3", "posthog-js": "^1.369.3", @@ -51,30 +58,37 @@ "react-icons": "^5.6.0", "react-tweet": "^3.3.0", "recharts": "2.15.4", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.1", + "remark-mdx-frontmatter": "^5.2.0", "shiki": "^3.20.0", "sonner": "^2.0.7", "tailwind-merge": "^3.5.0", + "unist-util-visit": "^5.1.0", "zod": "^4.3.6" }, "devDependencies": { "@axe-core/playwright": "^4.11.2", + "@playwright/test": "1.59.1", "@tailwindcss/postcss": "^4.2.2", "@tailwindcss/vite": "^4.2.2", "@types/culori": "^4.0.1", + "@types/mdast": "^4.0.4", + "@types/mdx": "^2.0.13", "@types/node": "25.6.0", "@types/papaparse": "^5.5.2", "@types/qrcode": "^1.5.6", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", + "@types/unist": "^3.0.3", "@vitejs/plugin-react": "^5.1.2", "nitro": "^3.0.0", + "playwright-core": "1.59.1", "postcss": "^8.5.10", "tailwindcss": "^4.2.2", "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", "vite": "^7.1.7", - "@playwright/test": "1.59.1", - "playwright-core": "1.59.1", "vite-tsconfig-paths": "^5.1.4" } } diff --git a/apps/web/public/llms.txt b/apps/web/public/llms.txt index cee72518b..60719d426 100644 --- a/apps/web/public/llms.txt +++ b/apps/web/public/llms.txt @@ -1,8 +1,8 @@ # Better Fullstack -> Scaffold production-ready fullstack apps in seconds. Pick your stack from 270+ options across TypeScript, Rust, Python, and Go — the CLI wires everything together. +> Scaffold production-ready fullstack apps in seconds. Pick your stack from 424 options across TypeScript, Rust, Python, Go, and Java — the CLI wires everything together. -Better Fullstack is an open-source CLI tool and visual web builder that generates fully configured, production-ready fullstack applications. Unlike single-framework scaffolders, it supports 4 language ecosystems and lets developers mix and match from 270+ technology options. +Better Fullstack is an open-source CLI tool and visual web builder that generates fully configured, production-ready fullstack applications. Unlike single-framework scaffolders, it supports 5 language ecosystems and lets developers mix and match from 424 technology options. ## Key Facts @@ -17,6 +17,7 @@ Better Fullstack is an open-source CLI tool and visual web builder that generate - Rust (Actix, Axum, Rocket, Leptos, Dioxus, Yew) - Python (FastAPI, Django, SQLAlchemy, SQLModel) - Go (Gin, Echo, GORM, sqlc) +- Java (Spring Boot, Maven, Gradle, Spring Data JPA, Spring Security) ## Frontend Frameworks (15) @@ -63,16 +64,19 @@ tRPC, oRPC, ts-rest, Garph (GraphQL), gRPC, and more. - Homepage: https://better-fullstack.dev/ - Stack Builder: https://better-fullstack.dev/new - Comparison: https://better-fullstack.dev/compare +- Docs: https://better-fullstack.dev/docs/ +- AI Agents: https://better-fullstack.dev/docs/ai/overview/ +- MCP: https://better-fullstack.dev/docs/ai/mcp/ - npm: https://www.npmjs.com/package/create-better-fullstack - GitHub: https://github.com/Marve10s/Better-Fullstack ## Common Questions ### What is Better Fullstack? -A CLI and web-based tool that scaffolds production-ready fullstack applications with 270+ configurable options across 4 language ecosystems (TypeScript, Rust, Python, Go). +A CLI and web-based tool that scaffolds production-ready fullstack applications with 424 configurable options across 5 language ecosystems (TypeScript, Rust, Python, Go, Java). ### How is it different from create-t3-app? -Better Fullstack supports 4 ecosystems (not just TypeScript), 15 frontend frameworks (not just Next.js), 17 backend options, payments, AI integrations, and a visual web builder. create-t3-app focuses on the T3 Stack (Next.js + tRPC + Prisma + Tailwind). +Better Fullstack supports 5 ecosystems (not just TypeScript), 15 frontend frameworks (not just Next.js), 17 backend options, payments, AI integrations, and a visual web builder. create-t3-app focuses on the T3 Stack (Next.js + tRPC + Prisma + Tailwind). ### How is it different from create-next-app? create-next-app only scaffolds Next.js projects. Better Fullstack scaffolds complete fullstack applications with your choice of frontend, backend, database, ORM, auth, payments, AI, and deployment — across multiple languages. diff --git a/apps/web/src/components/docs/docs-layout.tsx b/apps/web/src/components/docs/docs-layout.tsx new file mode 100644 index 000000000..f6ae65dd0 --- /dev/null +++ b/apps/web/src/components/docs/docs-layout.tsx @@ -0,0 +1,131 @@ +import { useLocation } from "@tanstack/react-router"; +import { Menu, X } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; +import type { ReactNode } from "react"; +import { useEffect, useState } from "react"; + +import { DocsSidebar } from "@/components/docs/sidebar"; +import { TableOfContents } from "@/components/docs/table-of-contents"; +import type { TocEntry } from "@/lib/docs/remark-extract-toc"; +import { cn } from "@/lib/utils"; + +/** + * Three-column docs shell rendered under `/docs/*`. Layout is: + * + * ┌────────────────────────────────────────────────────────────┐ + * │ navbar (from __root layout) │ + * ├────────────┬──────────────────────────────────────┬────────┤ + * │ sidebar │ content (DocsArticle wraps MDX) │ TOC │ + * │ │ │ │ + * └────────────┴──────────────────────────────────────┴────────┘ + * + * The sidebar collapses into a slide-in drawer on small screens. The TOC + * disappears entirely below `lg` (handled inside TableOfContents). + */ +export function DocsLayout({ toc, children }: { toc: TocEntry[]; children: ReactNode }) { + const [mobileOpen, setMobileOpen] = useState(false); + const location = useLocation(); + + // Auto-dismiss the mobile drawer when the user navigates to a new doc + // page. This replaces an event-delegation onClick on the sidebar wrapper + // (which would have triggered jsx-a11y `click-events-have-key-events` + // warnings since a non-interactive `
` can't satisfy keyboard parity). + useEffect(() => { + setMobileOpen(false); + }, [location.pathname]); + + // Lock body scroll while the mobile drawer is open and close on Escape. + useEffect(() => { + if (!mobileOpen) return; + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") setMobileOpen(false); + }; + window.addEventListener("keydown", onKey); + return () => { + document.body.style.overflow = previousOverflow; + window.removeEventListener("keydown", onKey); + }; + }, [mobileOpen]); + + return ( +
+ {/* Mobile sidebar toggle */} + + +
+ {/* Desktop sidebar */} + + +
{children}
+ + +
+ + {/* Mobile slide-in drawer */} + + {mobileOpen ? ( + + +
+ {/* + The drawer auto-closes on route change via the + `location.pathname` effect above, so this wrapper is + purely structural and stays free of event handlers. + */} +
+ +
+ + + ) : null} + +
+ ); +} diff --git a/apps/web/src/components/docs/docs-page.tsx b/apps/web/src/components/docs/docs-page.tsx new file mode 100644 index 000000000..cd5ae8a22 --- /dev/null +++ b/apps/web/src/components/docs/docs-page.tsx @@ -0,0 +1,82 @@ +import { MDXProvider } from "@mdx-js/react"; +import { Link } from "@tanstack/react-router"; + +import { DocsLayout } from "@/components/docs/docs-layout"; +import { mdxComponents } from "@/components/docs/mdx"; +import type { DocPage, PageNode } from "@/lib/docs/source"; + +/** + * Shared docs page renderer used by both the splat route (`/docs/$`) and + * the exact `/docs/` index route. Routes are responsible for resolving the + * `DocPage` and `neighbors` via their loaders; this component just renders + * them inside the standard chrome. + */ +export type DocsPageContentProps = { + page: DocPage; + neighbors: { previous: PageNode | null; next: PageNode | null }; +}; + +export function DocsPageContent({ page, neighbors }: DocsPageContentProps) { + const Content = page.Component; + + return ( + +
+
+ {page.frontmatter.title ? ( +

+ {page.frontmatter.title} +

+ ) : null} + {page.frontmatter.description ? ( +

{page.frontmatter.description}

+ ) : null} +
+ +
+ + + +
+ + {(neighbors.previous || neighbors.next) && ( + + )} +
+
+ ); +} diff --git a/apps/web/src/components/docs/mdx/callout.tsx b/apps/web/src/components/docs/mdx/callout.tsx new file mode 100644 index 000000000..1062d8c75 --- /dev/null +++ b/apps/web/src/components/docs/mdx/callout.tsx @@ -0,0 +1,49 @@ +import { AlertCircle, AlertTriangle, Info, Lightbulb } from "lucide-react"; +import type { ReactNode } from "react"; + +import { cn } from "@/lib/utils"; + +type CalloutKind = "info" | "tip" | "warn" | "danger"; + +const config: Record = { + info: { icon: Info, tone: "text-foreground" }, + tip: { icon: Lightbulb, tone: "text-foreground" }, + warn: { icon: AlertTriangle, tone: "text-amber-500 dark:text-amber-400" }, + danger: { icon: AlertCircle, tone: "text-red-500 dark:text-red-400" }, +}; + +/** + * Side-bar callout used inside MDX: + * Some advice here. + * + * Renders as a thin card with a colored icon. Spec leans neutral so callouts + * don't fight the content. Only `warn` and `danger` kinds carry color; the + * rest stay grayscale to honor the brand palette. + */ +export function Callout({ + kind = "info", + title, + children, +}: { + kind?: CalloutKind; + title?: string; + children?: ReactNode; +}) { + const { icon: Icon, tone } = config[kind]; + return ( + + ); +} diff --git a/apps/web/src/components/docs/mdx/code-block.tsx b/apps/web/src/components/docs/mdx/code-block.tsx new file mode 100644 index 000000000..daaacc95e --- /dev/null +++ b/apps/web/src/components/docs/mdx/code-block.tsx @@ -0,0 +1,84 @@ +import { Check, Copy } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; + +import { cn } from "@/lib/utils"; + +/** + * Wraps the `
` element rehype-shiki produces so we can layer a copy
+ * button + filename label on top without touching the highlighted markup.
+ *
+ * We don't replace the inner HTML — Shiki's spans and inline styles need to
+ * survive intact for the syntax-highlighting themes to render. Instead, we
+ * intercept the `
` rendered by MDX and render the same children inside
+ * our chrome.
+ */
+export function CodeBlock({
+  className,
+  children,
+  ...rest
+}: React.HTMLAttributes) {
+  const [copied, setCopied] = useState(false);
+  const preRef = useRef(null);
+  const language = extractLanguage(className);
+
+  // Detect whether this code block was substituted by PMTabs (which sets
+  // `data-pm-block` on the wrapper). In that case the parent owns its own
+  // copy UI; we render the bare pre.
+  const handleCopy = async () => {
+    const text = preRef.current?.innerText ?? "";
+    if (!text) return;
+    try {
+      await navigator.clipboard.writeText(text);
+      setCopied(true);
+    } catch {
+      // best-effort
+    }
+  };
+
+  useEffect(() => {
+    if (!copied) return;
+    const id = window.setTimeout(() => setCopied(false), 1600);
+    return () => window.clearTimeout(id);
+  }, [copied]);
+
+  return (
+    
+ {language ? ( +
+ {language} +
+ ) : null} +
+        {children}
+      
+ +
+ ); +} + +function extractLanguage(className: string | undefined): string | null { + if (!className) return null; + const match = className.match(/language-(\w+)/); + if (!match) return null; + const lang = match[1]; + if (lang === "npm") return null; // PMTabs hides this one + return lang; +} diff --git a/apps/web/src/components/docs/mdx/index.tsx b/apps/web/src/components/docs/mdx/index.tsx new file mode 100644 index 000000000..caa285012 --- /dev/null +++ b/apps/web/src/components/docs/mdx/index.tsx @@ -0,0 +1,24 @@ +import type { ComponentType } from "react"; + +import { Callout } from "./callout"; +import { CodeBlock } from "./code-block"; +import { PMTabs } from "./pm-tabs"; + +/** + * Registry of components passed to `` (or directly via the + * `components` prop on each MDX module). Maps both: + * - HTML element overrides (e.g. `
` → CodeBlock chrome)
+ *   - Custom MDX-only components used inside docs (e.g. ``)
+ *
+ * Keys are case-sensitive; markdown elements use lowercase names while
+ * JSX-imported components keep their PascalCase names.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export const mdxComponents: Record> = {
+  // HTML overrides
+  pre: CodeBlock,
+
+  // MDX-only components — referenced by name from .mdx files
+  Callout,
+  PMTabs,
+};
diff --git a/apps/web/src/components/docs/mdx/pm-tabs.tsx b/apps/web/src/components/docs/mdx/pm-tabs.tsx
new file mode 100644
index 000000000..268251a85
--- /dev/null
+++ b/apps/web/src/components/docs/mdx/pm-tabs.tsx
@@ -0,0 +1,134 @@
+import { Check, Copy } from "lucide-react";
+import { motion } from "motion/react";
+import { useEffect, useState } from "react";
+
+import PackageIcon from "@/components/home/icons";
+import { cn } from "@/lib/utils";
+
+const MANAGERS = ["npm", "pnpm", "bun", "yarn"] as const;
+type Manager = (typeof MANAGERS)[number];
+
+const STORAGE_KEY = "bfs.docs.pm";
+const SYNC_EVENT = "bfs:docs:pm-changed";
+
+/**
+ * Renders a 4-tab package-manager picker around a shell command. Selection
+ * is shared across every PMTabs instance on the page (and persists across
+ * reloads) via `localStorage` + a custom DOM event. Clicking a tab updates
+ * `localStorage`, then dispatches the event so other tabs in the same page
+ * (or other pages within the same tab thanks to `storage` events) react.
+ */
+export function PMTabs({
+  npm,
+  pnpm,
+  bun,
+  yarn,
+}: {
+  npm: string;
+  pnpm: string;
+  bun: string;
+  yarn: string;
+}) {
+  const commands: Record = { npm, pnpm, bun, yarn };
+  const [active, setActive] = useState("npm");
+  const [copied, setCopied] = useState(false);
+
+  // Initialize from storage and subscribe to changes.
+  useEffect(() => {
+    if (typeof window === "undefined") return;
+    const stored = window.localStorage.getItem(STORAGE_KEY);
+    if (stored && (MANAGERS as readonly string[]).includes(stored)) {
+      setActive(stored as Manager);
+    }
+    const onSync = (event: Event) => {
+      const detail = (event as CustomEvent).detail;
+      if (detail && MANAGERS.includes(detail)) setActive(detail);
+    };
+    const onStorage = (event: StorageEvent) => {
+      if (event.key === STORAGE_KEY && event.newValue) {
+        if (MANAGERS.includes(event.newValue as Manager)) {
+          setActive(event.newValue as Manager);
+        }
+      }
+    };
+    window.addEventListener(SYNC_EVENT, onSync);
+    window.addEventListener("storage", onStorage);
+    return () => {
+      window.removeEventListener(SYNC_EVENT, onSync);
+      window.removeEventListener("storage", onStorage);
+    };
+  }, []);
+
+  const select = (manager: Manager) => {
+    setActive(manager);
+    if (typeof window === "undefined") return;
+    window.localStorage.setItem(STORAGE_KEY, manager);
+    window.dispatchEvent(new CustomEvent(SYNC_EVENT, { detail: manager }));
+  };
+
+  useEffect(() => {
+    if (!copied) return;
+    const id = window.setTimeout(() => setCopied(false), 1600);
+    return () => window.clearTimeout(id);
+  }, [copied]);
+
+  const onCopy = async () => {
+    try {
+      await navigator.clipboard.writeText(commands[active]);
+      setCopied(true);
+    } catch {
+      // best-effort
+    }
+  };
+
+  return (
+    
+
+ {MANAGERS.map((manager) => { + const isActive = active === manager; + return ( + + ); + })} +
+ +
+
+
+        {commands[active]}
+      
+
+ ); +} diff --git a/apps/web/src/components/docs/search-dialog.tsx b/apps/web/src/components/docs/search-dialog.tsx new file mode 100644 index 000000000..dfe320bd5 --- /dev/null +++ b/apps/web/src/components/docs/search-dialog.tsx @@ -0,0 +1,327 @@ +import { useNavigate } from "@tanstack/react-router"; +import { ArrowRight, FileText, Hash, Search as SearchIcon } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import type { DocSearch, SearchHit } from "@/lib/docs/search"; +import { createDocSearch } from "@/lib/docs/search"; +import { searchSections } from "@/lib/docs/search-data"; +import { cn } from "@/lib/utils"; + +const SHORTCUT_HINT_KEYS = ["meta+k", "ctrl+k"] as const; + +/** + * Cmd/Ctrl+K search dialog. Lazy-loads the Orama instance the first time + * the dialog opens (avoids paying Orama's startup cost for users that never + * search). Keyboard: + * - ↑/↓: move selection + * - Enter: navigate to highlighted hit + * - Esc: close + */ +export function DocsSearchDialog({ + open, + onOpenChange, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; +}) { + const navigate = useNavigate(); + const [query, setQuery] = useState(""); + const [hits, setHits] = useState([]); + const [activeIndex, setActiveIndex] = useState(0); + const [search, setSearch] = useState(null); + const inputRef = useRef(null); + + // Lazy-init Orama on first open. The promise is cached so repeat opens + // don't rebuild the index. + useEffect(() => { + if (!open || search) return; + let cancelled = false; + const init = async () => { + const instance = await createDocSearch(searchSections); + if (!cancelled) setSearch(instance); + }; + void init(); + return () => { + cancelled = true; + }; + }, [open, search]); + + // Run the query whenever input changes. + useEffect(() => { + if (!search) return; + let cancelled = false; + const run = async () => { + const results = await search.query(query); + if (cancelled) return; + setHits(results); + setActiveIndex(0); + }; + void run(); + return () => { + cancelled = true; + }; + }, [query, search]); + + // Reset state on close so reopening starts clean. + useEffect(() => { + if (open) { + requestAnimationFrame(() => inputRef.current?.focus()); + return; + } + setQuery(""); + setHits([]); + setActiveIndex(0); + }, [open]); + + const onPick = useCallback( + (hit: SearchHit) => { + onOpenChange(false); + navigate({ to: hit.sectionUrl }); + }, + [navigate, onOpenChange], + ); + + const onKey = useCallback( + (event: React.KeyboardEvent) => { + if (event.key === "ArrowDown") { + event.preventDefault(); + setActiveIndex((idx) => Math.min(idx + 1, Math.max(0, hits.length - 1))); + return; + } + if (event.key === "ArrowUp") { + event.preventDefault(); + setActiveIndex((idx) => Math.max(idx - 1, 0)); + return; + } + if (event.key === "Enter") { + const hit = hits[activeIndex]; + if (hit) { + event.preventDefault(); + onPick(hit); + } + return; + } + if (event.key === "Escape") { + event.preventDefault(); + onOpenChange(false); + } + }, + [activeIndex, hits, onPick, onOpenChange], + ); + + // Group hits by page so identical-page results cluster together. + const grouped = useMemo(() => groupByPage(hits), [hits]); + + return ( + + {open ? ( + + + + ); + })} + + + ))} + + )} +
+ +
+ + + Navigate + + Open + + {searchSections.length} sections indexed +
+ + + ) : null} + + ); +} + +function Empty({ children }: { children: React.ReactNode }) { + return ( +
+ {children} +
+ ); +} + +function KeyHint({ label }: { label: string }) { + return ( + + {label} + + ); +} + +type Group = { + pageId: string; + pageTitle: string; + items: SearchHit[]; +}; + +function groupByPage(hits: SearchHit[]): Group[] { + const groups: Group[] = []; + const byId = new Map(); + for (const hit of hits) { + let g = byId.get(hit.pageId); + if (!g) { + g = { pageId: hit.pageId, pageTitle: hit.pageTitle, items: [] }; + byId.set(hit.pageId, g); + groups.push(g); + } + g.items.push(hit); + } + return groups; +} + +/** + * Imperative trigger button. Owns its own open state so consumers (the + * Navbar, mobile menus, etc.) only need a JSX placement. Listens for + * Cmd/Ctrl+K globally. + */ +export function DocsSearchTrigger({ className }: { className?: string }) { + const [open, setOpen] = useState(false); + + useEffect(() => { + const onKey = (event: KeyboardEvent) => { + if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") { + event.preventDefault(); + setOpen((value) => !value); + } + }; + window.addEventListener("keydown", onKey); + return () => window.removeEventListener("keydown", onKey); + }, []); + + return ( + <> + + + + ); +} + +function getModifierLabel(): string { + if (typeof navigator === "undefined") return SHORTCUT_HINT_KEYS[0]; + return /Mac|iPhone|iPod|iPad/i.test(navigator.platform || navigator.userAgent) + ? "⌘" + : "Ctrl"; +} diff --git a/apps/web/src/components/docs/sidebar.tsx b/apps/web/src/components/docs/sidebar.tsx new file mode 100644 index 000000000..98a93870e --- /dev/null +++ b/apps/web/src/components/docs/sidebar.tsx @@ -0,0 +1,187 @@ +import { Link, useLocation } from "@tanstack/react-router"; +import { motion } from "motion/react"; +import { useState } from "react"; + +import { DocsSearchTrigger } from "@/components/docs/search-dialog"; +import { + type FolderNode, + type PageNode, + pageTree, + type PageTreeNode, +} from "@/lib/docs/source"; +import { cn } from "@/lib/utils"; + +/** + * Top-level docs sidebar. Renders the page tree as a list of sections (each + * a `
` element so collapsed state is preserved through reloads via + * `defaultOpen`) interleaved with mono-uppercase separators. + * + * Active link styling uses a `motion.div` with `layoutId` so the indicator + * rail animates between pages on client-side navigation. The rail is + * intentionally subtle — a 1px column to the left of the link, painted with + * the foreground color, drawn via React's layout animation (no JS scroll + * math needed). + */ +export function DocsSidebar({ className }: { className?: string }) { + const location = useLocation(); + const currentUrl = location.pathname.replace(/\/$/, "") || "/docs"; + + return ( + + ); +} + +function getNodeKey(node: PageTreeNode, index: number): string { + if (node.type === "page") return `page:${node.url}`; + if (node.type === "folder") return `folder:${node.name}:${index}`; + return `sep:${node.name}:${index}`; +} + +function SidebarNode({ + node, + currentUrl, + depth, +}: { + node: PageTreeNode; + currentUrl: string; + depth: number; +}) { + if (node.type === "separator") return null; + if (node.type === "folder") + return ; + return ; +} + +function SidebarFolder({ + folder, + currentUrl, + depth, +}: { + folder: FolderNode; + currentUrl: string; + depth: number; +}) { + const [open, setOpen] = useState(folder.defaultOpen); + const childContains = (children: PageTreeNode[]): boolean => + children.some((c) => { + if (c.type === "page") return c.url === currentUrl; + if (c.type === "folder") + return c.index?.url === currentUrl || childContains(c.children); + return false; + }); + // Auto-expand when a descendant is active so deep links land with the + // section already open even if `defaultOpen` was false. + const expanded = open || childContains(folder.children); + + return ( +
setOpen(event.currentTarget.open)} + className="group select-none" + > + + {folder.name} + + +
    + {folder.index ? ( +
  • + +
  • + ) : null} + {folder.children.map((child, index) => ( +
  • + +
  • + ))} +
+
+ ); +} + +function SidebarPageLink({ + page, + currentUrl, + depth, +}: { + page: PageNode; + currentUrl: string; + depth: number; +}) { + const isActive = page.url === currentUrl; + return ( + + {isActive ? ( +