PHPackages                             easiviotech/fabriq - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. easiviotech/fabriq

ActiveProject

easiviotech/fabriq
==================

Fabriq — Unified Swoole-powered application platform. Serves HTTP APIs, WebSocket realtime, per-tenant frontend builds, background jobs, and event bus — with optional add-ons for live streaming and game server.

v1.2.2(2mo ago)07↓100%1MITPHPPHP &gt;=8.2CI passing

Since Feb 20Pushed 2mo agoCompare

[ Source](https://github.com/easiviotech/fabriq)[ Packagist](https://packagist.org/packages/easiviotech/fabriq)[ RSS](/packages/easiviotech-fabriq/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (6)Used By (1)

Fabriq
======

[](#fabriq)

> **Unified Swoole-powered application platform** — serves HTTP APIs, per-tenant frontend builds, WebSocket realtime, background jobs, and event bus with first-class multi-tenancy. Built-in CI/CD deploys any frontend framework (React, Vue, Svelte, Angular, etc.) from Git. Optional add-on packages for live streaming and game server.

**Brand:** Fabrq • **Runtime:** PHP 8.2+ / Swoole • **License:** Proprietary

---

Architecture
------------

[](#architecture)

Fabriq is a **long-running Swoole server** that hosts HTTP, frontend static files, WebSocket, queue processors, and event consumers in a single process. Every execution path enforces `TenantContext` — tenant isolation is guaranteed at the kernel level, including per-tenant frontend builds.

The platform serves both your **API** and your **frontend** from a single port — no Nginx or Apache required. Each tenant can have its own frontend build (React, Vue, Svelte, Angular, or any framework), cloned from Git and built automatically via CLI, API, or webhook.

Optional add-on packages extend the platform with **live streaming** (`fabriq/streaming`) and a **real-time game server** (`fabriq/gaming`) — install only what you need.

```
Client → HTTP/WS/UDP → Middleware Chain → Route Handler → DB/Redis (tenant-scoped)
                                        → Static File Handler → Per-tenant frontend (Swoole sendfile)
                                        → Push to WS rooms (Redis Pub/Sub)
                                        → Dispatch job (Redis Streams)
                                        → Emit event (Redis Streams)
                                        → Frontend Builder (git clone → npm build → deploy)
                                        → WebRTC signaling / HLS serving (fabriq/streaming)
                                        → Game room tick / state sync (fabriq/gaming)

```

### Core Packages

[](#core-packages)

These packages are always active and form the foundation of every Fabriq application:

PackagePathDescription**Kernel**`packages/kernel/`Swoole server bootstrap, Context (coroutine-local), Config, Container, Application, ServiceProvider**Tenancy**`packages/tenancy/`TenantResolver, TenantContext, TenantConfigCache**Storage**`packages/storage/`Connection pools (Channel-based), DbManager, TenantAwareRepository**HTTP**`packages/http/`Router, Request/Response wrappers, MiddlewareChain, Validator, StaticFileMiddleware, FrontendBuilder (CI/CD)**Realtime**`packages/realtime/`Gateway (fd mapping), Presence, PushService, RealtimeSubscriber**Queue**`packages/queue/`Dispatcher, Consumer (retry/DLQ), Scheduler, IdempotencyStore**Events**`packages/events/`EventBus, EventConsumer (dedupe), EventSchema**Security**`packages/security/`JwtAuthenticator, ApiKeyAuthenticator, PolicyEngine (RBAC+ABAC), RateLimiter**Observability**`packages/observability/`Logger (structured JSON), MetricsCollector (Prometheus), TraceContext**ORM**`packages/orm/`Active Record models, fluent QueryBuilder, stored procedures, schema migrations, tenant DB routing### Optional Add-on Packages

[](#optional-add-on-packages)

These packages are **disabled by default** and installed separately. Enable them only if your application needs streaming or gaming capabilities:

PackageInstallDescription**Streaming**`composer require fabriq/streaming`WebRTC signaling, FFmpeg transcoding (RTMP→HLS), viewer tracking, chat moderation**Gaming**`composer require fabriq/gaming`Game loop, matchmaking, lobbies, UDP protocol (MessagePack), delta state sync> See [Enabling Add-on Packages](#enabling-add-on-packages) for setup instructions.

### Application Structure

[](#application-structure)

DirectoryDescription`app/Http/Controllers/`HTTP request controllers`app/Providers/`Service providers (register + boot lifecycle)`app/Repositories/`Data access layer (replaces Eloquent in Swoole context)`app/Events/`Domain event classes`app/Listeners/`Event listener handlers`app/Jobs/`Queued job classes`app/Realtime/`WebSocket message handlers`app/Streaming/`Stream controllers and custom streaming logic`public/`Frontend build output, per-tenant subdirectories`public/_default/`Default frontend (login page, marketing site)`public/{tenant-slug}/`Tenant-specific frontend builds`storage/builds/`Build workspace (git clone + npm build temp files)`routes/api.php`HTTP API route definitions`routes/channels.php`WebSocket channel definitions`config/`Individual config files (app, server, database, redis, auth, static, streaming, gaming, etc.)`bootstrap/app.php`Application bootstrap (creates app, registers providers)### Config Files

[](#config-files)

FileDescription`config/app.php`Application name &amp; service providers list`config/server.php`Swoole host, port, workers, UDP settings`config/database.php`MySQL connection pools (platform + app)`config/redis.php`Redis connection settings`config/auth.php`JWT settings + RBAC role definitions`config/tenancy.php`Resolver chain + cache TTL`config/queue.php`Queue consumer group + retry policy`config/events.php`Event consumer group`config/observability.php`Log level`config/static.php`Frontend static file serving, SPA fallback, build automation`config/streaming.php`Live streaming — FFmpeg path, HLS settings, chat moderation`config/gaming.php`Game server — tick rates, matchmaking, UDP, reconnection---

Tech Stack
----------

[](#tech-stack)

ComponentVersionPHP≥ 8.2 (target 8.3)SwooleLatest stableMySQL8.0Redis7.xFFmpegLatest (for streaming transcoding)Docker Composev2---

Quick Start (Docker — Recommended)
----------------------------------

[](#quick-start-docker--recommended)

> **Note:** Swoole does not run natively on Windows. Docker is the recommended way to run Fabriq on all platforms.

### 1. Create a new project

[](#1-create-a-new-project)

**Linux / macOS:**

```
composer create-project easiviotech/fabriq-skeleton myapp
cd myapp
```

**Windows:**

```
composer create-project easiviotech/fabriq-skeleton myapp --ignore-platform-req=ext-swoole
cd myapp
```

> Swoole runs inside Docker — `--ignore-platform-req=ext-swoole` is safe and expected on Windows/macOS.
>
> Or clone directly: `git clone https://github.com/easiviotech/fabriq-skeleton myapp && cd myapp`

### 2. Start the full stack

[](#2-start-the-full-stack)

```
docker compose -f infra/docker-compose.yml up -d --build
```

Container names and ports are controlled by `infra/.env`:

```
# infra/.env — customise per project
COMPOSE_PROJECT_NAME=fabriq
APP_PORT=8000
MYSQL_PORT=3306
REDIS_PORT=6379
ADMINER_PORT=8080
```

This builds the app image (PHP 8.3 + Swoole + Redis extension) and starts **six containers**:

ContainerServiceURL / Port`{project}-app-1`Fabriq HTTP + WS server`{project}-processor-1`Queue/event processor*(background process)*`{project}-scheduler-1`Cron-like job scheduler*(background process)*`{project}-mysql-1`MySQL 8.0`localhost:3306``{project}-redis-1`Redis 7`localhost:6379``{project}-adminer-1`Adminer (DB GUI)> **Multiple projects:** To run multiple Fabriq-based projects side by side, give each a unique `COMPOSE_PROJECT_NAME` and different ports in `infra/.env`. Docker Compose auto-namespaces containers, volumes, and networks — no conflicts.

All application containers (app, processor, scheduler) start automatically. The processor and scheduler have `restart: unless-stopped` for crash recovery. Wait for MySQL to pass its health check (~15–30 seconds) before the services connect.

### 4. Verify the server is running

[](#4-verify-the-server-is-running)

```
curl http://localhost:8000/health
# {"status":"ok","service":"Fabriq","timestamp":...,"worker_id":0}
```

### 5. Access the database via Adminer

[](#5-access-the-database-via-adminer)

Open  and log in with:

FieldValueSystemMySQL / MariaDBServer`mysql`Username`fabriq`Password`sfpass`Database`sf_platform` or `sf_app`### 6. View logs

[](#6-view-logs)

```
# All containers
docker compose -f infra/docker-compose.yml logs -f

# Individual services
docker compose -f infra/docker-compose.yml logs -f app
docker compose -f infra/docker-compose.yml logs -f processor
docker compose -f infra/docker-compose.yml logs -f scheduler
```

### 7. Create a tenant

[](#7-create-a-tenant)

```
curl -X POST http://localhost:8000/api/tenants \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme","slug":"acme"}'
```

### Stopping the stack

[](#stopping-the-stack)

```
docker compose -f infra/docker-compose.yml down

# To also remove all data volumes (full reset):
docker compose -f infra/docker-compose.yml down -v
```

---

Quick Start (Local — Linux / macOS only)
----------------------------------------

[](#quick-start-local--linux--macos-only)

> Requires PHP 8.2+, Swoole extension, MySQL 8.0+, and Redis 7.x installed locally.

```
composer install

# Start MySQL and Redis (or use Docker for just the infrastructure):
docker compose -f infra/docker-compose.yml up -d mysql redis

# Start the HTTP + WebSocket server
php bin/fabriq serve

# In another terminal — start the queue processor
php bin/fabriq processor

# In another terminal — start the scheduler (optional)
php bin/fabriq scheduler
```

### Health check

[](#health-check)

```
curl http://localhost:8000/health
# {"status":"ok","timestamp":...,"worker_id":0}
```

---

CLI Commands
------------

[](#cli-commands)

CommandDescription`bin/fabriq serve`Start HTTP + WS + UDP server (with streaming &amp; gaming if enabled)`bin/fabriq processor`Start queue/event processor`bin/fabriq scheduler`Start job scheduler`bin/fabriq frontend:build `Build &amp; deploy a tenant's frontend from their Git repo`bin/fabriq frontend:status `Show frontend deployment status for a tenant---

Key Features
------------

[](#key-features)

### Frontend Serving &amp; Build Automation *(built-in)*

[](#frontend-serving--build-automation-built-in)

Fabriq serves per-tenant frontend builds directly through Swoole — no Nginx or Apache required. Use any frontend framework (React, Vue, Svelte, Angular, Next.js, etc.) and Fabriq handles the rest.

**Why serve frontends through Fabriq instead of Nginx, Vercel, or a CDN?**

Traditional SetupWith FabriqNginx + PHP-FPM + CDN + separate CI/CDSingle Swoole process serves API + frontendSeparate Nginx config per tenantTenants resolved automatically — zero server configCORS headers, preflight requests, proxy hopsSame origin — no CORS, no extra round tripsManage DNS + TLS + CDN per custom domainCustom domains resolved via config or DBDeploy frontend and API independentlyFrontend and API ship together, atomic per-tenant deploysNo tenant awareness in the web serverSame tenant resolution shared between API and frontend**Features:**

- **Per-tenant builds** — Each tenant gets their own frontend at `public/{tenant-slug}/`, resolved automatically from subdomain, header, JWT, or custom domain
- **High performance** — Swoole's `sendfile()` delivers files via zero-copy kernel transfer, no PHP memory allocation
- **SPA fallback** — Client-side routing works out of the box (`index.html` served for unmatched paths)
- **Smart caching** — Fingerprinted assets get immutable/1-year cache; HTML gets no-cache (CDN-ready)
- **Custom domains** — 3-tier resolution: static `domain_map` (O(1)), TenantResolver, DB lookup — add a domain by adding a DB row, no server restart
- **Built-in CI/CD** — Clone a tenant's Git repo, run `npm build`, deploy atomically with zero downtime
- **Three trigger methods** — CLI (`frontend:build`), API (`POST /api/tenants/{id}/frontend/deploy`), webhook (GitHub/GitLab push)
- **Atomic deployments** — Old build is swapped out atomically; users never see a half-built state
- **Framework agnostic** — Tenant A on React, tenant B on Vue, tenant C on plain HTML — all served from the same process
- **Fallback directory** — `public/_default/` serves as the shared frontend (login, marketing) when a tenant has no custom build

> See [FRONTEND.md](docs/FRONTEND.md) for the full guide.

### `fabriq/streaming` — Live Streaming *(add-on package)*

[](#fabriqstreaming--live-streaming-add-on-package)

> Install: `composer require fabriq/streaming` — [View on Packagist](https://packagist.org/packages/fabriq/streaming)

- **WebRTC signaling** — SDP offer/answer and ICE candidate exchange over WebSocket
- **FFmpeg transcoding** — RTMP → HLS with configurable segment duration and playlist size
- **Viewer tracking** — Redis-backed concurrent viewer counting with heartbeats
- **Chat moderation** — Slow mode, word filters, per-stream ban lists
- **CDN-ready** — HLS segments served with appropriate `Cache-Control` headers

### `fabriq/gaming` — Game Server *(add-on package)*

[](#fabriqgaming--game-server-add-on-package)

> Install: `composer require fabriq/gaming` — [View on Packagist](https://packagist.org/packages/fabriq/gaming)

- **Fixed tick-rate game loop** — 10 Hz (casual), 30 Hz (realtime), 60 Hz (competitive) via `Swoole\Timer`
- **UDP protocol** — Low-latency binary communication using MessagePack
- **Matchmaking** — Redis ZSET-based skill ranking with expanding search range
- **Pre-game lobbies** — Ready checks, countdowns, auto-start
- **Player reconnection** — Configurable grace period preserving session and room state
- **Delta state sync** — Only changed state is sent to each player

---

Prometheus Metrics
------------------

[](#prometheus-metrics)

Exposed at `GET /metrics`. Core metrics are always available; add-on metrics appear when the package is enabled.

**Core metrics:**

MetricTypeDescription`http_requests_total`counterTotal HTTP requests`http_latency_ms`histogramRequest latency`ws_connections`gaugeActive WebSocket connections`queue_processed_total`counterJobs processed**Streaming metrics** *(when `fabriq/streaming` is enabled):*

MetricTypeDescription`streams_active`gaugeCurrently live streams`stream_viewers_current`gaugeTotal concurrent viewers`stream_transcodes_active`gaugeActive FFmpeg processes**Gaming metrics** *(when `fabriq/gaming` is enabled):*

MetricTypeDescription`game_rooms_active`gaugeActive game rooms`game_players_connected`gaugeConnected game players`game_tick_latency_ms`histogramGame loop tick timing`udp_packets_total`counterUDP packets processed`matchmaking_queue_size`gaugePlayers waiting for match---

Testing
-------

[](#testing)

```
# Run all unit tests (inside Docker)
docker compose -f infra/docker-compose.yml exec app vendor/bin/phpunit

# Specific test
docker compose -f infra/docker-compose.yml exec app vendor/bin/phpunit tests/Unit/Kernel/ContextTest.php

# Or if you have PHP + Swoole locally:
vendor/bin/phpunit
```

---

Documentation
-------------

[](#documentation)

DocDescription[DEVELOPERS\_GUIDE.md](docs/DEVELOPERS_GUIDE.md)Comprehensive developer guide covering all subsystems[ARCHITECTURE.md](docs/ARCHITECTURE.md)System overview with component diagrams[FRONTEND.md](docs/FRONTEND.md)Frontend serving, per-tenant builds, CI/CD pipeline[TENANCY.md](docs/TENANCY.md)Tenant resolution, enforcement, config caching[DATABASE.md](docs/DATABASE.md)Connection pooling, transactions, tenancy strategy[REALTIME\_FABRIC.md](docs/REALTIME_FABRIC.md)WS gateway, push API, cross-worker routing[IDEMPOTENCY.md](docs/IDEMPOTENCY.md)Idempotency keys, dedupe, storage layers[SECURITY.md](docs/SECURITY.md)JWT/API key auth, RBAC/ABAC policy engine[OPERATIONS.md](docs/OPERATIONS.md)Health, metrics, logging, tracing[DEPLOYMENT.md](docs/DEPLOYMENT.md)Production deployment guide (Docker, K8s, cloud, TLS)### Docs Site

[](#docs-site)

The `docs-site/` directory contains a full HTML documentation site with syntax-highlighted code examples, search, and navigation:

PageTopic`index.html`Getting Started (prerequisites, installation, project structure)`architecture.html`Architecture (component diagram, bootstrap lifecycle, key classes)`configuration.html`Configuration (all config files, dot-notation access, service providers)`comparison.html`Why Fabriq? (feature comparison matrix vs Hyperf, Octane, MixPHP)`http.html`HTTP Routing (routes, middleware, validation)`tenancy.html`Multi-Tenancy (resolution chain, enforcement)`security.html`Security (JWT, API keys, RBAC+ABAC, rate limiting)`database.html`Database (pools, DbManager, transactions, repositories)`realtime.html`Real-Time (WebSocket auth, push API, presence)`async.html`Async Processing (jobs, events, scheduling, idempotency)`streaming.html`Live Streaming (WebRTC, HLS, transcoding, chat moderation)`gaming.html`Game Server (tick loop, matchmaking, lobbies, state sync)`operations.html`Operations (logging, metrics, testing, deployment)`deployment.html`Production Deployment (Docker, Kubernetes, cloud, TLS, checklist)---

Packagist Packages
------------------

[](#packagist-packages)

Fabriq's packages are published individually on [Packagist](https://packagist.org). The **core packages** power every Fabriq application. The **add-on packages** are optional and installed only when needed.

### Core Packages

[](#core-packages-1)

PackagePackagistDescription[`fabriq/kernel`](https://packagist.org/packages/fabriq/kernel)[![Latest Version](https://camo.githubusercontent.com/5bc5f991f20c36b1bfdd6ca7f10f55b39102f2778dc5b79481512929241b1614/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f6b65726e656c)](https://packagist.org/packages/fabriq/kernel)Core container, config, context, server, service providers[`fabriq/storage`](https://packagist.org/packages/fabriq/storage)[![Latest Version](https://camo.githubusercontent.com/b6180d5b355b81fb68f47155cbf5f853a959faa6445d386c2e368b361fef8467/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f73746f72616765)](https://packagist.org/packages/fabriq/storage)Connection pools, DbManager, tenant-aware repositories[`fabriq/observability`](https://packagist.org/packages/fabriq/observability)[![Latest Version](https://camo.githubusercontent.com/08a7bfa59932f34b3de12d6cf9da0b92f1fc14e3172833d3557bb159dff726d2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f6f62736572766162696c697479)](https://packagist.org/packages/fabriq/observability)Structured logging, metrics, tracing[`fabriq/tenancy`](https://packagist.org/packages/fabriq/tenancy)[![Latest Version](https://camo.githubusercontent.com/f9e3e4761087e868d646d2a38d7418ae4f3acb0d7157e0322c345eac4aa342e8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f74656e616e6379)](https://packagist.org/packages/fabriq/tenancy)Multi-tenant context, resolution, config caching### Add-on Packages

[](#add-on-packages)

PackagePackagistDescription[`fabriq/streaming`](https://packagist.org/packages/fabriq/streaming)[![Latest Version](https://camo.githubusercontent.com/76bcc9df73aec1fd1d95a316a5c689f1938f7cb33cfaec3c1d14108635119d43/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f73747265616d696e67)](https://packagist.org/packages/fabriq/streaming)WebRTC signaling, HLS transcoding, viewer tracking, chat[`fabriq/gaming`](https://packagist.org/packages/fabriq/gaming)[![Latest Version](https://camo.githubusercontent.com/af5e91d63bfcc9dc1530982aeb015f1ac5d50b47ab8b93f5dd9e46f3ad5d6185/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6661627269712f67616d696e67)](https://packagist.org/packages/fabriq/gaming)Game loop, matchmaking, lobbies, UDP protocol, state sync### Enabling Add-on Packages

[](#enabling-add-on-packages)

**`fabriq/streaming`:**

```
composer require fabriq/streaming
```

Then in your project:

1. Set `STREAMING_ENABLED=1` environment variable (or `'enabled' => true` in `config/streaming.php`)
2. Uncomment `\App\Providers\StreamingServiceProvider::class` in `config/app.php`

**`fabriq/gaming`:**

```
composer require fabriq/gaming
```

Then in your project:

1. Set `GAMING_ENABLED=1` environment variable (or `'enabled' => true` in `config/gaming.php`)
2. Uncomment `\App\Providers\GamingServiceProvider::class` in `config/app.php`

### Dependency Graph

[](#dependency-graph)

```
fabriq/streaming ──→ fabriq/kernel
                 ──→ fabriq/storage ──→ fabriq/kernel
                 ──→ fabriq/observability ──→ fabriq/kernel

fabriq/gaming ──→ fabriq/kernel
              ──→ fabriq/storage
              ──→ fabriq/observability
              ──→ rybakit/msgpack

fabriq/tenancy ──→ fabriq/kernel (optional, suggested by kernel)

```

When you `composer require fabriq/streaming`, Composer automatically pulls in `fabriq/kernel`, `fabriq/storage`, and `fabriq/observability`.

---

Safety Rules
------------

[](#safety-rules)

- All connections use per-worker pools (never global/shared)
- Context is reset per request/message/job (no state leakage)
- All DB queries enforce `tenant_id` via repository base class
- No pool-per-tenant (prevents connection explosion)
- Borrow → use → release in same coroutine (no stored connections)
- Streaming and gaming services are tenant-scoped — no cross-tenant data leakage
- Game state is per-worker; cross-worker coordination uses Redis
- FFmpeg child processes are tracked and cleaned up on stream end

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance94

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

5

Last Release

64d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/0cce56237b90dc59b214f88af2b3fa9c38d50509bb56f1d0d5ecff6af94053b8?d=identicon)[nikcoder2018](/maintainers/nikcoder2018)

---

Top Contributors

[![nikcoder2018](https://avatars.githubusercontent.com/u/18230102?v=4)](https://github.com/nikcoder2018 "nikcoder2018 (28 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/easiviotech-fabriq/health.svg)

```
[![Health](https://phpackages.com/badges/easiviotech-fabriq/health.svg)](https://phpackages.com/packages/easiviotech-fabriq)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
