⚡ FluxStack Application - Modern full-stack TypeScript framework
# Start development
bun run dev
# Build for production
bun run build
# Start production server
bun run startLiveComponentsDocs/
├── core/ # FluxStack framework (don't modify)
├── app/ # Your application code
│ ├── server/ # Backend API routes
│ ├── client/ # Frontend React app
│ └── shared/ # Shared types and utilities
└── package.json
- ⚡ Bun Runtime - 3x faster than Node.js
- 🔒 Full Type Safety - Eden Treaty + TypeScript
- 🎨 Modern UI - React 19 + Tailwind CSS v4
- 📋 Auto Documentation - Swagger UI generated
- 🔄 Hot Reload - Backend + Frontend
- 🔌 Plugin System - Extensible with custom plugins
Plugins are registered explicitly via framework.use() in
app/server/index.ts. There is no auto-discovery — every plugin you
want enabled must be imported and passed to .use(). This is the
only registration path: dev mode and production bundles behave identically.
FluxStack ships with several built-in plugins:
// app/server/index.ts
import { FluxStackFramework } from "@core/server"
import { vitePlugin } from "@core/plugins/built-in/vite"
import { swaggerPlugin } from "@core/plugins/built-in/swagger"
import { liveComponentsPlugin } from "@core/server/live"
const framework = new FluxStackFramework()
.use(swaggerPlugin)
.use(liveComponentsPlugin)
.use(vitePlugin)Install the package, import it, and register via .use():
// app/server/index.ts
import { csrfProtectionPlugin } from "@fluxstack/plugin-csrf-protection"
framework.use(csrfProtectionPlugin)A plugin is a plain object implementing the Plugin interface
from @fluxstack/plugin-kit. NOT a class — just an object with hook
functions as fields.
// plugins/my-plugin/index.ts
import type { Plugin, PluginContext, RequestContext } from "@fluxstack/plugin-kit"
export const myPlugin: Plugin = {
name: 'my-plugin',
version: '1.0.0',
// Runs once during framework.start() — use this to initialize
// resources, mount Elysia routes via context.app, register client
// hooks, etc.
setup: async (ctx: PluginContext) => {
ctx.logger.info('[my-plugin] initialized')
},
// Runs before every request is routed
onBeforeRoute: async (ctx: RequestContext) => {
// e.g. inspect ctx.path, reject with ctx.handled = true, etc.
},
// Runs if a handler throws
onError: async (ctx) => {
ctx.logger?.error('[my-plugin] handler failed', ctx.error)
},
}
export default myPluginThen register it:
// app/server/index.ts
import { myPlugin } from '../../plugins/my-plugin'
framework.use(myPlugin)| Hook | When it fires |
|---|---|
setup |
Once during framework.start(), before routes handle requests |
onBeforeServerStart / onServerStart / onAfterServerStart |
Server lifecycle |
onRequest |
Every incoming request, before routing |
onBeforeRoute / onAfterRoute |
Around route matching |
onBeforeResponse / onResponse |
Around response delivery |
onRequestValidation |
Request validation step (used by CSRF protection, auth guards, etc.) |
onError |
Uncaught errors in handlers |
onBuild / onBuildComplete |
Build pipeline |
See LLMD/reference/plugin-hooks.md for full hook signatures.
- LLM Documentation: Check
LLMD/INDEX.mdfor AI-optimized docs - Plugin Guide: Check
LLMD/resources/plugins-external.md - FluxStack Docs: Visit the FluxStack Repository
Built with ❤️ using FluxStack