Skip to content

Why Choose Bag?

Bag is a simple, lightweight, modern, and flexible library for working with value objects in PHP.

It is designed to be easy to use, with a minimal API that is easy to understand and use.

Bag focuses on immutability and type safety.

Compared to spatie/laravel-data

Bag was heavily inspired by the excellent spatie/laravel-data package, and as such should feel very familiar to anyone who has used it — however, it has several key differences.

Common Features


Bag is immutable by default.

spatie/laravel-data does not support immutable value objects, and as of PHP 8.3, there is no reasonable way to make them immutable.

Factory Support

Bag factories support many of the rich features and simple UX as Laravel Model Factories with the exception of not having a create() method (as value objects do not feature persistence). This includes support for factory states and sequences.

spatie/laravel-data v3 does not support factories, while v4 has rudimentary support.

Variadic Support

Bag supports the use of Variadic during value object creation.


Bag uses Laravel Collections as the basis for its Collection classes, and supports them wherever Collections are used, however Bag\Collection is an immutable-safe variant that we recommend using whenever possible.

spatie/laravel-data v3 uses a custom DataCollection class that is not based on Laravel collections and lacks many Collection features. v4 uses Laravel Collections, although it still has custom collection classes with varying levels of compatibility with Laravel Collections.

Hidden Properties

Bag supports hiding properties when transforming to an array or JSON.

Other Differences

In addition to the above, Bag has a few other minor differences:

  • Casters apply to both incoming values and outgoing values, while spatie/laravel-data splits these into two difference concepts.
  • Input from complex values uses Transformers, which are more explicit in Bag, while spatie/laravel-data uses a more implicit approach with magic methods e.g. ::fromModel()
  • Simpler attribute names: Cast vs WithCast and WithTransformer

Made with 🦁💖🏳️‍🌈 by Davey Shafik.