From zero to running in under a minute

npm install -g @bloomneo/bloom

# Web app (React + Express, FBCA routing)
bloom create my-app

# Auth + user management + admin panel
bloom create my-app userapp

# Admin console (userapp + audit log, settings dashboard, 3-tier roles)
bloom create my-app adminapp

# Desktop app (Electron, SQLite, cross-platform)
bloom create my-app desktop-basicapp
bloom create my-app desktop-userapp

# Mobile app (iOS + Android via Capacitor 6)
bloom create my-app mobile-basicapp

For AI coding agents (Claude, Cursor, Copilot, Windsurf)

This page is written for humans. Agents should fetch /bloom/llms.txt and /bloom/AGENTS.md for the authoritative CLI + template reference. Inside a scaffolded project, read the project's root AGENTS.md first, then docs/appkit-agents.md + docs/uikit-agents.md (auto-populated by npm install) for library-specific rules.

Three packages. One framework.

Bloom isn't monolithic. Install the full stack with bloom create, or pull any pillar into an existing project. They're designed to compose but work standalone.

AppKit · backend

Node.js toolkit with 12 typed modules — JWT auth, Prisma multi-tenancy, Redis cache & queue, S3 storage, SMTP/Resend email, structured logging, CSRF & rate limiting, semantic HTTP errors, typed config. Auto-scales memory → Redis → cloud without a rewrite.

UIKit · frontend

45+ typed React components, 5 OKLCH themes, 6 production layouts. Forms, tables, dialogs, toasts, confirms, permission gates, responsive hooks — all wired on Radix + Tailwind. Web, Electron desktop, Capacitor mobile, browser-extension popups.

Bloom CLI · scaffolder

5 templates (web / auth+users / desktop / desktop+auth / mobile). Feature-Based Component Architecture — add a route by adding a folder. Every scaffold ships docs/ + .claude/skills/ auto-populated from installed packages, kept version-matched on every npm install.

Add a folder. Get a route.

Bloom has one load-bearing convention across every template: Feature-Based Component Architecture. Backend endpoints and frontend pages are auto-discovered by scanning feature folders. No router config to edit, no import list to maintain, no manual registration. Adding functionality = creating files.

# Backend — drop a folder → auto-mounted API route
src/api/features/
└── invoice/
    ├── invoice.route.ts     → /api/invoice
    ├── invoice.service.ts   (business logic; uses appkit)
    └── invoice.types.ts     (shared with frontend)

# Frontend — drop a folder → auto-routed page
src/web/features/
└── invoice/
    ├── pages/
    │   ├── index.tsx        → /invoice
    │   ├── [id].tsx         → /invoice/:id   (dynamic segment)
    │   └── [...path].tsx    → /invoice/*     (catch-all)
    ├── components/          (local to this feature)
    └── services/            (API calls; uses uikit useApi)

Route pattern rules — how file paths become URLs:

File pathBecomes route
features/main/pages/index.tsx/ (root)
features/blog/pages/index.tsx/blog
features/blog/pages/[slug].tsx/blog/:slug
features/docs/pages/[...path].tsx/docs/* (catch-all)
features/invoice/invoice.route.ts/api/invoice

Under the hood: the web router uses import.meta.glob('../features/*/pages/**/*.tsx'); the API router scans src/api/features/ at boot. Both are re-discovered on hot reload — no server restart required when you add a feature.

Built for the moment an agent is confidently wrong

Most frameworks were built for humans and retro-fitted with an LLM integration after ChatGPT. Bloom starts from a different observation: agents rarely fail while researching — they fail mid-sentence, writing something plausible without stopping to check. No document intercepts that. A type does. The defences below are ordered by what actually catches a mistake, not by what reads well in a README.

What Bloom shipsWhat it catches
Generated ApiRoute unionEvery path the API serves, derived from the route files and regenerated on install, dev and build. api.get('/api/user') becomes a compile error when the real route is /api/user/admin/users — the most expensive class of mistake, caught before the app runs.
One typed API clientshared/api.ts owns the base URL, the auth token and the error shape. No feature hand-rolls fetch, so none can hand-roll it wrong.
Gates on the router, not the handlerrouter.use(auth.requireLoginToken()) once per feature. A handler added next month inherits it instead of having to remember it.
Errors that name the causeA misconfigured API base says so, rather than Unexpected token '<' from a JSON parse three frames away. A route file the router will never mount warns at startup instead of quietly 404ing.
Palette lockdownRaw hex and stock Tailwind colour classes are absent from the build, so an agent cannot drift the design system — the wrong class does not exist.
Typed errors with module + code + docsUrlAn error that carries the page explaining it, so the next step is a link rather than a guess.
Single canonical API patternxxxClass.get() across every AppKit module. One shape to learn, one shape to get right.
llms.txt and AGENTS.md in every packageThe reference and the rules, re-synced from node_modules on every install so they cannot drift from the installed API. Genuinely useful — but read during research, which is not when mistakes happen. The rows above are what catch them.
Drift-checked public surface (CI)Every package fails CI if docs, types or template pins disagree with package.json.

Where Bloom stands vs established frameworks

Closest in scope to T3 Stack or RedwoodJS — not Laravel or NestJS directly. Bloom's differentiator is agentic-first design + cross-platform coverage; its weakness is ecosystem age.

DimensionBloomLaravelNestJST3 StackNext.js
Backend✓ AppKit✓ (PHP)✓ coreNext APIPartial
Frontend✓ UIKitBlade—✓ Next✓
Desktop (Electron)✓————
Mobile native (Capacitor)✓————
Auth built-in✓ JWT + roles✓via PassportNextAuth—
Queue / background jobs✓ memory→Redis✓ Horizon✓ Bull——
Ships llms.txt✓————
Ships AGENTS.md✓————
Agent skills✓————
Drift-checked docs (CI)✓————
Postinstall doc hydration✓————
Ecosystem maturityNew14 yrs7 yrs3 yrs8 yrs
LLM training-data familiarityLowHighHighMediumVery high

Bloom's bet: runtime llms.txt fetching closes the training-data gap. Agents don't need to have seen Bloom before — the docs ship with the code, version-matched, ready to load into context.

Best fit today: solo developers and small teams (≤10) shipping SaaS with heavy Claude Code / Cursor / Copilot usage, and anyone building cross-platform products (web + desktop + mobile) who doesn't want to stitch three stacks.

Not yet the right fit: 100-engineer enterprise teams where hiring pool and 10-year ecosystem matter more than agentic ergonomics. Use Laravel or NestJS for those.

One framework. Every shippable surface.

Bloom is the scaffolder teams reach for when they need a working stack — not an evening evaluating starters.

The six mistakes worth knowing before your agent makes them

Most ways to break a Bloom project now fail loudly. These are the ones that do not — the residue worth knowing. Point your AI agent at AGENTS.md where they're spelled out line by line.

Run the app

cd my-app
npm install        # installs dependencies AND copies appkit/uikit docs into docs/
npm run dev        # starts frontend + backend concurrently
App typeFrontendBackend
Web apphttp://localhost:5173 (Vite + React)http://localhost:3000 (Express + AppKit)
Desktop appElectron window at http://localhost:5183http://localhost:3000 (Express + AppKit)
Mobile appCapacitor native shellExternal API (configure VITE_API_URL)

One base. Layers on top.

Each layer adds features across the whole stack — API routes, pages, Prisma models, dependencies — and composes with the others. The preset names below are shorthand for a set of layers, and every one still works.

app The base React + Express, FBCA routing, TypeScript, Vite, a themeable component system, and public pages (about, contact, privacy, terms)
bloom create my-app
--auth Accounts Register, login, password reset, email verification, AuthGuard, the Prisma User model, and a guarded dashboard shell
bloom create my-app --auth
--admin Admin console User management with full CRUD, an append-only audit trail, editable app settings — all behind a role gate. Implies --auth
bloom create my-app --admin
--desktop Desktop Electron wrapper. Packages the same web build and the same API — not a second source tree. Ships to Windows / macOS / Linux
bloom create my-app --desktop
--mobile iOS + Android Capacitor wrapper over the same web build. Safe-area handling, status bar, Android back button. npx cap add ios generates the native project
bloom create my-app --mobile
basicapp = app The base, no layers
bloom create my-app basicapp
userapp = app + auth Accounts and a dashboard
bloom create my-app userapp
adminapp = app + auth + admin Everything, including the console
bloom create my-app adminapp

Because they compose, combinations that never existed as separate templates now do — an admin console that also ships as a desktop app and a phone app, from a single src/web:

compose Everything, everywhere Web + Electron + iOS + Android, one src/web
bloom create my-app adminapp --desktop --mobile

What a web scaffold looks like

my-app/
├── src/
│   ├── api/                      # Express backend (AppKit)
│   │   ├── features/
│   │   │   └── welcome/
│   │   │       ├── welcome.route.ts   # Auto-mounts at /api/welcome
│   │   │       └── welcome.service.ts
│   │   ├── lib/
│   │   │   └── api-router.ts          # FBCA auto-discovery for routes
│   │   └── server.ts
│   └── web/                      # React frontend (UIKit)
│       ├── features/
│       │   ├── main/pages/index.tsx   # → /
│       │   ├── gallery/pages/index.tsx
│       │   └── welcome/pages/index.tsx
│       ├── shared/
│       │   └── components/
│       └── main.tsx
├── docs/                         # Auto-populated after npm install
│   ├── appkit.md                 # ← node_modules/@bloomneo/appkit/llms.txt
│   ├── appkit-agents.md          # ← node_modules/@bloomneo/appkit/AGENTS.md
│   └── uikit.md                  # ← node_modules/@bloomneo/uikit/llms.txt
├── AGENTS.md                     # Project-level AI agent conventions
├── .env.example                  # Environment variable template
├── package.json
└── tsconfig.json

What an auth-enabled scaffold adds

my-app/
├── src/
│   ├── api/features/
│   │   ├── auth/                 # Registration, login, email verify, password reset
│   │   │   ├── auth.route.ts
│   │   │   └── auth.service.ts
│   │   ├── users/                # User CRUD, profile, role management
│   │   │   ├── users.route.ts
│   │   │   └── users.service.ts
│   │   └── admin/                # Admin panel APIs
│   │       ├── admin.route.ts
│   │       └── admin.service.ts
│   └── web/features/
│       ├── auth/pages/           # Login, register, forgot-password pages
│       ├── dashboard/pages/      # Main dashboard
│       └── admin/pages/          # Admin user management UI
├── prisma/
│   ├── schema.prisma             # User, Role, Session models
│   └── seed.ts                   # Default admin user
└── .env.example                  # DATABASE_URL, BLOOM_AUTH_SECRET, etc.
bloom create my-app userapp
cd my-app
npm install

# Configure your .env (copy from .env.example)
# Set DATABASE_URL, BLOOM_AUTH_SECRET, etc.

npx prisma db push     # create tables
npm run db:seed        # create default admin user
npm run dev            # start frontend + backend

Electron with an embedded backend

my-desktop-app/
├── src/
│   └── desktop/
│       ├── main/                 # Electron main process (AppKit + Express backend)
│       │   ├── features/
│       │   │   └── welcome/
│       │   │       ├── welcome.route.ts
│       │   │       └── welcome.service.ts
│       │   ├── lib/
│       │   └── server.ts
│       └── renderer/             # React frontend (UIKit)
│           ├── features/
│           ├── shared/
│           └── main.tsx
├── electron/
│   └── main.js                   # Electron main process entry
└── package.json
npm run dev          # Electron window + Vite hot reload + Express backend
npm run build        # production build
npm run preview      # preview production build in Electron

# electron-builder packages for your platform automatically:
# macOS → .dmg, Windows → .exe installer, Linux → .AppImage

iOS + Android from one React codebase

my-mobile-app/
├── src/
│   └── web/                      # React frontend (UIKit)
│       ├── features/
│       │   ├── home/pages/index.tsx
│       │   └── profile/pages/profile.tsx
│       ├── shared/
│       │   └── components/
│       │       └── MobileNav.tsx  # Uses UIKit TabBar + MobileLayout
│       └── main.tsx
├── ios/                          # Generated Xcode project
├── android/                      # Generated Android Studio project
└── capacitor.config.ts
cd my-mobile-app
npm install

npm run dev                    # Vite dev server (browser preview)

# iOS
npm run mobile:run:ios         # iOS Simulator
npm run mobile:build:ios       # Build for Xcode

# Android
npm run mobile:run:android     # Android Emulator
npm run android:build          # Build APK

New feature = new folder

Every new feature lives in its own folder. No imports to add, no routing files to edit.

# 1. Create the backend feature
mkdir -p src/api/features/invoice
# Add invoice.route.ts (auto-mounts at /api/invoice)
# Add invoice.service.ts (business logic)

# 2. Create the frontend feature
mkdir -p src/web/features/invoice/pages
# Add index.tsx → routes to /invoice
# Add [id].tsx → routes to /invoice/:id

# That's it. Restart the server — no config needed.
// src/api/features/invoice/invoice.route.ts
import { Router } from 'express';
import { authClass, errorClass } from '@bloomneo/appkit';
import { InvoiceService } from './invoice.service';

const router = Router();
const auth  = authClass.get();
const error = errorClass.get();

router.get('/', auth.requireLoginToken(), error.asyncRoute(async (req, res) => {
  const invoices = await InvoiceService.list(req.user!.userId);
  res.json({ invoices });
}));

router.post('/', auth.requireLoginToken(), error.asyncRoute(async (req, res) => {
  const invoice = await InvoiceService.create(req.user!.userId, req.body);
  res.status(201).json({ invoice });
}));

export default router;

Every project ships with AI context built in

docs/ folder

npm install automatically copies the latest llms.txt and AGENTS.md from installed packages into docs/appkit.md, docs/uikit.md.

AGENTS.md

Project-level AI instructions at the root: feature structure, env vars, always/never rules, and where to look for APIs.

Mistakes that fail fast

Agents guess — every model does. The generated ApiRoute union, the typed component props and the shared API client turn those guesses into compile errors instead of runtime bugs.

What each template needs in .env

TemplateRequired env vars
basicapp BLOOM_AUTH_SECRET
userapp BLOOM_AUTH_SECRET, DATABASE_URL, BLOOM_SECURITY_CSRF_SECRET, optionally RESEND_API_KEY for email
desktop-basicapp / desktop-userapp BLOOM_AUTH_SECRET — SQLite path is auto-configured
mobile-basicapp VITE_API_URL — points to your backend API

Frequently asked questions

What is Bloom?
Bloom is a TypeScript full-stack framework built for agentic coding. It ships three packages that compose: AppKit (Node backend toolkit, 14 modules), UIKit (React component library, 30 components), and a scaffolding CLI that wires them together via Feature-Based Component Architecture. One base plus composable layers — auth, admin, desktop (Electron) and mobile (Capacitor) — reach browser, desktop and phone from a single source tree. Generated route types and a shared API client turn the most common agent mistakes into compile errors rather than runtime bugs.
How is Bloom different from create-next-app, Remix CLI, T3 stack, or Expo CLI?
Bloom is narrower and more opinionated about one thing: keeping AI agents, humans, and the installed library versions in sync. Every scaffold ships a postinstall hook that copies llms.txt + AGENTS.md + Claude Code skills from node_modules into the project on every npm install — so docs never drift from installed versions. The CLI itself is tiny: bloom create and bloom start, nothing else.
What is FBCA (Feature-Based Component Architecture)?
FBCA is a convention where every feature lives in its own folder with a canonical shape. Backend: src/api/features/<name>/*.route.ts auto-mounts at /api/<name>. Frontend: src/web/features/<name>/pages/*.tsx auto-routes via import.meta.glob. Add a feature = create a folder. No manual route registration, no router config to edit. Dynamic segments use [param], catch-all uses [...path].
How do I use Bloom with Claude Code, Cursor, or GitHub Copilot?
After bloom create, run npm install. The postinstall hook copies appkit + uikit llms.txt + AGENTS.md into docs/, and every Claude Code skill into .claude/skills/. Point your agent at the project root; it will find AGENTS.md first, then docs/appkit-agents.md + docs/uikit-agents.md for library-specific rules. No extra configuration.
Can I build desktop and mobile apps with Bloom?
Yes. desktop-basicapp and desktop-userapp wrap the same web build and API in Electron (desktop-userapp adds auth). mobile-basicapp wraps the same web build with Capacitor 6 for iOS + Android; the API runs on a server the phone can reach. Same UIKit components and the same API across surfaces.
Does Bloom require a database?
Only the userapp and desktop-userapp templates require a database (Prisma with Postgres or SQLite). basicapp, desktop-basicapp, and mobile-basicapp run without one.
Is Bloom production-ready?
Yes. Bloom v5.3.1 is stable. Scaffolded apps use production-ready appkit 5.x + uikit 4.x components. A CI drift-check enforces that docs, template pins, and the installed bloom version stay in sync with package.json — so agents never read stale guidance.
Can I add a feature to an existing Bloom project?
Yes — by creating a folder. For a backend endpoint, add src/api/features/<name>/<name>.route.ts. For a page, add src/web/features/<name>/pages/index.tsx. FBCA auto-discovers both. There is no bloom add feature command; features are just folders.
What license is Bloom under?
MIT. Use Bloom itself and any scaffolded templates in commercial projects, fork them, vendor them — no attribution required. The source lives on GitHub at github.com/bloomneo/bloom.

Machine-readable specs for coding agents

llms.txt

Canonical CLI + template reference. Commands, templates, exit codes, flags, FBCA rules. View →

AGENTS.md

Always-do, never-do rules: what Bloom IS / IS NOT, template decision tree, FBCA conventions. View →

Auto-hydrated docs/

Every scaffold's postinstall copies appkit + uikit llms.txt + AGENTS.md into docs/ on every npm install. Agents always read version-matched docs.