Offline-first sync for Laravel & NativePHP.

Build offline-first Laravel and NativePHP apps with local database writes, mutation logs, conflict resolution, and client-driven sync when connectivity returns - without WebSockets, polling, or realtime infrastructure.

Sync lifecycle

Client writes first. Server reconciles later.

No sockets

Local database

Reads and writes continue offline.

Mutation log

Creates, updates, and deletes become immutable operations.

Push

Client sends pending mutations.

Pull

Server returns changed snapshots.

The package family

Two free MIT packages cover most use cases.
Commercial add-ons add NativePHP-specific functionality and production observability tools.

Free & Open Source
MIT
tether/client- any Laravel app

The Syncable trait, mutation log, and full push/pull sync engine. Runs on any Laravel application.

Syncable trait Mutation log ULID identity Offline-first
tether/server- central server

Sync endpoints, mutation application, and pull snapshot generation. Install on your central Laravel server alongside your business logic.

Push endpoint Pull snapshots Conflict detection Idempotent
Commercial Add-ons
tether/nativephp-client

Automatic sync for NativePHP iOS and Android apps. Syncs on app resume, connectivity restored, and optionally in the background.

iOS & Android Background sync Network awareness
tether/pro-server

Production dashboard for understanding what every sync request did, why it failed, which conflicts were detected, and ability to manually replay it.

Sync timeline Payload diffs Replay preview Health metrics

Built for real-world offline apps

    Truly offline-first

    No network dependency for reads or writes. Data lives in a local database. Sync is a background concern, not a blocking step.

    Client-initiated sync

    The server never pushes to clients. All sync is triggered by the client - on demand, on a schedule, or automatically via queue jobs.

    Conflict resolution

    The server detects conflicts when two clients modify the same record. Register a custom resolver per model, or rely on the sensible last-write-wins default.

    ULID identity

    Every record gets a client-generated ULID before it touches the network. No ID remapping on sync. Records created offline merge cleanly when they reach the server.

    Idempotent by design

    Every push is safe to retry. The server deduplicates by mutation ID - within a batch and across requests. No duplicate writes, no matter how many times a sync runs.

    Layered architecture

    The free packages provide the core sync foundation. Commercial add-ons extend the system with mobile automation and a finished Pro Server dashboard for inspecting production sync behaviour.