Skip to content

Arsenoal/syncforge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

205 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SyncForge

Offline-first sync for Kotlin Multiplatform — Android, iOS, JVM desktop, and native macOS.

Kotlin Maven Central License CI

Android iOS Desktop macOS

v2.0.0 on Maven Central · Release notes

Your app keeps its own database (Room on Android, or any store you choose). SyncForge owns a separate outbox and conflict store, then push/pulls over a pluggable transport. Local writes are instant; sync survives offline use and app restarts.


See it in action

SyncForge demo: add task, sync, conflict resolution, clear local DB, pull from server

./gradlew :mock-server:run          # Terminal 1
./gradlew :sample:installDebug      # Terminal 2 — emulator uses http://10.0.2.2:8080

Tap Sync in the sample app, trigger a conflict, or clear local data and pull from the server. Debug builds show an SF overlay for outbox and sync health.


Why SyncForge

Offline-first — Users edit locally; mutations queue in a durable outbox until the network returns.

Your data stays yours — Entity tables live in your Room DB or custom EntityStore. SyncForge does not replace your schema.

Conflict-aware — Per-entity strategies: last-write-wins, user resolution, field merge, gitLike three-way merge, CRDT fields.

Pluggable backend — Default REST/Ktor transport, or GraphQL, Supabase, Firebase, and custom SyncTransport adapters.

Optional sync — Ship offline-only, self-host a backend, or point at any server implementing the push/pull contract.


Quick start

Import the version catalog once (2.0.0 pins every artifact and the Gradle plugin):

// settings.gradle.kts
dependencyResolutionManagement {
    versionCatalogs {
        create("syncforge") {
            from("studio.syncforge:syncforge-catalog:2.0.0")
        }
    }
}
// app/build.gradle.kts
plugins {
    alias(syncforge.plugins.syncforge.android)
}
dependencies {
    implementation(syncforge.core)
}
// Application
syncManager = SyncForge.android(this) {
    baseUrl("https://api.example.com")
    registry(SyncForgeHandlers.registry(taskDao))
    schedulePeriodicSyncOnStart()
}

// Repository
syncManager.enqueueChange(Change.create("tasks", task))
syncManager.sync()

Full walkthrough (~10 min): Getting Started


Platforms

Platform Entry point Setup guide Sample
Android SyncForge.android { } Android setup :sample
iOS SyncForge.ios { } iOS setup :ios-sample
JVM desktop SyncForge.desktop { } Desktop setup :sample-desktop
macOS native SyncForge.macos { } Desktop setup
Browser SyncForge.web { } (experimental) Web setup :sample-web

Gradle snippets, DSL options, and platform-specific wiring are in each setup guide — not duplicated here.


Documentation

All features + samples Feature catalog
Copy-paste recipes Recipes
API reference Modules
Backend contract REST API
Conflicts Conflict resolution
Everything else docs/README.md

Sample apps

Module What it proves
:sample Multi-entity sync, gitLike conflicts, debug overlay, Compose UI
:mock-server Reference backend + conflict simulation endpoints
:backend-starter-spring Spring Boot + JDBC store

Development

Want to contribute or run the repo locally? See CONTRIBUTING.md.

git clone https://github.com/Arsenoal/syncforge.git
cd syncforge
./gradlew verifyReleaseSignOff

License

Apache License, Version 2.0

About

Offline-first sync library for Kotlin Multiplatform — outbox, push/pull, conflicts, and Compose helpers for Android, iOS, and desktop.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages