PHPackages                             freddie/mercure-x - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. freddie/mercure-x

ActiveProject[HTTP &amp; Networking](/categories/http)

freddie/mercure-x
=================

A Mercure Hub PHP implementation.

0.4(2y ago)10139415[6 issues](https://github.com/bpolaszek/freddie/issues)[6 PRs](https://github.com/bpolaszek/freddie/pulls)GPL-3.0-onlyPHPPHP &gt;=8.1CI passing

Since Nov 29Pushed 2mo ago6 watchersCompare

[ Source](https://github.com/bpolaszek/freddie)[ Packagist](https://packagist.org/packages/freddie/mercure-x)[ RSS](/packages/freddie-mercure-x/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (7)Dependencies (28)Versions (15)Used By (0)

[![Application](https://github.com/bpolaszek/mercure-x/actions/workflows/app.yml/badge.svg)](https://github.com/bpolaszek/mercure-x/actions/workflows/app.yml)[![Coverage](https://camo.githubusercontent.com/879a8f4272acdae71e5e56c1e6206a403eca6ce0ba429784f474d1dc45bda42f/68747470733a2f2f636f6465636f762e696f2f67682f62706f6c61737a656b2f667265646469652f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d75423467524879533672)](https://codecov.io/gh/bpolaszek/freddie)

Freddie
=======

[](#freddie)

Freddie is a PHP implementation of the [Mercure Hub Specification](https://mercure.rocks/spec).

It is blazing fast, built on the shoulders of giants:

- [PHP](https://www.php.net/releases/8.1/en.php) 8.1
- [Framework X](https://framework-x.org/) and [ReactPHP](https://reactphp.org/)
- [Symfony](https://symfony.com/) 6
- [Redis](https://redis.io/) (optionally).

See what features are covered and what aren't (yet) [here](#feature-coverage).

Installation
------------

[](#installation)

PHP 8.1+ is required to run the hub.

### As a standalone Mercure hub

[](#as-a-standalone-mercure-hub)

```
composer create-project freddie/mercure-x freddie && cd freddie
bin/freddie
```

This will start a Freddie instance on `127.0.0.1:8080`, with anonymous subscriptions enabled.

You can publish updates to the hub by generating a valid JWT signed with the `!ChangeMe!` key with `HMAC SHA256` algorithm.

To change these values, see [Security](#security).

### As a bundle of your existing Symfony application

[](#as-a-bundle-of-your-existing-symfony-application)

```
composer req freddie/mercure-x
```

You can then start the hub by doing:

```
bin/console freddie:serve
```

You can override relevant env vars in your `.env.local`and services in your `config/services.yaml` as usual.

Then, you can inject `Freddie\Hub\HubInterface` in your services so that you can call `$hub->publish($update)`, or listening to dispatched updates in a CLI context 👍

Keep in mind this only works when using the Redis transport.

⚠️ **Freddie** uses its own routing/authentication system (because of async / event loop).

The controllers it exposes cannot be imported in your `routes.yaml`, and get out of your `security.yaml` scope.

Usage
-----

[](#usage)

```
./bin/freddie
```

It will start a new Mercure hub on `127.0.0.1:8080`. To change this address, use the `X_LISTEN` environment variable:

```
X_LISTEN="0.0.0.0:8000" ./bin/freddie
```

### Security

[](#security)

The default JWT key is `!ChangeMe!` with a `HS256` signature.

You can set different values by changing the environment variables (in `.env.local` or at the OS level): `X_LISTEN`, `JWT_SECRET_KEY`, `JWT_ALGORITHM`, `JWT_PUBLIC_KEY` and `JWT_PASSPHRASE` (when using RS512 or ECDSA)

Please refer to the [authorization](https://mercure.rocks/spec#authorization) section of the Mercure specification to authenticate as a publisher and/or a subscriber.

### PHP Transport (default)

[](#php-transport-default)

By default, the hub will run as a simple event-dispatcher, in a single PHP process.

It can fit common needs for a basic usage, but using this transport prevents scalability, as opening another process won't share the same event emitter.

It's still prefectly usable as soon as :

- You don't expect more than a few hundreds updates per second
- Your application is served from a single server.

### Redis transport

[](#redis-transport)

On the other hand, you can launch the hub on **multiple ports** and/or **multiple servers** with a Redis transport (as soon as they share the same Redis instance), and optionally use a load-balancer to distribute the traffic.

The [official open-source version](https://mercure.rocks/docs/hub/install) of the hub doesn't allow scaling because of concurrency restrictions on the *bolt* transport.

To launch the hub with the Redis transport, change the `TRANSPORT_DSN` environment variable:

```
TRANSPORT_DSN="redis://127.0.0.1:6379" ./bin/freddie
```

Optional parameters you can pass in the DSN's query string:

- `pingInterval` - regularly ping Redis connection, which will help detect outages (default `2.0`)
- `readTimeout` - max duration in seconds of a ping or publish request (default `0.0`: considered disabled)

*Alternatively, you can set this variable into `.env.local`.*

Advantages and limitations
--------------------------

[](#advantages-and-limitations)

This implementation does not provide SSL nor HTTP2 termination, so you'd better put a reverse proxy in front of it.

### Example Nginx configuration

[](#example-nginx-configuration)

```
upstream freddie {
    # Example with a single node
    server 127.0.0.1:8080;

    # Example with several nodes (they must share the same Redis instance)
    # 2 instances on 10.1.2.3
    server 10.1.2.3:8080;
    server 10.1.2.3:8081;

    # 2 instances on 10.1.2.4
    server 10.1.2.4:8080;
    server 10.1.2.4:8081;
}

server {

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com/example.com.cert;
    ssl_certificate_key /etc/ssl/certs/example.com/example.com.key;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

    location /.well-known/mercure {
        proxy_pass http://freddie;
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

### Example Caddy configuration

[](#example-caddy-configuration)

#### Single node

[](#single-node)

```
example.com

reverse_proxy 127.0.0.1:8080
```

#### With multiple nodes

[](#with-multiple-nodes)

```
example.com

reverse_proxy 10.1.2.3:8080 10.1.2.3:8081 10.1.2.4:8080 10.1.2.4:8081
```

### Payload limitations

[](#payload-limitations)

⚠ There's a known limit in [Framework-X](https://framework-x.org/docs/api/request/) which prevents request bodies to weigh more than [64 KB](https://github.com/reactphp/http/issues/412). At the time of writing, this limit cannot be raised due to Framework-X encapsulating HTTP Server instantiation.

Publishing bigger updates to Freddie (through HTTP, at least) could result in 400 errors.

Feature coverage
----------------

[](#feature-coverage)

FeatureCoveredJWT through `Authorization` header✅JWT through `mercureAuthorization` Cookie✅Allow anonymous subscribers✅Alternate topics✅️Private updates✅URI Templates for topics✅HMAC SHA256 JWT signatures✅RS512 JWT signatures✅Environment variables configuration✅Custom message IDs✅Last event ID (including `earliest`)✅️Customizable event type✅️Customizable `retry` directive✅️CORS❌ (configure them on your web server)Health check endpoint❌ (PR welcome)Logging❌ (PR welcome))️Metrics❌ (PR welcome)️Different JWTs for subscribers / publishers❌ (PR welcome)Subscription API❌️ (TODO)Tests
-----

[](#tests)

This project is 100% covered with [Pest](https://pestphp.com/) tests.

```
composer tests:run
```

Contribute
----------

[](#contribute)

If you want to improve this project, feel free to submit PRs:

- CI will yell if you don't follow [PSR-12 coding standards](https://www.php-fig.org/psr/psr-12/)
- In the case of a new feature, it must come along with tests
- [PHPStan](https://phpstan.org/) analysis must pass at level 8

You can run the following command before committing to ensure all CI requirements are successfully met:

```
composer ci:check
```

License
-------

[](#license)

GNU General Public License v3.0.

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance56

Moderate activity, may be stable

Popularity29

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 87.5% 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 ~117 days

Recently: every ~164 days

Total

7

Last Release

918d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/acdd1a8ee0e657ddd06cf11f98a32100ef7121afb8aa270a5b295f5c29c038b3?d=identicon)[bpolaszek](/maintainers/bpolaszek)

---

Top Contributors

[![bpolaszek](https://avatars.githubusercontent.com/u/5569077?v=4)](https://github.com/bpolaszek "bpolaszek (28 commits)")[![misaert](https://avatars.githubusercontent.com/u/12974251?v=4)](https://github.com/misaert "misaert (2 commits)")[![domino91](https://avatars.githubusercontent.com/u/5851173?v=4)](https://github.com/domino91 "domino91 (1 commits)")[![KouloukLeGrand](https://avatars.githubusercontent.com/u/33009422?v=4)](https://github.com/KouloukLeGrand "KouloukLeGrand (1 commits)")

---

Tags

hubmercurephpssehttpasyncreactphpssemercurepublishreactsubscribepubsubserver sent eventsframework x

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/freddie-mercure-x/health.svg)

```
[![Health](https://phpackages.com/badges/freddie-mercure-x/health.svg)](https://phpackages.com/packages/freddie-mercure-x)
```

###  Alternatives

[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M651](/packages/sylius-sylius)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[ec-cube/ec-cube

EC-CUBE EC open platform.

78527.0k1](/packages/ec-cube-ec-cube)[kadirov/api-starter-kit

443.9k](/packages/kadirov-api-starter-kit)

PHPackages © 2026

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