PHPackages                             byrcsc/laravel-data-sync - 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. [PDF &amp; Document Generation](/categories/documents)
4. /
5. byrcsc/laravel-data-sync

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

byrcsc/laravel-data-sync
========================

Stream files into Laravel models with auditable, resumable data syncs and transfers.

v1.0.0(today)00MITPHPPHP ^8.3CI passing

Since Jul 29Pushed todayCompare

[ Source](https://github.com/byrcsc/laravel-data-sync)[ Packagist](https://packagist.org/packages/byrcsc/laravel-data-sync)[ Docs](https://github.com/byrcsc/laravel-data-sync)[ Fund](https://www.buymeacoffee.com/ryancatapang)[ RSS](/packages/byrcsc-laravel-data-sync/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (21)Versions (3)Used By (0)

Laravel Data Sync
=================

[](#laravel-data-sync)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1cdaab8414031129901eb6cdf7b2aaf05f01c8d5d0ac564ce03e744deb367de7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6279726373632f6c61726176656c2d646174612d73796e632e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/byrcsc/laravel-data-sync)[![GitHub Tests Action Status](https://camo.githubusercontent.com/596a4284207f19179d30ed36cc7146b498feec99c7fadd7e189ac7da02ab402c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6279726373632f6c61726176656c2d646174612d73796e632f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/byrcsc/laravel-data-sync/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub PHPStan Action Status](https://camo.githubusercontent.com/aced6c9a7a3685811cf4a6708ebbf8130c6e95d5b752813a38411f6d152ccaa2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6279726373632f6c61726176656c2d646174612d73796e632f7068707374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d7068707374616e267374796c653d666c61742d737175617265)](https://github.com/byrcsc/laravel-data-sync/actions?query=workflow%3APHPStan+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/4665e6e2b31c0c4e1006ad3cb9db44ad2fd272c39afea857a7d416f769379d5f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6279726373632f6c61726176656c2d646174612d73796e632e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/byrcsc/laravel-data-sync)

An external system drops a file on your server: a CRM export, a supplier price list, a bank statement. It has to end up in your tables. Laravel Data Sync turns that into a class that names the source, the format, the model, the field mapping, and the columns to match on.

The package handles discovery, reading, validation, queued writes, and the audit trail. A process-once ledger means the same file never lands twice. Your application keeps ownership of its models, its business rules, and whatever it does with the data afterwards.

**[Read the full documentation](https://docs.rcsc.dev/laravel-data-sync/)** for definitions, readers, write policies, queued execution, transfers, retries, retention, and every Artisan command.

LaravelTested PHP versions12.x8.3, 8.413.x8.3, 8.4Installation
------------

[](#installation)

Install the package, publish its configuration and migration, and migrate:

```
composer require byrcsc/laravel-data-sync
php artisan vendor:publish --tag="data-sync-config"
php artisan vendor:publish --tag="data-sync-migrations"
php artisan migrate
```

Publish the configuration before the migration when you want custom table names; the migration reads them from `data-sync.tables`.

Queued syncs fan chunks out through `Bus::batch()`, so the framework's `job_batches` table must exist. FTP and SFTP sources need a Flysystem adapter (`league/flysystem-ftp` or `league/flysystem-sftp-v3`), neither of which is installed by default.

Run `php artisan sync:doctor` after installing. It checks tables, disks, source reachability, cache locks, and `matchOn` indexes before your first real feed arrives. See the [installation guide](https://docs.rcsc.dev/laravel-data-sync/v1/installation)for disks, connections, and queue routing.

Quick start
-----------

[](#quick-start)

Generate a definition:

```
php artisan make:sync ProductsSync
```

Fill in the source, the format, the model, the fields, and the match columns:

```
namespace App\Syncs;

use App\Models\Product;
use ByRcsc\LaravelDataSync\Contracts\Reader as ReaderContract;
use ByRcsc\LaravelDataSync\Definitions\Field;
use ByRcsc\LaravelDataSync\Definitions\Reader;
use ByRcsc\LaravelDataSync\Definitions\Source;
use ByRcsc\LaravelDataSync\Definitions\SyncDefinition;

final class ProductsSync extends SyncDefinition
{
    public function source(): Source
    {
        return Source::disk('incoming')->path('products');
    }

    public function format(): ReaderContract
    {
        return Reader::csv();
    }

    public function model(): string
    {
        return Product::class;
    }

    public function fields(): array
    {
        return [
            Field::make('sku', from: 'SKU'),
            Field::make('name', from: 'Description'),
            Field::make('price_cents', from: 'Price')
                ->transform(fn (string $value): int => (int) round((float) $value * 100)),
        ];
    }

    public function matchOn(): array
    {
        return ['sku'];
    }

    public function rules(): array
    {
        return [
            'sku' => ['required', 'string', 'max:32'],
            'price_cents' => ['required', 'integer', 'min:0'],
        ];
    }
}
```

Register it in `config/data-sync.php` and run it:

```
'syncs' => [
    App\Syncs\ProductsSync::class,
],
```

```
php artisan sync:run products          # queued
php artisan sync:run products --now    # in this process
php artisan sync:status
```

The name is derived from the class: `ProductsSync` becomes `products`.

What is included
----------------

[](#what-is-included)

- Class-based sync definitions with a declarative field mapping, per-row validation rules, and configurable write, duplicate, and unknown-column policies.
- Streaming readers for CSV and other delimited text, XLSX, JSON, NDJSON, and fixed-width files.
- Queued processing that fans a file's chunks out through `Bus::batch()`, plus an in-process mode for small feeds and an `atomic()` whole-file mode.
- A SHA-256 ledger that makes reprocessing a no-op, checksum-verified archives for completed files, and preserved copies for failed ones.
- Run history with counters, batch progress, failed-row records, and an error summary, surfaced through `sync:status`.
- `sync:retry` for a whole finished run, or `--failed-rows` to replay only the captured failed-row payloads.
- File transfers with filename-pattern metadata, templated destination paths, checksum verification, and optional model linking.
- Schedule registration, retention pruning, and a `sync:doctor` health check for the whole installation.

Important behavior
------------------

[](#important-behavior)

- File identity is the SHA-256 checksum of the contents. Renaming a file does not make it new; changing one byte does.
- Only a successful run blocks reprocessing. A failed checksum is retried on the next run without `--force`.
- Chunks commit independently. Only `atomic()` gives a file all-or-nothing semantics, at the cost of parallelism.
- Model events fire only on the Eloquent write path, which a definition opts into by declaring `beforeSave()` or `afterSave()`.
- Package events are dispatched synchronously and never implement `ShouldQueue`. Queue your listeners.
- Multi-server deployments need a shared staging disk. A local staging disk is a single-machine configuration.
- `--dry-run` skips `prepare()`, so its counts are a preview and not a guarantee.
- `Reader::json()` reads a whole document into memory. Use NDJSON for feeds that need to stream.
- The `sync_files` ledger is never pruned; runs, failed rows, and archived files are. `sync:prune` does not sweep the staging disk, so successful runs leave their staged copy behind.
- Rows that fail are recorded and the run continues. `maxErrors()` is the only thing that stops a bad feed part way.

Out of scope
------------

[](#out-of-scope)

The package draws its edges deliberately. What follows describes what it sets out to do rather than what it might do later: treat none of it as planned work, and none of it as ruled out forever.

- **Model pruning for absent rows.** The package never deletes application records that stop appearing in a feed. It is written for incremental and delta feeds rather than full snapshots.
- **PDF and OCR extraction.** Transfers move PDFs; nothing reads inside them.
- **AI-assisted extraction.** Mapping is declarative and deterministic.
- **Two-way sync.** Data flows from files into models, never back out.
- **API connectors.** Sources are filesystems. An API feed has to be written to a disk first.
- **Merge semantics for captured JSON.** `UnknownColumnPolicy::Capture` overwrites the target attribute; it does not merge with what is already there.
- **Retry from a date.** `sync:retry` takes a run, not a time range.
- **Glob and pattern discovery.** A source names either a directory, including files in its subdirectories, or a single file. There is no filtering by name or extension.

Documentation
-------------

[](#documentation)

- [Installation and setup](https://docs.rcsc.dev/laravel-data-sync/v1/installation)
- [Quick start](https://docs.rcsc.dev/laravel-data-sync/v1/quick-start)
- [Matching and writing](https://docs.rcsc.dev/laravel-data-sync/v1/matching-and-writing)
- [Running a sync](https://docs.rcsc.dev/laravel-data-sync/v1/running-syncs)
- [File transfers](https://docs.rcsc.dev/laravel-data-sync/v1/file-transfers)
- [Failures and retries](https://docs.rcsc.dev/laravel-data-sync/v1/failures-and-retries)
- [Configuration](https://docs.rcsc.dev/laravel-data-sync/v1/configuration)
- [Troubleshooting](https://docs.rcsc.dev/laravel-data-sync/v1/troubleshooting)

Development
-----------

[](#development)

The local checks mirror CI:

```
composer install
composer test
composer analyse
vendor/bin/pint --test
```

PHPStan runs at level max with no baseline. Tests use SQLite locally and run against MySQL and PostgreSQL in CI.

`workbench/` is a bootable demo application that installs the package the way a real application would. `composer build` sets it up; see [workbench/README.md](workbench/README.md) for the demo loop.

Versioning
----------

[](#versioning)

The package follows [semantic versioning](https://semver.org/spec/v2.0.0.html).

- Upgrading within `1.x` is safe. Nothing you use will break.
- Only a new major version, like `2.0.0`, can break your code.
- If the README or the documentation describes it, it is safe to build on. If they don't, treat it as internal and expect it to change.

Bug fixes go into the newest version only. To get a fix, upgrade to it.

Questions and issues
--------------------

[](#questions-and-issues)

- **Stuck, or have an idea?** Start a [discussion](https://github.com/byrcsc/laravel-data-sync/discussions). Usage questions and feature ideas both live there.
- **Found a bug you can reproduce?**[Open an issue](https://github.com/byrcsc/laravel-data-sync/issues). A failing test is the fastest way to a fix, and a short reproduction is the next best thing.
- **Found a security problem?** Please don't open a public issue. See [SECURITY.md](SECURITY.md) for how to report it privately.
- **Planning a pull request?** [CONTRIBUTING.md](CONTRIBUTING.md) covers the setup and the three checks it needs to pass.

This package is maintained by one person, so replies can take a while. Everything gets read.

Credits
-------

[](#credits)

- [Ryan Catapang](https://github.com/byrcsc)
- [All contributors](https://github.com/byrcsc/laravel-data-sync/graphs/contributors)

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md). Changelog in [CHANGELOG.md](CHANGELOG.md).

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity49

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 ~2 days

Total

2

Last Release

0d ago

Major Versions

v0.2.0 → v1.0.02026-08-01

### Community

Maintainers

![](https://www.gravatar.com/avatar/9258c643a563d82b6ae3f5b1c71158ed150c5bfd95ec48b52f837dbf8caf55d6?d=identicon)[rcscatapang](/maintainers/rcscatapang)

---

Top Contributors

[![rcscatapang](https://avatars.githubusercontent.com/u/60214290?v=4)](https://github.com/rcscatapang "rcscatapang (27 commits)")

---

Tags

jsonlaravelsftpxlsxcsvNDJSONetldata-importfixed widthdata-sync

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/byrcsc-laravel-data-sync/health.svg)

```
[![Health](https://phpackages.com/badges/byrcsc-laravel-data-sync/health.svg)](https://phpackages.com/packages/byrcsc-laravel-data-sync)
```

###  Alternatives

[laravel/ai

The official AI SDK for Laravel.

1.1k4.6M275](/packages/laravel-ai)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9872.4M142](/packages/roots-acorn)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.4M352](/packages/psalm-plugin-laravel)[flarum/core

Delightfully simple forum software.

261.5M2.4k](/packages/flarum-core)[spatie/laravel-medialibrary

Associate files with Eloquent models

6.2k45.4M679](/packages/spatie-laravel-medialibrary)[illuminate/queue

The Illuminate Queue package.

20433.0M1.7k](/packages/illuminate-queue)

PHPackages © 2026

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