Skip to content

Repository files navigation

Open Sync

Data sync from any source to any destination.

Open Sync's two arrows illuminated by moving warm light

Deploy on nibrun

Open Sync is a headless sync engine that handles checkpointing, queuing, and retries. You define how sources read data and how destinations deliver it, so the same engine can fit different providers, storage systems, and workflows.

Embed it as a dependency and call it directly from your host's business logic. The engine runs in the same process; your application keeps its own UI and authentication.

This repository also includes a default host implementation as a sample app: a dashboard with sources for GitHub pull requests, Gmail and Slack threads, and Granola meetings.

How it works

Any external API exchanges data with your source logic through polling, followed by the Open Sync engine, your delivery logic, and your destination.

Components

Component What it does How to configure it
External API The system your source polls. Choose it in your source logic; connect provider accounts through sync.providers when needed.
Source logic Your code that reads data and returns a deliverable. Register it in definitions; declare inputs in configSchema and read data in step().
Engine Coordinates polling, saves checkpoints, queues deliveries, and retries failed work. Register sources and delivery handlers with createOpenSync(). Your host controls its start() and close() lifecycle.
Delivery logic Your code that writes each delivery to the destination. Register it in destinationTypes with a configSchema and deliver(). Set acceptsAssets: true to handle assets.
Destination The service, database, or storage that receives your data. Pass its settings as config to sync.api.createDestination().

Data types

Data What it is How to use it
Record A structured item, such as an email thread. Set operation (upsert or delete), kind, and a stable id. Upserts include data matching the source's kinds schema.
Asset Binary content, such as an attachment or image. Capture it with assets.capture() and include its reference in a record's assetRefs or the deliverable's assets.
Deliverable A batch of records and optional assets produced by a source. Return it from step() alongside a checkpoint (where to resume) and complete (whether this poll finished).

Embed in your host

The current package requires Bun 1.4+.

bun add @context-use/open-sync
  1. Call await createOpenSync() with a data directory, your sources and destinations, and your host's authorization functions.
  2. Route requests to sync.fetch(request) and set publicUrl to that route's full URL (for example, https://your-app.com/api/open-sync). This also handles provider authorization callbacks.
  3. Call await sync.start() before accepting requests and await sync.close() when shutting down.

Startup registers one half-hourly OS job through Bun.cron; Linux hosts need a running cron service. For a compiled binary, follow the sample entrypoint: handle runOpenSyncCron() before dynamically importing the normal server code, and compile with splitting: true. This keeps the temporary cron process from loading the server modules. It asks the running app to process due syncs, waits for completion, and exits.

Use sync.providers to connect accounts, then create a sync with sync.api.createSync(). Supply the source definition, its config, the destination, and a provider connection when needed. All enabled syncs poll on the shared cron schedule. Pass the acting user's actorId and data owner's ownerId from your host's authentication.

See the sample host, configuration options, and source and destination examples.

Deploy on nibrun

Deploy on nibrun

Use the button above to deploy the sample host on nibrun. Open your instance's URL, create an account, and connect your providers.

To update an existing instance, complete the local setup below, then install the nibrun CLI and sign in:

curl -fsSL https://nibrun.com/install.sh | sh
nib login
bun run deploy --app YOUR_APP_SLUG

Replace YOUR_APP_SLUG with the slug from nib apps list. The command builds and deploys the update.

Run the sample app locally

Clone this repository and install Bun 1.4 and Node 24, then:

bun install
bun run dev

Open localhost:5173 and create an account.

About

Headless data sync from any source to any destination

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages