# hono - docs --- # 🔥 FX + Hono Integration Guide ## 🎯 **Overview** This guide shows how to integrate FX Framework into your **Hono backend** while maintaining all FX functionality including: - ✅ **Cross-realm execution** for fx-flow - ✅ **Database proxying** for fx-orm - ✅ **CORS-safe API calls** for web workers - ✅ **Module loading** for sync imports - ✅ **Auto-loading plugins** with zero configuration **Perfect for:** React + ShadCN + Hono + FX stacks --- ## 🚀 **Quick Setup** ### **1. Install Dependencies** ```bash # Your existing Hono project npm install hono # Add to your server file import { setupFXWithHono } from './fx/plugins/fx-hono.ts'; import { fx } from './fx/fx.ts'; ``` ### **2. Basic Integration** ```typescript // server.ts import { Hono } from 'hono'; import { fx } from './fx/fx.ts'; import { setupFXWithHono } from './fx/plugins/fx-hono.ts'; const app = new Hono(); // Mount FX routes into your Hono app const fxHono = setupFXWithHono(app, fx, { basePath: '/fx', // FX routes at /fx/* corsEnabled: true, // Enable CORS for React allowedOrigins: ['http://localhost:3000'] // Your React dev server }); // Your existing API routes app.get('/api/hello', (c) => c.json({ message: 'Hello from Hono + FX!' })); // Start server export default app; ``` ### **3. That's It!** Your Hono app now supports all FX functionality: - 🌐 **`/fx/proxy`** - Cross-origin API calls - 📦 **`/fx/module`** - Module loading - 💚 **`/fx/health`** - Health checks - 🔄 **Cross-realm execution** for fx-flow --- ## 🏗️ **Complete Stack Example** ### **Backend (Hono + FX)** ```typescript // server/main.ts import { Hono } from 'hono'; import { cors } from 'hono/cors'; import { logger } from 'hono/logger'; import { fx, $$ } from '../fx/fx.ts'; import { setupFXWithHono } from '../fx/plugins/fx-hono.ts'; const app = new Hono(); // Middleware app.use('*', logger()); app.use('/api/*', cors({ origin: ['http://localhost:3000'], // React allowMethods: ['GET', 'POST', 'PUT', 'DELETE'], allowHeaders: ['Content-Type', 'Authorization'] })); // ===== FX INTEGRATION ===== const fxHono = setupFXWithHono(app, fx, { basePath: '/fx', allowedOrigins: ['http://localhost:3000'] }); // Initialize FX state $$('app').set({ name: 'My App', environment: 'development', startTime: Date.now() }); // ===== API ROUTES WITH FX ===== app.get('/api/users', async (c) => { // FX auto-loads fx-orm on first $db access const users = $db.users.all(); // Reactive stats $$('api.requests.users').set( ($$('api.requests.users').get() || 0) + 1 ); return c.json({ users, total: users.length }); }); app.post('/api/users', async (c) => { const userData = await c.req.json(); // Use FX flow for complex business logic const result = $flow('createUser') // Auto-loads fx-flow .node('validate', { runsOn: 'server', effect: (ctx) => { if (!userData.email?.includes('@')) { ctx.error('Invalid email'); return; } ctx.next('create', userData); } }) .node('create', { runsOn: 'server', effect: (ctx) => { const userId = $db.users.create(ctx.in); // Auto-loads fx-orm ctx.set({ userId, created: true }); } }) .start('validate', userData); return c.json(result.data); }); // Real-time dashboard app.get('/api/dashboard', (c) => { return c.json({ users: $db.users.all().length, requests: $$('api.requests.users').get() || 0, uptime: Date.now() - $$('app.startTime').get(), health: 'ok' }); }); export default app; ``` ### **Frontend (React + ShadCN + FX)** ```tsx // components/Dashboard.tsx import { useEffect, useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; export function Dashboard() { const [stats, setStats] = useState(null); useEffect(() => { // FX auto-loads plugins when globals are first accessed const { useFXAPI } = FXReact; // Auto-loads fx-react + dependencies // Reactive API calls const dashboardData = useFXAPI('/api/dashboard'); dashboardData.watch(data => { setStats(data); // Update FX state for other components $$('dashboard.stats').set(data); }); // Real-time updates every 30 seconds const interval = setInterval(() => { // Trigger new API call $$('dashboard.refreshTrigger').set(Date.now()); }, 30000); return () => clearInterval(interval); }, []); if (!stats) return
Loading dashboard...
; return (
Total Users

{stats.users}

API Requests

{stats.requests}

Uptime

{Math.floor(stats.uptime / 1000 / 60)} min

Health

{stats.health}

); } ``` ```tsx // components/UserManager.tsx import { useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent } from '@/components/ui/card'; export function UserManager() { // FX React hooks for state management const { useFXState, useFXAPI, useFXForm } = FXReact; // Reactive state via FX const [selectedUserId, setSelectedUserId] = useFXState('ui.selectedUser', null); // API integration const { data: users, loading } = useFXAPI('/api/users'); // Form management with FX const form = useFXForm( { name: '', email: '' }, { fxPath: 'forms.createUser', onSubmit: async (values) => { const response = $api.post('/api/users', values); // Auto-loads fx-api response.watch(result => { if (result.created) { // Clear form form.setValues({ name: '', email: '' }); // Refresh user list $$('api.users.refresh').set(Date.now()); } }); } } ); return (
form.setValue('name', e.target.value)} /> form.setValue('email', e.target.value)} />
{loading ? (
Loading users...
) : ( users?.map(user => ( setSelectedUserId(user.id)} >

{user.name}

{user.email}

)) )}
); } ``` --- ## 🔧 **Advanced Configuration** ### **Custom FX Routes in Hono** ```typescript // Add custom FX-powered routes fxHono.addCustomRoutes(app, { '/analytics': async (c, fx) => { // Complex analytics using FX const userStats = $db.users.where('[active=true]'); // Auto-loads fx-orm const apiStats = $$('api.requests').select('.request[status="success"]'); return { activeUsers: userStats.length, successfulRequests: apiStats.length, timestamp: Date.now() }; }, '/flows/status': async (c, fx) => { // Flow execution status const flows = $$('flows').select('.flow[status="running"]'); return { runningFlows: flows.length, flows: flows.map(flow => ({ name: flow.name, progress: flow.progress, startTime: flow.startTime })) }; } }); ``` ### **Database Integration** ```typescript // Configure fx-orm for your database app.use('/api/*', async (c, next) => { // Set up database connection for FX if (!$db.isConnected) { await $db.connect(Deno.env.get('DATABASE_URL') || 'sqlite://./app.db'); } await next(); }); ``` ### **Authentication with FX Safe** ```typescript // Use FX safe patterns for resilient auth app.use('/api/protected/*', async (c, next) => { const token = c.req.header('authorization'); const authResult = $safe.circuit('auth-service').execute(() => { return $api.post('/auth/verify', { token }); // Auto-loads fx-api + fx-safe }); if (!authResult.success) { return c.json({ error: 'Unauthorized' }, 401); } // Store in FX for cross-request access $$('request.user').set(authResult.user); await next(); }); ``` --- ## 🎯 **Key Benefits** ### **✅ Single Server** - No need to run FX's Deno server separately - All FX functionality in your Hono backend - Simplified deployment and configuration ### **✅ Seamless Integration** - FX routes mount cleanly into Hono - Your API routes can use FX globals - React frontend gets full FX reactivity ### **✅ Auto-Loading Magic** - Just use `$db`, `$api`, `jsx`, etc. - Plugins load automatically with dependencies - Zero configuration needed ### **✅ Full Stack Reactivity** - Backend: FX reactive state management - Frontend: React + FX hooks - Real-time: Automatic UI updates --- ## 🚨 **Important Notes** ### **CORS Configuration** Make sure to allow your React dev server: ```typescript allowedOrigins: ['http://localhost:3000', 'http://localhost:5173'] ``` ### **Environment Variables** ```bash # Your .env file PORT=8787 DATABASE_URL=sqlite://./app.db FX_CORS_ORIGINS=http://localhost:3000,http://localhost:5173 ``` ### **Build Manifest** Run before deployment: ```bash deno task build-manifest ``` This generates the auto-loading code that makes plugin globals work magically. --- ## 🎊 **Result: Perfect Stack Integration** With this setup, you get: **Backend (Hono + FX):** - 🔥 Hono's excellent routing and middleware - 🪄 FX's reactive state management and auto-loading plugins - 🗄️ fx-orm for database with zero latency - 🔄 fx-flow for complex business logic - 🛡️ fx-safe for resilient external API calls **Frontend (React + ShadCN + FX):** - ⚛️ React with ShadCN components - 🪄 FX reactive hooks via FXReact - 🎯 Auto-loading plugins (jsx, $, $api, etc.) - 🔄 Seamless state synchronization **The ultimate modern web stack with FX's reactive superpowers!** ✨