Bloom scaffolds fullstack apps with Feature-Based Component Architecture. AppKit backend + UIKit frontend — wired up, configured, AI-ready, and running in minutes.
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
# Desktop app (Electron, SQLite, cross-platform)
bloom create my-app desktop-basicapp
bloom create my-app desktop-userapp
# Mobile app (iOS + Android via Capacitor 7)
bloom create my-app mobile-basicapp
cd my-app
npm install # installs dependencies AND copies appkit/uikit docs into docs/
npm run dev # starts frontend + backend concurrently
| App type | Frontend | Backend |
|---|---|---|
| Web app | http://localhost:5173 (Vite + React) | http://localhost:3000 (Express + AppKit) |
| Desktop app | Electron window at http://localhost:5183 | http://localhost:3000 (Express + AppKit) |
| Mobile app | Capacitor native shell | External API (configure VITE_API_URL) |
bloom create my-app
bloom create my-app userapp
bloom create my-app desktop-basicapp
bloom create my-app desktop-userapp
bloom create my-app mobile-basicapp
No routing config. No manual registration. No import lists. Drop a folder inside features/ and it's automatically discovered on both frontend and backend.
# Backend — drop a folder → auto-registered API route
src/api/features/
└── invoice/
├── invoice.route.ts # Auto-mounts at /api/invoice
└── invoice.service.ts
# Frontend — drop a folder → auto-routed page
src/web/features/
└── invoice/
└── pages/
├── index.tsx # → /invoice
├── [id].tsx # → /invoice/:id (dynamic)
└── new.tsx # → /invoice/new
| File path | Becomes route |
|---|---|
features/main/pages/index.tsx | / |
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 |
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
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
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
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
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;
docs/ foldernpm install automatically copies the latest llms.txt and AGENTS.md from installed packages into docs/appkit.md, docs/uikit.md.
AGENTS.mdProject-level AI instructions at the root: feature structure, env vars, always/never rules, and where to look for APIs.
AI coding agents read docs/appkit.md first and never guess method names. LLMs.txt coverage means the first suggestion is usually the correct one.
| Template | Required 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 |