The Enterprise SaaS Framework Kernel — Production-grade multi-tenancy, events, jobs, and observability for building SaaS products.
efncore is a production-grade framework for building multi-tenant SaaS products. Like WordPress for enterprise SaaS, it provides:
- 🏗️ Domain-Driven Design architecture that scales with your team
- 🏢 Built-in multi-tenancy with tenant isolation at all layers
- ⚡ Event-driven architecture with transactional outbox
- 🔄 Background jobs with retry logic and scheduling
- 📊 OpenTelemetry observability from day one
- 🔌 Module system for extensible features
- 🎨 Frontend shell included (Next.js 16)
For SaaS Founders: Ship months faster with production-grade patterns. For Developers: FastAPI + Next.js with TypeScript everywhere. For AI Agents: CLAUDE.md with explicit architecture documentation.
Get efncore running locally with Docker Compose.
- Docker & Docker Compose
- Git
git clone https://github.com/anthonykewl20/efncore.git
cd efncore
docker compose up -d| Service | URL | Credentials |
|---|---|---|
| Frontend | http://localhost:3001 | - |
| Backend API | http://localhost:8001 | - |
| API Docs | http://localhost:8001/docs | - |
| Debug Context | http://localhost:8001/debug/context | - |
| Keycloak | http://localhost:8080 | admin/admin |
# Check health status
curl http://localhost:8001/health
# Check request context (tenant isolation)
curl -H "X-Tenant-Id: 123e4567-e89b-12d3-a456-426614174000" \
http://localhost:8001/debug/context| Challenge | efncore Solution |
|---|---|
| Building multi-tenancy from scratch | Tenant isolation built-in (DB, cache, events) |
| Handling background jobs reliably | Transactional outbox + RabbitMQ workers |
| Scaling read load | Automatic replica routing (ADR-014) |
| Observability after the fact | OpenTelemetry tracing from day one |
| Hiring developers | Standard DDD patterns, clear documentation |
# Tenant-scoped requests (automatic)
from efncore.kernel.request_context import RequestContextDep
@router.get("/users")
async def list_users(ctx: RequestContextDep):
# ctx.tenant_id automatically filters queries
users = await user_service.list(ctx.tenant_id)
return users# Read from replicas automatically
# Write to primary explicitly
async with get_db_session(prefer_replica=True) as session:
user = await session.get(User, id) # Routes to replica
async with get_write_db_session() as session:
session.add(new_user) # Always goes to primary
await session.commit()efncore includes CLAUDE.md — explicit architecture documentation for AI assistants:
- File placement rules (non-negotiable)
- API patterns and conventions
- Testing workflows and patterns
- Configuration system reference
- Tenant isolation at database, cache, and event layers
- Request context middleware automatically scopes all operations
- Tenant-scoped Redis keys prevent data leakage
- Row-level security with tenant governance
- Tenant onboarding flows built-in
- Transactional outbox pattern prevents event loss
- RabbitMQ integration with at-least-once delivery
- Event handlers with idempotency and replay
- Dead-letter queues for failed events
- Module-to-core communication via events
- Arq-based job queue with Redis backend
- Retry logic with exponential backoff
- Scheduled jobs and cron-like workflows
- Tenant-isolated job execution
- Job observability with tracing
- OpenTelemetry tracing (OTLP) with W3C trace context
- Structured logging with tenant/user context
- Performance guardrails (query timeouts, backpressure)
- Slow query logging with automatic detection
- Health checks for all dependencies
- Dynamic module loading from directory
- Strict contracts (HTTP APIs + domain events)
- Module governance (allowlist, version checks)
- UI extension points for frontend modules
- Kill switch for emergency disabling
- OIDC authentication (Keycloak integration)
- Role-based access control (RBAC)
- Audit logging for compliance (SOC 2, HIPAA)
- PII redaction in logs and events
- Rate limiting and load shedding
efncore follows Domain-Driven Design (DDD) with bounded contexts:
graph TB
subgraph "Frontend (Next.js)"
A[app/] --> B[core/templates/]
A --> C[modules/]
A --> D[platform/]
end
subgraph "Backend (FastAPI)"
E[app/main.py] --> F[core/contexts/]
E --> G[modules/]
E --> H[efncore/kernel/]
end
subgraph "Kernel Services"
H --> I[request_context/]
H --> J[data/]
H --> K[eventing/]
H --> L[jobs/]
H --> M[cache/]
end
A -->|HTTP/REST| E
K -->|RabbitMQ| N[Workers]
J -->|PostgreSQL| O[(Primary)]
J -->|Read Replicas| O
M -->|Redis| P[(Cache)]
efncore/
├── backend/ # FastAPI application
│ ├── src/
│ │ ├── app/ # Composition root
│ │ ├── core/ # Non-removable bounded contexts
│ │ │ ├── tenancy/ # Tenant lifecycle
│ │ │ ├── iam/ # Users, auth, RBAC
│ │ │ ├── audit/ # Audit logging
│ │ │ └── billing/ # Subscriptions, entitlements
│ │ ├── modules/ # Installable features
│ │ └── efncore/ # Platform kernel
│ │ ├── kernel/
│ │ │ ├── request_context/ # Tenant/user metadata
│ │ │ ├── data/ # Read/write splitting
│ │ │ ├── eventing/ # Outbox, events
│ │ │ ├── jobs/ # Background jobs
│ │ │ └── cache/ # Redis caching
│ │ ├── http/ # Middleware, errors
│ │ └── config/ # Centralized settings
│ ├── tests/ # Unit, integration, E2E
│ └── worker/ # Background job worker
│
├── frontend/ # Next.js application
│ ├── src/
│ │ ├── app/ # App Router
│ │ ├── core/ # Shell/core UI
│ │ ├── modules/ # Module UI
│ │ └── platform/ # Theme, UI kit
│ └── e2e/ # Playwright E2E tests
│
├── docs/ # Architecture & dev docs
│ ├── architecture/ # ADRs, system context
│ ├── development/ # Roadmap, workstreams
│ └── dev-docs/ # Developer guides
│
└── CLAUDE.md # AI agent documentation
Key Principles:
- 📁 No
utils/,common/, orshared/directories - 🚫 No business logic in HTTP routers
- 🔒 All requests tenant-scoped
- 📡 Modules communicate via HTTP APIs or events
| Guide | Description |
|---|---|
| Quick Start | Get running in 5 minutes |
| Configuration Guide | All 100+ environment variables |
| Debugging Guide | Troubleshooting common issues |
| Request Context | Tenant/user propagation |
| Document | Description |
|---|---|
| System Context | C4 system-level architecture |
| ADR Index | Architecture decision records |
| Deployment | Production deployment guide |
| Performance | Scaling and optimization |
| Document | Description |
|---|---|
| File Governance | Where code belongs (NON-NEGOTIABLE) |
| Module Development | Building modules |
| Eventing Guide | Event handlers and outbox |
| Jobs Guide | Background job patterns |
efncore uses Shin et al methodologies (mutation testing, sad path first):
# Backend tests
cd backend
pytest # All tests
pytest -m unit # Unit tests only
pytest -m integration # Integration tests (requires DB)
pytest -m smoke # Health checks against running services
# Frontend tests
cd frontend
npm test # Unit tests (Vitest)
npm run test:e2e # E2E tests (Playwright)
npm run test:coverage # With coverageTest Philosophy:
- ✅ Sad path before happy path
- ✅ Tenant isolation tests
- ✅ Mutation testing for critical modules
- ✅ Cross-module integration tests
docker compose up -dSee Deployment Guide for:
- Kubernetes manifests
- Environment variable reference
- Database migrations
- PgBouncer for read replicas
- OpenTelemetry collector setup
Current Deployment: Single VPS with Dokploy (Phase 0) Migration Path: VPS → Split DB → Multi-region (same codebase)
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
Areas for Contribution:
- 🐛 Bug fixes
- 🔌 New modules
- 📖 Documentation improvements
- ✅ Test coverage
- ⚡ Performance optimizations
Good First Issues: GitHub Issues
- GitHub Discussions: Ask questions
- Issues: Bug reports & feature requests
- Documentation: CLAUDE.md for AI agent contributors
| Phase | Status | Description |
|---|---|---|
| Phase 0 | ✅ Complete | Single VPS deployment (cost optimization) |
| Phase 1 | ✅ Complete | Core multi-tenancy + read replicas |
| Phase 2 | 🚧 In Progress | Module marketplace + governance UI |
| Phase 3 | 📋 Planned | AI agent SDK for module development |
| Phase 4 | 📋 Planned | Multi-region high availability |
efncore is built for scale:
- Throughput: 10,000+ req/sec per instance
- Database: Read replicas with automatic routing
- Caching: Tenant-scoped Redis with TTL governance
- Backpressure: Load shedding when overloaded
- Query Timeouts: 50% of request timeout threshold
- Slow Queries: Auto-logged when exceeding 1 second
Backend:
- FastAPI 0.124.4 — Web framework
- Python 3.12 — Runtime
- PostgreSQL 18.1 — Primary database
- Redis 7 — Caching & sessions
- RabbitMQ 4.1 — Message broker
- Alembic 1.17.2 — Migrations
Frontend:
- Next.js 16.0.10 — React framework
- TypeScript — Type safety
- Tailwind CSS 4.1.18 — Styling
- Radix UI — Component primitives
- Playwright — E2E testing
Observability:
- OpenTelemetry — Tracing & metrics
- SigNoz — APM backend
RANEX FRAMEWORKS SOURCE-AVAILABLE EVALUATION LICENSE (RSEL) v1.0
See LICENSE for details.
efncore stands on the shoulders of giants:
- WordPress — Plugin architecture inspiration
- Stripe — API design patterns
- Shopify — Multi-tenancy patterns
- FastAPI — Backend framework
- Next.js — Frontend framework
If you use efncore in your research or production, please cite:
@software{efncore,
title = {efncore: Enterprise SaaS Framework Kernel},
author = {Anthony Kewl},
year = {2024},
url = {https://github.com/anthonykewl20/efncore}
}⭐ Star us on GitHub — it helps more people discover efncore!