PHPackages                             tailflow/dto - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. tailflow/dto

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

tailflow/dto
============

A simple and lightweight implementation of Data Transfer Objects (DTO) in Laravel with optional casting support.

1.0.2(3y ago)4305MITPHPPHP &gt;=8.1

Since Jun 18Pushed 3y ago1 watchersCompare

[ Source](https://github.com/tailflow/dto)[ Packagist](https://packagist.org/packages/tailflow/dto)[ Docs](https://github.com/tailflow/dto)[ RSS](/packages/tailflow-dto/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (3)Versions (4)Used By (0)

Laravel Data Transfer Object
============================

[](#laravel-data-transfer-object)

[![Latest Version on Packagist](https://camo.githubusercontent.com/ec8423e0df85a81c4cd1f217ca68cafe09f8d2167a0067e3a72bd95636d35d9d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7461696c666c6f772f64746f2e737667)](https://packagist.org/packages/tailflow/dto)[![Build Status on GitHub Actions](https://camo.githubusercontent.com/5c9294cec1a70d049c1d2071dcb63855f38ce1e336330738401d1273d9193397/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7461696c666c6f772f64746f2f63692e796d6c3f6272616e63683d6d61696e)](https://github.com/tailflow/dto/actions)

A simple and lightweight implementation of Data Transfer Objects (DTO) in Laravel with optional casting support.

Under the hood it implements Laravel's [`Castable`](https://laravel.com/docs/8.x/eloquent-mutators#castables) interface with a Laravel [custom cast](https://laravel.com/docs/7.x/eloquent-mutators#custom-casts) that handles serializing between the `DataTransferObject` (or a compatible array) and your JSON database column.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require tailflow/dto
```

Usage
-----

[](#usage)

### 1. Create your `DataTransferObject` or `DataTransferObjectCollection`

[](#1-create-your-datatransferobject-or-datatransferobjectcollection)

```
namespace App\DataTransferObjects;

use Tailflow\DataTransferObjects\DataTransferObject;

class Address extends DataTransferObject
{
    public string $country;
    public string $city;
    public string $street;
}
```

```
namespace App\DataTransferObjects;

use Tailflow\DataTransferObjects\DataTransferObjectCollection;

class WorkAddresses extends DataTransferObjectCollection
{
    public static function getItemClass(): string
    {
        return Address::class;
    }
}
```

### (Optional) 2. Configure your Eloquent attribute casting:

[](#optional-2-configure-your-eloquent-attribute-casting)

Note that this should be a `jsonb` or `json` column in your database schema.

```
namespace App\Models;

use App\DataTansferObjects\Address;
use App\DataTansferObjects\WorkAddresses;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $casts = [
        'address' => Address::class,
        'work_addresses' => WorkAddresses::class,
    ];
}
```

### 3. Enjoy ~

[](#3-enjoy-)

Pass DTOs as arguments or use as return values, and get a nice autocompletion.

```
function getAddress(Address $originalAddress): Address
{
    $address = new Address();
    $address->county = $originalAddress->country;
    $address->city = 'Tokyo';
    $address->street = '4-2-8 Shiba-koen';

    return $address;
}

// or

function getAddress(): Address
{
    return new Address(
        [
            'country' => 'Japan',
            'city' => 'Tokyo',
            'street' => '4-2-8 Shiba-koen',
        ]
    );
}
```

On Eloquent models, you can now pass either an instance of your `Address` class, or even just an array with a compatible structure. It will automatically be cast between your class and JSON for storage and the data will be validated on the way in and out.

```
$workAddress = new Address();
$workAddress->country = 'Japan';
$workAddress->city = 'Osaka';

$user = User::create([
    // ...
    'address' => [
        'country' => 'Japan',
        'city' => 'Tokyo',
        'street' => '4-2-8 Shiba-koen',
    ],
    'work_addresses' => [
        $workAddress
    ]

]);

$residents = User::where('address->city', 'Tokyo')->get();
```

But the best part is that you can decorate your class with domain-specific methods to turn it into a powerful value object.

```
$user->address->toMapUrl();

$user->address->getCoordinates();

$user->address->getPostageCost($sender);

$user->address->calculateDistance($otherUser->address);

echo (string) $user->address;
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~96 days

Total

3

Last Release

1229d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b474f301550aa1d1c883fabfd3523fd6bd7577b9b6fa0c15a3f758f95307ea5e?d=identicon)[alexzarbn](/maintainers/alexzarbn)

---

Top Contributors

[![alexzarbn](https://avatars.githubusercontent.com/u/12220926?v=4)](https://github.com/alexzarbn "alexzarbn (22 commits)")

---

Tags

laravel-castable-data-transfer-objectlaravel-castable-value-objectlaravel-data-transfer-objecttailflowlaravel castable dtolaravel value object

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tailflow-dto/health.svg)

```
[![Health](https://phpackages.com/badges/tailflow-dto/health.svg)](https://phpackages.com/packages/tailflow-dto)
```

###  Alternatives

[guava/calendar

Adds support for vkurko/calendar to Filament PHP.

298241.0k3](/packages/guava-calendar)[tonysm/rich-text-laravel

Integrates Trix content with Laravel

46577.8k1](/packages/tonysm-rich-text-laravel)[mauricius/laravel-htmx

Laravel helper library for Htmx

364101.1k1](/packages/mauricius-laravel-htmx)[illuminate/reflection

The Illuminate Reflection package.

361.6M3](/packages/illuminate-reflection)[ralphjsmit/laravel-helpers

A package containing handy helpers for your Laravel-application.

13704.6k2](/packages/ralphjsmit-laravel-helpers)[spatie/laravel-screenshot

Take screenshots of web pages in Laravel apps

7615.9k2](/packages/spatie-laravel-screenshot)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
