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

Framework Laravel Package

spiral/framework

Spiral is a high-performance, long-living full-stack PHP framework built on RoadRunner. It ships 60+ PSR-compatible components with resident-memory workers, native queue support, GRPC, WebSockets, and anti-memory-leak tools.

View on GitHub
Deep Wiki
Context7

Getting Started

Frame it correctly first. spiral/framework is not a Laravel package you composer require into an existing app — it is a competing full-stack framework with its own container, HTTP kernel, PSR-7/15 stack, ORM bridge, and queue/worker model. The realistic day-to-day use is: you are starting a new service (API, gRPC, queue consumer, CLI worker) and choosing Spiral instead of Laravel/Symfony. If you try to install it alongside Laravel you will fight duplicate PSR implementations and two containers.

Minimal path to a running app:

composer create-project spiral/app my-service
cd my-service
vendor/bin/rr get-binary   # fetch the RoadRunner application server
./rr serve                 # or: php app.php serve
php app.php                # lists console commands (no artisan here)

Use spiral/app (web/api/cli skeleton variants) rather than hand-assembling spiral/framework — the skeleton wires the Kernel, RoadRunner config (.rr.yaml), dotenv, and bootloader discovery for you.

Where to look first, in order:

  1. app/src/Kernel.php — extends Spiral\Framework\Kernel; this is where app bootloaders are declared (defineAppBootloaders()).
  2. app/src/Bootloader/ — your ServiceProvider equivalent. Everything (config, bindings, routes, middleware, commands) is registered from a bootloader.
  3. app/config/*.php — plain PHP arrays consumed via Spiral\Config\ConfigManager; env vars come in through the DotEnv bootloader and AppEnvironment enum.
  4. vendor/spiral/framework/src/ for a component you don't understand — the source is the real documentation for anything not covered on spiral.dev/docs.

First use case — ship one JSON endpoint end to end. This exercises the four things you'll do daily: route → filter (request validation) → injected service → response.

#[Route(uri: '/api/users', methods: ['POST'])]
final class CreateUserAction
{
    public function __invoke(CreateUserFilter $filter, UserService $users): array
    {
        return ['id' => $users->create($filter)->id];
    }
}

final class CreateUserFilter extends Filter
{
    #[NotBlank] public string $name = '';
    #[Email]    public string $email = '';
}

Register UserService in a bootloader, run php app.php route:list to confirm the route, and curl it. Once that round trip works, the rest of the framework's surface area is variations on the same theme.

Implementation Patterns

Map your Laravel reflexes onto Spiral's vocabulary before writing code:

Laravel Spiral
ServiceProvider Bootloader (defineBindings, defineSingletons, init, boot, start)
Facade / app() Constructor & method injection from the PSR-11 container
Artisan php app.php (Spiral\Console, #[AsCommand])
Eloquent Cycle ORM via spiral/cycle-bridge (data mapper, explicit mapping)
Blade Stempler or Twig bridge
php artisan make:* Scaffolder commands (create:controller, create:bootloader, …)
HTTP middleware PSR-15 middleware, registered per route group or globally
Horizon / queue workers RoadRunner workers + spiral/queue (AMQP, SQS, Beanstalk, Kafka)

Bootloader-centric composition. Bindings, config, routes, middlewares, and console commands all get declared in bootloaders rather than in a monolithic provider. Prefer defineSingletons() over the class constants when possible; use bootstrap/init for ordering-sensitive work. Since 3.10 you have BootloaderRegistryInterface when you need explicit ordering control instead of relying on discovery order.

Interceptors over base-controller inheritance. Since 3.14 the spiral/interceptors package replaces the deprecated spiral/hmvc. If you're following an older tutorial that has controllers extending CoreController for before/after hooks, translate that into a route interceptor — it composes better and works identically for HTTP, console, and queue targets.

Request-scoped values via method injection, not constructors. ServerRequestInterface, auth context, session, and input manager live in the http scope. Inject them into the controller action or middleware process() signature; injecting into a singleton's constructor is the number-one source of "works in dev, throws in prod" scope errors.

Queue-oriented design. Jobs are handlers with an attribute and a typed payload; dispatch by name/payload through QueueManagerInterface. Since 3.13 there's Spiral\Queue\TaskInterface / Task carrying the envelope, and RetryPolicyInterceptor (3.9) gives you configurable retries without hand-rolling a supervisor. Build queue consumers as separate RoadRunner workers in .rr.yaml — that's the framework's real performance story.

Cycle ORM discipline. It's a data mapper, not an Active Record. You define entities + mapping (#[Entity], #[Column], relations), generate migrations from the mapping diff, and drive persistence through EntityManagerInterface (persist / run / clean) with explicit load()/select() for relations. No lazy magic means fewer N+1 surprises and more upfront mapping work. Budget a real learning day here; it's the biggest delta from Eloquent.

Cross-cutting concerns. Telemetry (OpenTelemetry spans) and Monolog are first-class; DebugConfig (3.11) lets you register tags/collectors without touching the debug bootloader. MONOLOG_FORMAT configures log format via env. Treat observability as an install-time decision, not a retrofit.

Gotchas and Tips

  • Resident memory changes the rules. PHP code stays loaded across requests. Any mutable state on a singleton (caches keyed by request, static accumulators, "last user" fields) leaks between requests. Audit every singleton for per-request state before going to production; this is the single largest source of framework-transition bugs.
  • Container scopes are load-bearing. ServerRequestInterface only resolves inside the http scope (since 3.14.6 it's always a proxy there). Use method injection, or Spiral\Core\Scope (public since 3.15.3) for manual scope boundaries in workers and CLI. Introspector and proxy recursion have real failure modes — read the RecursiveProxyException message rather than guessing.
  • Turn on the stricter options now. In 3.15.0 the container gained allowSingletonsRebinding; setting it to false today avoids a migration later when the default flips. Likewise, SingletonInterface is deprecated in favor of #[Singleton] (3.12) and will be removed in v4 — don't write new code with the interface.
  • Spiral\Http\Pipeline is deprecated (3.15.0) in favor of LazyPipeline, which resolves middleware inside the correct scope. If middlewares behave differently from what you expect on older tutorials, this is why.
  • Keep the framework patched. The changelog is full of security-relevant fixes in exactly the components you'd hand-roll in Laravel: session ID validation and file-handler path containment (3.17.1), CSRF cookie Path attribute (3.17.0), auth config replacement (3.14.7), singleton rebinding in telemetry (3.15.8). Pin a minor and upgrade deliberately.
  • RoadRunner version drift is a real failure mode. rr binary, spiral/roadrunner-bridge, and the framework all move independently. Use rr get-binary per project and commit .rr.yaml; a mismatched server binary produces confusing boot errors rather than clean messages.
  • Debugging tooling is thinner than Laravel's. No Telescope, no dd/dump culture. Your loop is php app.php route:list / the scaffolder info command / Spiral\Debug collectors, plus reading vendor/spiral/framework/src and the container's resolving trace (improved in 3.15.6–3.15.7 — the traces are genuinely useful, so read them fully).
  • route:list crashed on LINK/UNLINK verbs until 3.17.0 — if you're on an older minor and your introspection commands misbehave, check the changelog before debugging your own routes.
  • Scaffolding writes real files. create:* commands generate controllers, bootloaders, middleware, and commands directly into app/src. Run them on a clean git working tree, and read the output — they encode the current idioms, which doubles as the fastest way to learn them.
  • Ecosystem risk to price in. 2k stars, single-vendor maintenance (Spiral Scout), and a small hiring pool relative to Laravel. The code quality is high (PHPStan/Psalm-level typing, PSR-compliant components, ten-plus years of production use), but your team's onboarding cost and the availability of Stack Overflow answers are materially worse. For a high-throughput, long-lived service where you control the team, that trade is often worth it; for a CRUD app with rotating contractors, it usually isn't.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource