wayofdev/laravel-cycle-orm-adapter
Integrates Cycle ORM into Laravel applications. Provides package configuration, service provider bindings, and a bridge between Cycle's data-mapper ORM and Laravel's container and ecosystem, letting you use Cycle entities alongside familiar Laravel tooling.
Architecture fit. This package is a thin Laravel service-provider bridge over Cycle ORM 2.x, not an ORM in its own right. Its value proposition is architectural: it lets a Laravel application adopt a DataMapper + Unit of Work persistence model with a domain layer that is deliberately decoupled from the framework. That is a genuinely different architecture from Eloquent's ActiveRecord, and the decision to adopt it is a decision to run two persistence paradigms side by side — Eloquent for the Laravel ecosystem surface (Sanctum, Cashier, Telescope, Horizon, notifications, third-party packages) and Cycle for the domain core. The adapter does not and cannot consolidate that; it enables a bifurcation. Fit is therefore only strong in one scenario: a greenfield, DDD-first bounded context with a team that already understands identity maps, mapping schemas, and explicit transaction boundaries. For a typical CRUD-heavy Laravel product it is negative-value complexity.
Integration feasibility. Mechanically easy — Composer install, publish config, register mapping paths, define entities with attributes or schema files. The real effort is authoring mapping metadata and repository ports, which is not a one-afternoon task per aggregate. Note the compatibility matrix shows the package tracks Laravel majors aggressively: 6.0.0 requires PHP 8.3 and adds Laravel 13, so the PHP floor moved within a major-ish release window. Any org pinned to PHP 8.2 is frozen on the 5.x line, which in turn caps Laravel 12 support.
Technical risk. High, but concentrated rather than diffuse:
Key questions. (1) Is DDD purity a funded requirement, or an aspiration? (2) Can we run PHP 8.3+ across all environments now? (3) Who owns the entity/mapping layer long-term, and is that a named person or a team? (4) Which bounded context is small enough to pilot without touching auth or billing? (5) Are we prepared to maintain our own fork or pin if the maintainer stops releasing? (6) How will Cycle-originated queries be observed in production?
Stack fit. Compatible across Laravel 10.28 through 13 and PHP 8.2/8.3 depending on adapter line, with Cycle ORM 2.x throughout. The adapter is framework-native (service provider + facade-style bindings), so it slots in without altering Laravel bootstrap. It fits alongside Eloquent rather than replacing it, which is the correct framing for planning: treat it as an additional persistence engine for one context.
Migration path. There is no automated Eloquent→Cycle migration, and none should be expected. The realistic path is a strangler pattern at the bounded-context seam: introduce Cycle for a new or newly carved-out context, expose it to the rest of the app through repository interfaces owned by the domain, and keep Eloquent behind those interfaces for everything not yet moved. Existing database data needs no migration — only code. Retrofit of existing Eloquent models into Cycle entities should be explicitly out of scope for the first year.
Compatibility. Two axes to watch: the Laravel/PHP matrix, and Cycle ORM 2.x minor releases, which the adapter consumes. Because the adapter's majors are tied to Laravel majors, a platform upgrade forces an adapter major upgrade, which can carry breaking changes and a PHP floor bump. Budget a dedicated upgrade workstream each Laravel cycle rather than assuming routine dependency bumps.
Sequencing. (1) Confirm PHP 8.3+ availability and pin the adapter/Cycle versions. (2) Choose one bounded context with no cross-ORM transactional needs. (3) Define mapping schema conventions and a repository port layer before writing entities. (4) Stand up test helpers and a seeding strategy early — the package ships a seed() helper, so validate it against your fixtures. (5) Wire observability for Cycle queries. (6) Only after a full production cycle on the pilot, evaluate a second context.
Maintenance. The package itself is small and low-churn; the maintenance load lives in your own mapping metadata, which is hand-authored and must be kept in lockstep with schema changes. Expect ongoing cost from maintaining two persistence idioms in one codebase — code review needs reviewers fluent in both. Upstream cadence is healthy (release-please, conventional commits, changelogs, mutation testing), but the maintainer is a single point of failure; keep a fork-ready posture and avoid deep coupling to internals.
Support. Community support is effectively absent at this adoption level — no dependents, minimal issue traffic, a Discord that is the vendor's rather than a dedicated channel. Escalation is "read the source" or "ask the maintainer." Documentation is real (dedicated docs site, AI-assisted dev guidelines added), which partially offsets this, but it should not be mistaken for a support contract. Plan internal ownership.
Scaling. Throughput is generally fine; the failure surface is process lifetime, not request volume. Long-lived workers — Horizon/queue, Octane — must reset or scope the EntityManager per job/request, or the identity map grows unbounded and serves stale entities. Lazy-loading across aggregates can reintroduce N+1 patterns the team thought it left behind with Eloquent. Connections are configured separately from config/database.php, so pool sizing and limits duplicate and can drift.
Failure modes. Ranked by expected pain: (1) cross-ORM partial commits — a write succeeding in one engine and failing in the other with no rollback; (2) schema drift between migrations and mapping metadata, surfacing as runtime mapping exceptions; (3) stale identity-map reads in workers; (4) observability blind spots, since Cycle traffic may not appear in Telescope or DB::listen — the database slow-query log becomes the primary signal; (5) upgrade cliffs when a Laravel major forces an adapter major with a PHP floor bump.
Ramp-up. Steep and under-appreciated. Engineers fluent in Eloquent have strong, wrong intuitions here — no save(), no mass assignment, explicit persist/flush, collections rather than query builders. Realistic ramp is weeks per engineer before productive, and the learning material is essentially the Cycle ORM docs plus this package's site, with no local expertise to lean on. If the team cannot absorb that, the architecture will erode back toward Eloquent-shaped code inside Cycle entities and the original justification disappears.
Recommendation. Given a composite score of ~24/100 with zero dependents, this is a conditional-accept, pilot-only package: suitable for an organization that has already committed to DDD with a DataMapper ORM and needs Laravel integration glue, and unsuitable as a reason to adopt DDD. Do not make it load-bearing for a core revenue path until the pilot has survived a Laravel major upgrade cycle.
How can I help you explore Laravel packages today?