Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Reactor Laravel Package

windwalker/reactor

Reactor is a Windwalker PHP package for building event-driven applications, offering a lightweight reactive layer to wire up listeners, values, and state changes so components respond to updates without boilerplate or tight coupling.

View on GitHub
Deep Wiki
Context7

Getting Started

windwalker/reactor sits in the Windwalker ecosystem as the request-handling core: a PSR-15 middleware pipeline wired to a PSR-11 container and PSR-7 HTTP messages. If you're coming from Laravel, think of it as the equivalent of Illuminate\Foundation\Http\Kernel + the middleware stack + the container bindings that make routing and controllers resolvable — but with none of the facades, helpers, or Artisan scaffolding.

Minimal setup:

composer require windwalker/reactor

You'll need PSR-7/PSR-17 implementations alongside it (Windwalker ships windwalker/http and windwalker/http-client; nyholm/psr7 or guzzlehttp/psr7 also work). Look first at:

  1. Windwalker\Reactor\ — the reactor/kernel class and how a request is dispatched through middleware.
  2. Any *Application or *Kernel subclass in the repo — this is the extension point you'll subclass for a web app vs. console app.
  3. The composer.json require block — it tells you exactly which Windwalker components (windwalker/di, windwalker/router, windwalker/middleware, windwalker/event) the reactor expects to be present, which is your checklist for wiring.

First use case: stand up a single JSON endpoint. Construct a PSR-7 request (or pull from $_SERVER via ServerRequestFactory), push it through the reactor, and return the PSR-7 response — echo the body. Once that round-trips, add routing middleware.

Because the package has essentially zero public adoption (0 stars, 0 dependents), treat the source as the documentation. Read src/ before trusting any blog post — there are none.

Implementation Patterns

Concept mapping from Laravel. Keep this table nearby; it's the fastest way to orient:

Laravel Reactor equivalent
HTTP Kernel / handle() Reactor handle() dispatching through middleware
$middleware array Explicit PSR-15 middleware added to the pipeline
Service Providers Container set()/bind() calls during bootstrap
Facades Constructor injection — no static resolvers
Route::get() windwalker/router routes registered as middleware or handler
Events/Listeners windwalker/event dispatcher fed by the reactor

Pipeline as the primary integration surface. Add cross-cutting behavior (auth, CORS, JSON error shaping, request logging) as PSR-15 middleware rather than controller concerns. Middleware is the only place where the Laravel dev's instincts transfer cleanly; lean on it.

Bootstrap in one place. Write a single bootstrap.php that: creates the container, registers bindings (PSR-17 factories, router, event dispatcher, config), constructs the reactor, and appends middleware in order. Keep the reactor instance reusable — construct once, dispatch many times in tests.

Testing pattern. This is where the reactor shines over Laravel's kernel. Because it takes a PSR-7 request and returns a PSR-7 response with no globals, your integration tests are:

$response = $reactor->handle($request);
$this->assertSame(200, $response->getStatusCode());

No $this->get(), no application bootstrapping between tests if you reuse the reactor. Build a TestCase base that yields a fresh reactor per test.

Routing as middleware. Register windwalker/router as a middleware that resolves the request to a handler and stores it in a request attribute; a terminal middleware invokes it. This keeps routing swappable and testable in isolation.

Controller resolution. Controllers shouldn't be new'd inline — resolve them through the container so their dependencies come in. This is your equivalent of Laravel's automatic controller resolution; it just isn't magic, you write the $container->get($class) call.

Gotchas and Tips

No framework autoloading of providers or middleware. Laravel's bootstrap/app.php and config/app.php don't exist here. Every middleware, binding, and route is registered by your own bootstrap code. Missing middleware ordering bugs and "class not found" during container resolution are almost always a missing manual registration.

Middleware order is LIFO for response, FIFO for request. The first middleware you add sees the request first and the response last. Error-handling middleware must be added first; auth after it. This trips up Laravel devs used to $middlewarePriority doing some of this for you.

Container is PSR-11, not Laravel's container. No app(), no resolve(), no contextual binding, no #[Inject] attribute magic. If you need auto-wiring of constructor dependencies, you implement a reflection-based resolver or pull in windwalker/di's resolver explicitly. Don't assume $container->get(Foo::class) will construct Foo — verify.

No request/response helpers. You're working with PSR-7 immutables. $request->withAttribute(...) returns a new request; middleware must pass the new instance down the chain. Forgetting the reassignment is the single most common silent bug — data "disappears" between middleware.

Config is whatever you make it. There's no config repository, no .env loader, no config caching. Load config yourself (e.g., vlucas/phpdotenv + an array) and bind it into the container as a plain object or array.

Debugging. No Telescope, no debug toolbar. Use xdebug + a Psr\Log\LoggerInterface bound into the container and a logging middleware. When a middleware chain misbehaves, temporarily append a middleware that returns a diagnostic response early — faster than guessing.

Extension points to know. The reactor is designed to be subclassed. Override the container factory or the middleware-stack assembly method rather than monkey-patching. Check whether the class exposes getContainer()/setContainer() — you'll want it for tests.

Version risk. With zero stars and no dependents, expect breaking changes between minor versions and sparse changelogs. Pin exact versions in composer.json and read the diff on every composer update. If this is going into anything production, wrap it behind your own thin App facade so a future swap (to windwalker/application, Slim, or a Laravel zero-config kernel) is a single-file change.

Where it beats Laravel for day-to-day: PSR compliance makes it trivial to swap a router, a logger, or a PSR-7 implementation without touching app code. If your team already runs PSR-15 middleware elsewhere (Mezzio, Slim, Laminas), you can share middleware packages directly — that portability is the real argument for the reactor over the full Laravel kernel.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core