@flareflow/cli
v0.0.3
Published
flareflow CLI
Readme
flareflow
The Operating System for Edge Apps on Cloudflare
flareflow is a high-level, production-grade backend framework and infrastructure abstraction layer built specifically for the Cloudflare ecosystem.
If Firebase is for GCP and Supabase is for Postgres, then flareflow is for Cloudflare.
✨ Features
- Unified Context: Access
db,cache,storage,jobs,actors, andauthfrom a single, type-safectxobject. - Stateful Edge Actors: Durable Objects as first-class business entities with typed RPC and automatic state persistence.
- Durable Workflow Engine: Multi-step, resumable orchestrations (Sagas) with automatic retries and compensation logic.
- Realtime Rooms: WebSocket-based rooms with built-in presence and broadcasting using Durable Objects.
- Type-safe SQL: Integrated Drizzle ORM over Cloudflare D1.
- Edge Auth & RBAC: Stateless JWT-based authentication and Role-Based Access Control optimized for the edge.
- Background Jobs: Typed async tasks powered by Cloudflare Queues.
- Modern CLI: Scaffolding, boilerplate generators, and a typed
flareflow.config.ts.
📦 Project Structure
flareflow is a modular TypeScript monorepo:
@flareflow/core: The heart of the framework, HTTP engine (Hono), and DI Context.@flareflow/db: D1 wrapper with Drizzle ORM.@flareflow/actor: Durable Object abstraction and RPC bridge.@flareflow/workflow: Durable saga/workflow engine.@flareflow/realtime: WebSocket room management.@flareflow/auth: Edge-optimized authentication and RBAC.@flareflow/jobs: Cloudflare Queues abstraction.@flareflow/cache: KV-based typed caching.@flareflow/storage: R2-based object storage.@flareflow/cli: Theflareflowcommand-line developer tool.
🚀 Getting Started
1. Initialize a new project
npx @flareflow/cli init my-edge-app
cd my-edge-app
npm install2. Configure your app (flareflow.config.ts)
flareflow replaces manual wrangler.toml management with a typed TypeScript configuration.
import { defineConfig } from "@flareflow/cli";
export default defineConfig({
name: "my-edge-app",
compatibilityDate: "2024-04-05",
resources: {
db: { type: "d1", name: "prod-db", database_id: "xxxx-yyyy-zzzz" },
cache: { type: "kv", name: "prod-cache", id: "aaaa-bbbb-cccc" }
},
actors: ["CounterActor"],
rooms: ["ChatRoom"],
workflows: ["OrderWorkflow"]
});3. Start development
flareflow dev🛠️ Core Abstractions
Entities (D1 + Drizzle)
Define your schema once, and it's automatically available on ctx.db.
import { entity, field } from "@flareflow/db";
export const Users = entity("users", {
id: field.id(),
name: field.string("name"),
email: field.string("email").unique(),
});
// usage in a route
app.get("/users/:id", async (ctx) => {
return await ctx.db.select().from(Users).where(eq(Users.id, ctx.param("id")));
});Actors (Durable Objects)
Business logic that lives in a stateful, single-threaded isolate at the edge.
export const CounterActor = actor("CounterActor", {
state: { count: 0 },
methods: {
async increment(ctx) {
ctx.state.count++; // State is automatically persisted
return ctx.state.count;
}
}
});
// call from an HTTP handler
const count = await ctx.actor(CounterActor).id("global-counter").increment();Workflows (Durable Sagas)
Orchestrate complex, multi-step business logic with failure recovery.
export const OrderWorkflow = workflow("OrderWorkflow", {
steps: [
{
name: "reserve-inventory",
action: async (ctx, state) => Inventory.reserve(state.itemId),
compensate: async (ctx, state) => Inventory.release(state.itemId)
},
{
name: "charge-card",
action: async (ctx, state) => Stripe.charge(state.amount)
}
]
});
// trigger the workflow
await ctx.workflow(OrderWorkflow).start("order_123", { itemId: "sku_1", amount: 100 });Realtime (WebSockets)
Built-in pub/sub and presence rooms.
export const ChatRoom = room("ChatRoom", {
onJoin: (ctx, client) => ctx.broadcast("user_joined", { id: client.id }),
onMessage: (ctx, client, msg) => ctx.broadcast("message", { from: client.id, text: msg.text })
});
// upgrade to WebSocket in a route
app.get("/chat/:id", (ctx) => ctx.realtime(ChatRoom).id(ctx.param("id")).upgrade());Background Jobs (Queues)
Typed async tasks with automatic retries and dead-letter queues.
export const WelcomeEmailJob = job("WelcomeEmail", {
handler: async (ctx, payload: { email: string; name: string }) => {
await ctx.email.send(payload.email, `Welcome to the app, ${payload.name}!`);
}
});
// enqueue from a route or actor
await ctx.jobs.enqueue(WelcomeEmailJob, { email: "[email protected]", name: "Alice" });Storage (R2)
Interact with object storage using a simple, typed API.
app.post("/upload", async (ctx) => {
const { file } = await ctx.req.parseBody();
await ctx.storage.bucket("avatars").put("user_1.jpg", file);
return ctx.json({ status: "uploaded" });
});Cache (KV)
Fast, edge-optimized key-value storage with built-in getOrSet.
app.get("/posts/:id", async (ctx) => {
const cacheKey = `post:${ctx.param("id")}`;
return await ctx.cache.getOrSet(cacheKey, async () => {
return await ctx.db.select().from(Posts).where(eq(Posts.id, ctx.param("id")));
}, { ttl: 3600 });
});💻 CLI Commands
flareflow init <dir>: Scaffold a new project.flareflow dev: Start local development with hot-reloading and infrastructure simulation.flareflow generate <type> <name>: Generate boilerplate forentity,actor,job,workflow, orroom.flareflow db:generate: Generate SQL migrations from your Entities.flareflow db:migrate: Apply migrations to D1 (local or remote).flareflow deploy: Automatically generatewrangler.tomland deploy to Cloudflare.flareflow studio: Start the local web dashboard to inspect your data, actors, and workflows.
📄 License
MIT
