Ecosystems

Open documentation actions

Multi-Ecosystem

Compose one Better Fullstack project from frontend, backend, database, and mobile parts across ecosystems.

Multi-Ecosystem mode models a project as connected stack parts instead of one flat ecosystem selection. Use it when a product spans languages: a TypeScript frontend, a Go API, a shared PostgreSQL database, and a React Native app in one workspace. Open it in the Stack Builder or pass repeated --part flags.

Stack parts

Each part has the shape role:ecosystem:tool, or owner.role:ecosystem:tool when the role attaches to a parent part:

ExampleMeaning
frontend:typescript:nextGenerate a TypeScript Next.js frontend.
backend:go:ginGenerate a Go Gin backend.
backend.orm:go:gormAttach GORM to that backend.
backend.api:rust:tonicAttach Tonic gRPC to a Rust backend.
database:universal:postgresAdd a shared PostgreSQL database part.
mobile:kotlin:jetpack-composeGenerate a Kotlin Jetpack Compose app.
mobile:swift:swiftuiGenerate a SwiftUI app.
frontend:dotnet:blazor-webassemblyGenerate a standalone Blazor WebAssembly frontend.

Top-level roles describe generated apps or shared infrastructure. Owned roles attach capabilities such as ORM, API, auth, or libraries to their owner.

Scripted example

npm create better-fullstack@latest my-mixed-app -- \  --part frontend:typescript:next \  --part backend:go:gin \  --part backend.orm:go:gorm \  --part backend.auth:go:jwt \  --part database:universal:postgres \  --part mobile:kotlin:compose-multiplatform \  --part mobile.libraries:kotlin:ktor-client \  --part workspaceRunner:universal:turborepo \  --part containerOrchestration:universal:docker-compose

Design-system lint

For a supported React web frontend, add these Stack Parts to use shadcn/lint alongside Oxlint:

text
--part frontend.css:typescript:tailwind
--part codeQuality:universal:oxlint
--part codeQuality:universal:shadcn-lint

Use codeQuality:universal:eslint and codeQuality:universal:prettier for the ESLint + Prettier profile instead of Oxlint. The plugin checks the React application; backend tools such as Ruff or golangci-lint keep their own Role Bindings. See Code Quality in the builder for supported frontends and the generated rule policy.

Source of truth

Multi-ecosystem projects write stackParts to bts.jsonc, and those parts drive generated structure, history, and reproducible commands. Legacy flat fields may still appear as compatibility views derived from the graph. The generated command preserves the graph as repeated --part flags, so nothing depends on hidden builder state.

The builder starts with an application flow:

  1. Applications: choose web, mobile, backend, or a combination. Each card lists the directory it generates, the choices its step offers, and the languages it supports.
  2. One step per application: choose the application's language, framework, and capabilities. The backend step includes an optional database and its hosting. The mobile step offers React Native, Kotlin, Swift, and Flutter.
  3. Project: choose settings supported by the selected applications. JavaScript package-manager and toolchain questions appear only when the project includes a TypeScript or React Native workspace.
  4. Review: name the project, check each application's framework, language, directory, and capabilities, then copy the command, preview the files, run the project in the browser, download a ZIP, or copy a share link.

You can return to a step to edit it. Changing one application preserves unrelated named services and their capabilities. Existing stack URLs keep their graph selections.

Local setup and startup

Projects with a JavaScript workspace use the selected package manager at the root. When a project also contains native backend services, the root dev script starts the web applications and services together and stops them when one exits.

Native-only graphs have no root package.json. Run bash scripts/setup.sh to prepare dependencies, then bash scripts/dev.sh to start the web applications and backend services. These scripts need Bash, including Git Bash on Windows. Native mobile apps run separately in their simulator or device; their generated READMEs provide the commands and SDK requirements.

The CLI's --install option prepares every selected application's dependencies using its toolchain. Missing SDKs are reported as setup failures. Use --no-install to generate files first and run the README's setup commands later.

Compatibility

  • Owned capability parts must reference an owner, and their ecosystem generally must match it.
  • Primary services can take an explicit stable ID as a fourth segment, such as backend:go:gin:api; capabilities then target that ID with api.orm:go:gorm.
  • Repeatable named backends render under services/<id> when their adapters support independent output; the checker rejects repeated projections it cannot render safely.
  • Universal database parts can be shared across ecosystems.
  • Some tools imply parts, for example a backend that assumes routing, and those appear in generated stackParts.
  • The compatibility validator runs before generation and reports owner, duplicate, and unsupported-tool issues.

Multiple named services

npm create better-fullstack@latest services-app -- \  --part frontend:typescript:next \  --part backend:go:gin:api \  --part backend:go:echo:admin \  --part api.orm:go:gorm \  --part admin.orm:go:sqlc \  --part database:universal:postgres

Stable IDs make ownership unambiguous and keep generated service paths reproducible.

GitHub Sponsors