flexism
v0.16.0
Published
Realtime-first fullstack framework for Flexium
Downloads
620
Maintainers
Readme
Flexism
Realtime-first Fullstack Framework for Flexium
Flexism is a fullstack framework built on top of Flexium, designed for building realtime applications with Server-Sent Events (SSE) and fine-grained reactivity.
Features
- File-based Routing - page.tsx, route.ts, layout.tsx conventions
- Two-function Pattern - Server loader + Client component in one file
- SSE Streaming - Real-time data with automatic reconnection
- Hot Module Replacement - CSS hot reload without page refresh
- Incremental Builds - Only changed files recompile
- CLI Tools - Development server, build, and production commands
Installation
npm install flexism flexiumQuick Start
npm create flexism@latest my-app
cd my-app
npm install
npm run devCLI Commands
flexism dev # Start development server with HMR
flexism build # Build for production
flexism start # Start production serverFile-based Routing
src/
├── page.tsx # / (home)
├── layout.tsx # Root layout
├── about/
│ └── page.tsx # /about
├── users/
│ ├── page.tsx # /users
│ └── [id]/
│ └── page.tsx # /users/:id
└── api/
└── messages/
└── route.ts # /api/messagesPage (Two-function Pattern)
Server logic and client component in one function:
// src/users/[id]/page.tsx
export default async function UserPage({ params }) {
// Server: runs on server, fetches data
const user = await db.users.find(params.id)
// Client: hydrates on client with server data
return ({ user }) => (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
)
}The outer function is the server loader (async, has DB access). The returned inner function is the client component (hydrated in browser).
API Route (SSE Streaming)
// src/api/messages/route.ts
import { sse } from 'flexism/server'
// SSE endpoint with async generator
export function GET() {
return sse(async function* () {
yield { text: 'Connected!' }
for await (const msg of db.messages.subscribe()) {
yield msg
}
})
}
// Regular JSON API
export async function POST(request) {
const body = await request.json()
const message = await db.messages.create(body)
return Response.json(message)
}Stream (Reactive SSE)
Declare real-time streams with the two-function pattern:
// src/chat/[roomId]/page.tsx
import { use } from 'flexium/core'
import { Stream } from 'flexism/stream'
export default async function ChatPage({ params }) {
// Server: Create stream with callback (runs on server)
const Messages = new Stream<Message[]>(() =>
db.messages.subscribe(params.roomId)
)
// Client: Receive StreamRef and subscribe reactively
return ({ Messages }) => {
const [messages] = use(Messages)
return (
<ul>
{messages?.map(m => <li key={m.id}>{m.text}</li>)}
</ul>
)
}
}How It Works
- Server:
Streamcaptures the callback and runtime params - Compiler: Generates SSE handler at
/_flexism/sse/{id} - Client: Receives
StreamRefthat auto-connects to SSE endpoint - Reactive:
use()hook updates UI when new data arrives
Stream with Options
const Notifications = new Stream<Notification>(
() => notificationService.subscribe(userId),
{
initial: [], // Initial value before connection
once: true // Close after first complete response
}
)Layout
Wrap pages with shared UI:
// src/layout.tsx
export function Component({ children }) {
return (
<html>
<head><title>My App</title></head>
<body>
<nav>...</nav>
{children}
</body>
</html>
)
}Requirements
- Node.js 18.0.0 or higher
- Flexium >= 0.15.8
Documentation
Full documentation available at https://flexium.junhyuk.im
License
MIT
