symfony/object-mapper
Symfony Object Mapper maps one object to another using PHP attributes, giving you a clean, declarative way to handle DTOs and transformations without boilerplate. Part of the Symfony ecosystem.
new UserResponseDTO($user->name, $user->email, ...) blocks, adopting a declarative mapper is a decision you can defend on maintenance cost alone — one mapping definition instead of N call sites.toArray().Adopt if:
Look elsewhere if:
spatie/laravel-data gives you DTOs, validation, casting, and request integration in one package — more opinionated, but far less glue for a Laravel team. If you don't need the mapping layer in isolation, this package is the harder path.Model::fill() / Eloquent casts / API Resources already do the job — this is overkill and adds a dependency with a learning curve.To executives: "We're proposing a narrowly scoped dependency to remove a recurring tax on every API change: the manual copying of data between our database models and the objects we return to clients. Today each new endpoint re-implements that copying by hand, which is where field-rename bugs and review churn come from. This lets us describe the conversion once, next to the class, and reuse it. It's MIT-licensed, maintained by the Symfony project, and it's a library — not a framework commitment. The risk is low and reversible: it's additive, we can pilot it on one module, and we can rip it out without touching the database or the domain model. The honest caveat is that it's a young component with little third-party adoption, so I'm recommending it as a scoped pilot with a named owner, not as a house standard."
To engineering: "This replaces hand-written mapping with attributes — field renames, nested objects, collections, conditional and custom transforms. It's a single composer dependency, no framework lock-in; we wire the mapper into the container ourselves with a small provider. Two things to weigh honestly: (1) it's early — 36 stars, no dependents — so assume we'll hit unpatched edge cases and should pin the version; (2) spatie/laravel-data is the Laravel-native alternative and comes with validation and casting. Proposed approach: pilot on one bounded context with complex nested DTOs — the case where a hand-written mapper hurts most — and compare code volume, error surface, and runtime cost before deciding. If the pilot is ambiguous, we default to the Laravel-native option."
To architects: "The architectural value is enforced separation between persistence models and outbound contracts, expressed declaratively so the mapping is reviewable in one place. It fits cleanly where we have distinct read/write shapes or are extracting a service layer. The trade-offs: a young component with an API that moved quickly across 7.x→8.x, a PHP 8.4 floor on the current major, and an integration we own end-to-end since there's no Laravel bridge. My recommendation is to standardize the pattern — explicit DTOs and one mapping mechanism — while treating the specific library as swappable. Decide the pattern now, choose the implementation after the pilot."
How can I help you explore Laravel packages today?