Microservices Architecture
FluxKit wires can be deployed as independent microservices or combined in a single process. This guide shows both approaches.
Monolith (Single Process)
The simplest approach. All wires run in one Node.js process:
import { FluxKit } from "@fluxkitdev/core";
import { auth } from "@fluxkitdev/auth";
import { messaging } from "@fluxkitdev/messaging";
import { store } from "@fluxkitdev/store";
import { pay } from "@fluxkitdev/pay";
import { onchain } from "@fluxkitdev/onchain";
const app = new FluxKit({
wires: [auth(), messaging(), store(), pay(), onchain()],
database: { uri: process.env.MONGODB_URI },
});
await app.start({ port: 3000 });
Best for: Small to medium applications, prototypes, and teams that prefer simplicity.
Microservices (Separate Processes)
Each wire runs in its own process with its own port. They share the same MongoDB database.
Auth Service
// services/auth/src/index.ts
import { FluxKit } from "@fluxkitdev/core";
import { auth } from "@fluxkitdev/auth";
const app = new FluxKit({
wires: [auth()],
database: { uri: process.env.MONGODB_URI },
});
await app.start({ port: 3001 });
Messaging Service
// services/messaging/src/index.ts
import { FluxKit } from "@fluxkitdev/core";
import { messaging } from "@fluxkitdev/messaging";
const app = new FluxKit({
wires: [messaging()],
database: { uri: process.env.MONGODB_URI },
});
await app.start({ port: 3002 });
Store Service
// services/store/src/index.ts
import { FluxKit } from "@fluxkitdev/core";
import { store } from "@fluxkitdev/store";
const app = new FluxKit({
wires: [store()],
database: { uri: process.env.MONGODB_URI },
});
await app.start({ port: 3003 });
Docker Compose
Run all services with Docker:
# docker-compose.yml
version: "3.8"
services:
mongodb:
image: mongo:7
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
auth:
build:
context: ./services/auth
ports:
- "3001:3001"
environment:
- MONGODB_URI=mongodb://mongodb:27017/myapp
- JWT_SECRET=${JWT_SECRET}
- PORT=3001
depends_on:
- mongodb
messaging:
build:
context: ./services/messaging
ports:
- "3002:3002"
environment:
- MONGODB_URI=mongodb://mongodb:27017/myapp
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USER=${SMTP_USER}
- SMTP_PASS=${SMTP_PASS}
- PORT=3002
depends_on:
- mongodb
store:
build:
context: ./services/store
ports:
- "3003:3003"
environment:
- MONGODB_URI=mongodb://mongodb:27017/myapp
- S3_BUCKET=${S3_BUCKET}
- S3_REGION=${S3_REGION}
- S3_ACCESS_KEY=${S3_ACCESS_KEY}
- S3_SECRET_KEY=${S3_SECRET_KEY}
- PORT=3003
depends_on:
- mongodb
frontend:
build:
context: ./frontend
ports:
- "80:80"
volumes:
mongo-data:
Reverse Proxy (nginx)
Route requests to the correct service:
# nginx.conf
upstream auth_service {
server auth:3001;
}
upstream messaging_service {
server messaging:3002;
}
upstream store_service {
server store:3003;
}
server {
listen 80;
location /auth/ {
proxy_pass http://auth_service;
}
location /messaging/ {
proxy_pass http://messaging_service;
}
location /store/ {
proxy_pass http://store_service;
}
location /health {
proxy_pass http://auth_service;
}
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
}
}
Shared Dockerfile
Each service uses the same Dockerfile pattern:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist/ ./dist/
EXPOSE ${PORT:-3000}
CMD ["node", "dist/index.js"]
Service-to-Service Communication
If services need to communicate with each other, use the HTTP client from the core wire:
// In the auth service, send a welcome email via the messaging service
import { FluxKit } from "@fluxkitdev/core";
const app = new FluxKit({ ... });
app.http.post("/auth/register", {
handler: async (req, res) => {
const user = await app.auth.createUser(req.body);
// Call the messaging service
await fetch("http://messaging:3002/messaging/email", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${internalToken}`,
},
body: JSON.stringify({
to: user.email,
subject: "Welcome!",
body: "<h1>Welcome to our platform!</h1>",
}),
});
res.status(201).json({ user });
},
});
Hybrid Approach
Group related wires together. This is often the best balance between simplicity and scalability:
Service 1 (User-facing): auth + store
Service 2 (Background): messaging
Service 3 (Payments): pay + onchain
Service 4 (Frontend): @fluxkitdev/ui (React)
// services/user/src/index.ts
const app = new FluxKit({
wires: [auth(), store()],
database: { uri: process.env.MONGODB_URI },
});
await app.start({ port: 3001 });
Scaling
Each service can be scaled independently:
docker compose up --scale messaging=3 --scale store=2
Since all services share the same MongoDB database, there is no need for data synchronization between services.