# 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 (
{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!** ✨