create-fluxstack
v1.17.1
Published
⚡ Revolutionary full-stack TypeScript framework with Declarative Config System, Elysia + React + Bun
Maintainers
Readme
⚡ FluxStack
The Full-Stack TypeScript Framework for Real-Time Apps
Build modern web apps with Bun, Elysia, React, and Eden Treaty
Quick Start • Features • Live Components • Documentation
✨ Key Features
🚀 Blazing Fast
- Bun Runtime - 3x faster than Node.js
- Elysia.js - High-performance backend
- Vite 7 - Lightning-fast HMR
🔒 Type-Safe Everything
- Eden Treaty - Automatic type inference
- End-to-End Types - Backend to frontend
- Zero Manual DTOs - Types flow naturally
⚡ Live Components
- WebSocket Sync - Real-time state synchronization
- Reactive Proxy -
this.state.count++auto-syncs - Room System - Multi-room real-time communication
- Auth System - Declarative RBAC for components
🎯 Production Ready
- Docker Multi-Stage - Optimized containers
- Declarative Config - Laravel-inspired config system
- Plugin Security - Whitelist-based NPM plugin safety
🚀 Quick Start
# Create a new FluxStack app
bunx create-fluxstack my-awesome-app
cd my-awesome-app
bun run devThat's it! Your full-stack app is running:
| Service | URL | |---------|-----| | 🌐 Frontend | http://localhost:5173 | | ⚙️ Backend API | http://localhost:3000 | | 📚 Swagger Docs | http://localhost:3000/swagger | | 🩺 Health Check | http://localhost:3000/api/health |
Alternative Installation
# Create in current directory
mkdir my-app && cd my-app
bunx create-fluxstack .
bun run dev💎 Tech Stack
🏗️ Architecture Overview
graph TB
subgraph "🎨 Frontend Layer"
React[React 19 + Vite]
LiveClient[Live Components Client]
Eden[Eden Treaty]
end
subgraph "🔌 Communication"
HTTP[HTTP / REST]
WS[WebSocket]
end
subgraph "⚙️ Backend Layer"
Elysia[Elysia.js]
Routes[API Routes]
LiveServer[Live Components Server]
Rooms[Room System]
end
React --> Eden
Eden --> HTTP
HTTP --> Elysia
Elysia --> Routes
LiveClient --> WS
WS --> LiveServer
LiveServer --> Rooms📁 Project Structure
FluxStack/
├── 🔒 core/ # Framework Core (Read-Only)
│ ├── framework/ # FluxStack orchestrator
│ ├── server/ # Elysia plugins, middleware, live engine
│ ├── client/ # Vite integration, Live hooks, providers
│ ├── cli/ # CLI commands & generators
│ ├── plugins/ # Built-in plugins (Swagger, Vite, etc.)
│ ├── types/ # Framework type definitions
│ └── utils/ # Logger, config schema, errors
│
├── 👨💻 app/ # Your Application Code
│ ├── server/ # Backend (Elysia + Bun)
│ │ ├── controllers/ # Business logic
│ │ ├── routes/ # API endpoints + schemas
│ │ ├── live/ # Live Components (server-side)
│ │ └── app.ts # Elysia app instance (Eden Treaty export)
│ │
│ ├── client/ # Frontend (React + Vite)
│ │ └── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Route pages
│ │ ├── live/ # Live Components (client-side)
│ │ └── lib/ # Eden Treaty client
│ │
│ └── shared/ # Shared type definitions
│
├── ⚙️ config/ # Declarative Configuration
│ ├── system/ # Config files (app, server, db, logger, etc.)
│ ├── fluxstack.config.ts # FluxStack config
│ └── index.ts # Centralized exports
│
├── 🔌 plugins/ # Project Plugins (auto-discovered)
├── 🧪 tests/ # Test suite (unit + integration)
├── 🤖 LLMD/ # LLM-Optimized Documentation
└── 🐳 Dockerfile # Multi-stage production build⚡ Live Components
Real-time WebSocket components with automatic state synchronization between server and client. Define state and logic on the server, interact with it from React — updates sync instantly via WebSocket.
🖥️ Server Side
// app/server/live/LiveCounter.ts
import { LiveComponent } from '@/core/server'
export class LiveCounter extends LiveComponent<{
count: number
}> {
static defaultState = { count: 0 }
async increment() {
this.state.count++ // auto-syncs via Proxy
return { success: true }
}
async decrement() {
this.state.count--
return { success: true }
}
async reset() {
this.state.count = 0
return { success: true }
}
}⚛️ Client Side
// app/client/src/live/CounterDemo.tsx
import { Live } from '@/core/client'
import { LiveCounter } from '@server/live/LiveCounter'
export function CounterDemo() {
const counter = Live.use(LiveCounter, {
room: 'global-counter',
initialState: LiveCounter.defaultState
})
return (
<div>
<span>{counter.$state.count}</span>
<button
onClick={() => counter.increment()}
disabled={counter.$loading}
>
+
</button>
<button onClick={() => counter.decrement()}>
-
</button>
<span>
{counter.$connected ? '🟢' : '🔴'}
</span>
</div>
)
}🔑 Client Proxy API
The Live.use() hook returns a Proxy object with full access to server state and actions:
const component = Live.use(MyComponent)
// State access
component.$state // Full state object
component.myProp // Direct property access via Proxy
component.$connected // Boolean - WebSocket connected?
component.$loading // Boolean - action in progress?
component.$error // Error message or null
// Actions
await component.myAction() // Call server method (type-safe)
component.$set('key', val) // Set a single property
// Form field binding
<input {...component.$field('email', { syncOn: 'change', debounce: 500 })} />
<input {...component.$field('name', { syncOn: 'blur' })} />
await component.$sync() // Manual sync for deferred fields
// Room events
component.$room.emit('event', data)
component.$room.on('message', handler)🏠 Room System
Multi-room real-time communication for Live Components — users in the same room share events.
Server: join rooms and emit events
// app/server/live/ChatRoom.ts
export class ChatRoom extends LiveComponent<State> {
async joinRoom(payload: { roomId: string }) {
this.$room(payload.roomId).join()
this.$room(payload.roomId).on('message:new', (msg) => {
this.setState({
messages: [...this.state.messages, msg]
})
})
return { success: true }
}
async sendMessage(payload: { text: string }) {
const message = { id: Date.now(), text: payload.text }
this.setState({
messages: [...this.state.messages, message]
})
this.$room('chat').emit('message:new', message)
return { success: true }
}
}HTTP API for external integrations
# Send a message to a room via API
curl -X POST \
http://localhost:3000/api/rooms/general/messages \
-H "Content-Type: application/json" \
-d '{"user": "Bot", "text": "Hello from API!"}'
# Emit a custom event to a room
curl -X POST \
http://localhost:3000/api/rooms/tech/emit \
-H "Content-Type: application/json" \
-d '{
"event": "notification",
"data": {"type": "alert", "msg": "Deploy done!"}
}'Rooms are accessible both from Live Components (WebSocket) and via REST API for webhooks, bots, and external services.
🔐 Authentication
Declarative auth for Live Components with role-based access control.
Server: protect components and actions
// app/server/live/AdminPanel.ts
export class AdminPanel extends LiveComponent<State> {
static componentName = 'AdminPanel'
static defaultState = { users: [] }
// Component requires admin role
static auth = {
required: true,
roles: ['admin']
}
// Per-action permissions
static actionAuth = {
deleteUser: { permissions: ['users.delete'] }
}
async deleteUser(payload: { userId: string }) {
// Access user info via $auth
console.log(`${this.$auth.user?.id} deleting user`)
return { success: true }
}
}Client: authenticate dynamically
import { useLiveComponents } from '@/core/client'
function LoginButton() {
const { authenticated, authenticate } = useLiveComponents()
const handleLogin = async () => {
await authenticate({ token: 'my-jwt-token' })
// Components auto re-mount with new auth!
}
return (
<button onClick={handleLogin}>
{authenticated ? 'Logged in' : 'Login'}
</button>
)
}Components that fail with AUTH_DENIED automatically retry when authentication succeeds.
🔒 Type-Safe API Development
Eden Treaty infers types from Elysia route definitions automatically. No manual DTOs.
📝 Define Backend Route
// app/server/routes/users.routes.ts
import { Elysia, t } from 'elysia'
export const userRoutes = new Elysia({ prefix: '/users' })
.post('/', ({ body }) => createUser(body), {
body: t.Object({
name: t.String(),
email: t.String({ format: 'email' })
}),
response: t.Object({
success: t.Boolean(),
user: t.Optional(t.Object({
id: t.Number(),
name: t.String(),
email: t.String()
}))
})
})✨ Use in Frontend (Fully Typed!)
// app/client/src/lib/eden-api.ts
import { api } from './eden-api'
// TypeScript knows all types automatically!
const { data, error } = await api.users.post({
name: 'Ada Lovelace', // ✅ string
email: '[email protected]' // ✅ string (email)
})
if (data?.user) {
console.log(data.user.name) // ✅ string
console.log(data.user.id) // ✅ number
}Benefits:
- ✅ Zero Manual Types — Types flow automatically from backend to frontend
- ✅ Full Autocomplete — IntelliSense in your IDE
- ✅ Refactor Friendly — Change backend schema, frontend updates automatically
⚙️ Declarative Configuration
Laravel-inspired config system with schema validation and full type inference.
// config/system/app.config.ts
import { defineConfig, config } from '@/core/utils/config-schema'
const appConfigSchema = {
name: config.string('APP_NAME', 'FluxStack', true),
port: config.number('PORT', 3000, true),
env: config.enum('NODE_ENV', ['development', 'production', 'test'] as const, 'development', true),
debug: config.boolean('DEBUG', false),
} as const
export const appConfig = defineConfig(appConfigSchema)
// appConfig.port → number, appConfig.env → "development" | "production" | "test"All environment variables are validated at boot time. See .env.example for available options.
🔌 Plugin System
Three-layer plugin architecture with security-first design:
| Layer | Location | Auto-discovered | Trusted |
|-------|----------|-----------------|---------|
| 🔒 Built-in | core/plugins/ | No (manual .use()) | ✅ Yes |
| 📁 Project | plugins/ | ✅ Yes | ✅ Yes |
| 📦 NPM | node_modules/ | ❌ No (opt-in) | 🔒 Whitelist required |
NPM plugins are blocked by default. To add one safely:
bun run cli plugin:add fluxstack-plugin-auth
# Audits the package, installs it, and adds it to the whitelist📜 Available Scripts
🔨 Development
bun run dev # Full-stack with hot reload
bun run dev:frontend # Frontend only (port 5173)
bun run dev:backend # Backend only (port 3001)🚀 Production
bun run build # Production build
bun run start # Start production server🧪 Testing & Quality
bun run test # Run tests (Vitest)
bun run test:ui # Vitest with browser UI
bun run test:coverage # Coverage report
bun run typecheck:api # Strict TypeScript check🛠️ CLI & Utilities
bun run cli # CLI interface
bun run make:component # Generate a Live Component
bun run sync-version # Sync version across files🔀 Frontend Routes
Default routes included in the demo app (React Router v7):
| Route | Page |
|-------|------|
| / | Home |
| /counter | Live Counter |
| /form | Live Form |
| /upload | Live Upload |
| /auth | Auth Demo |
| /api-test | Eden Treaty Demo |
🔧 Environment Variables
Copy .env.example to .env and adjust as needed:
cp .env.example .env| Variable | Default | Description |
|----------|---------|-------------|
| PORT | 3000 | Backend server port |
| HOST | localhost | Server host |
| FRONTEND_PORT | 5173 | Vite dev server port |
| NODE_ENV | development | Environment |
| LOG_LEVEL | info | Logging level |
| CORS_ORIGINS | localhost:3000,localhost:5173 | Allowed CORS origins |
| SWAGGER_ENABLED | true | Enable Swagger UI |
| SWAGGER_PATH | /swagger | Swagger UI path |
See .env.example for the full list.
🐳 Docker
# Build
docker build -t fluxstack-app .
# Run
docker run -p 3000:3000 fluxstack-appThe Dockerfile uses a multi-stage build with oven/bun:1.2-alpine and runs as a non-root user.
🤔 Why FluxStack?
⚙️ Requirements
📦 System Requirements
- Bun >= 1.2.0 (required runtime)
- Git (for version control)
- Linux, macOS, or Windows
📥 Install Bun
macOS / Linux:
curl -fsSL https://bun.sh/install | bashWindows:
powershell -c "irm bun.sh/install.ps1 | iex"⚠️ Important: FluxStack requires Bun. Node.js is not supported as a runtime.
📚 Documentation & Support
📖 Documentation
- LLMD Index — Navigation hub
- Framework Lifecycle
- Live Components
- Live Auth
- Live Rooms
- Routes & Eden Treaty
- CLI Reference
- Troubleshooting
💬 Community
🔄 Upgrading
bunx create-fluxstack@latest🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'Add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
Please open an issue first to discuss larger changes.
📄 License
MIT - Marcos Brendon De Paula
Made with ❤️ by the FluxStack Team
Star ⭐ this repo if you find it helpful!
