replikativ A distributed replication system for CRDTs (Conflict-free Replicated Data Types) that enables serverless, peer-to-peer data synchronization between Clojure and ClojureScript applications. Changelog | Vision | Related Work Features Cross-platform:…
replikativ
A distributed replication system for CRDTs (Conflict-free Replicated Data Types) that enables serverless, peer-to-peer data synchronization between Clojure and ClojureScript applications.
[Changelog](CHANGELOG.md) | [Vision](vision.md) | [Related Work](related_work.md)
Features
- Cross-platform: Works seamlessly between JVM (Clojure) and JavaScript (ClojureScript/Node.js)
- Multiple CRDTs: CDVCS (git-like), ORMap, LWWR (Last-Writer-Wins Register), SimpleGSet
- P2P synchronization: Direct peer-to-peer replication without central authority
- Composable: Built on core.async with middleware architecture
Development Setup
Prerequisites
- Clojure CLI tools (1.11.1+)
- Java 11+ (for JVM development)
- Node.js 18+ (for ClojureScript/integration tests)
Dependencies
This project uses deps.edn for dependency management. All dependencies will be automatically downloaded when running commands.
Key dependencies:
io.replikativ/kabel- Network layer for peer communicationio.replikativ/konserve- Storage abstractionio.replikativ/superv.async- Supervised async programmingthheller/shadow-cljs- ClojureScript compiler
Important: After cloning the repository or updating git dependencies, run:
bash
clj -X:deps prep
This prepares git dependencies (like kabel) for use. Required before running other commands.
Development Workflow
Start a REPL with development dependencies:
bash
clojure -M:dev
Or connect your editor (Emacs/Cider, Cursive, VSCode/Calva) using the :dev alias.
Testing
Running Clojure Tests
Run all Clojure tests on the JVM:
bash
clojure -M:test
Or run specific test namespaces:
bash
clojure -M:test -n replikativ.cdvcs-test
Running ClojureScript Tests
The project uses shadow-cljs for ClojureScript compilation and testing.
Cross-Platform Integration Tests
Test the full stack with JVM server + Node.js client:
bash
./test-integration.sh
This script:
1. Starts a JVM server hosting test CRDTs
2. Compiles ClojureScript tests for Node.js
3. Runs Node.js client tests that sync with the server
4. Automatically cleans up processes
The integration test verifies:
- Cross-platform CRDT synchronization
- LWWR replication between JVM and Node.js
- WebSocket connection handling
Manual ClojureScript Compilation
Compile for different targets:
bash
# Node.js (for integration tests)
clojure -M:shadow-cljs compile integration
# Browser development build
clojure -M:shadow-cljs compile browser-simple
# Browser production build (advanced optimization)
clojure -M:shadow-cljs compile browser-advanced
# Watch mode for development
clojure -M:shadow-cljs watch dev
Building
Library JAR
Build the library JAR for distribution:
bash
clojure -T:jar jar
This creates target/replikativ-0.2.5.jar.
Install locally to ~/.m2:
bash
clojure -T:jar install
Deploy to Clojars (maintainers only):
bash
# Requires CLOJARS_USERNAME and CLOJARS_PASSWORD env vars
clojure -T:jar deploy
API Documentation
Generate HTML API documentation locally with Codox:
bash
clojure -X:codox
This generates HTML documentation in the doc/ directory. Open doc/index.html in a browser to view the API docs.
Note: The HTML documentation is for local use only. GitHub doesn't render HTML files. See the [Documentation](#documentation) section below for markdown documentation available on GitHub.
Project Structure
replikativ/
├── src/replikativ/ # Core library code
│ ├── crdt/ # CRDT implementations
│ │ ├── cdvcs/ # Git-like CRDT
│ │ ├── lwwr/ # Last-Writer-Wins Register
│ │ ├── ormap/ # Observed-Remove Map
│ │ └── simple_gset/ # Grow-only Set
│ ├── p2p/ # P2P middleware (fetch, hooks)
│ ├── peer.cljc # Peer management
│ ├── stage.cljc # High-level API
│ └── core.cljc # Replication protocol
├── test/ # Test files
│ └── replikativ/
│ ├── integration_test.cljs # Cross-platform tests
│ └── integration_server.clj # Test server
├── deps.edn # Project dependencies
├── shadow-cljs.edn # ClojureScript build config
└── test-integration.sh # Integration test runner
Getting Started
Installation
Add replikativ to your deps.edn:
clojure
{:deps {io.replikativ/replikativ {:git/url "https://github.com/replikativ/replikativ"
:git/sha "LATEST-SHA-HERE"}
io.replikativ/konserve {:mvn/version "0.8.321"}}}
Or with Leiningen in project.clj:
clojure
:dependencies [[io.replikativ/replikativ "0.2.5"]
[io.replikativ/konserve "0.8.321"]]
Core Concepts
Peer - A network node that can synchronize CRDTs with other peers. Each peer has:
- A storage backend (konserve) for persistence
- Network handlers for communication (via kabel)
- Middleware for handling replication (fetch, hooks)
Stage - Your working area for CRDT operations. Think of it as a "workspace" where you:
- Create and modify CRDTs locally
- Subscribe to CRDTs from other peers
- Trigger synchronization
CRDT - Conflict-free Replicated Data Type. Data structures that can be modified independently on different peers and always converge to the same state when synced.
Complete Example: Syncing Data Between Two Peers
Server Side (JVM)
clojure
(ns my-app.server
(:require [replikativ.peer :refer [server-peer]]
[replikativ.stage :refer [create-stage!]]
[replikativ.crdt.lwwr.stage :as lwwr]
[konserve.memory :refer [new-mem-store]]
[kabel.peer :refer [start]]
[superv.async :refer [<?? S]]))
(defn start-server! []
(let [;; Create storage
store (<?? S (new-mem-store))
;; Create peer with WebSocket endpoint
peer (<?? S (server-peer S store "ws://localhost:47297"))
;; Create stage for this user
stage (<?? S (create-stage! "[email protected]" peer))
;; Start accepting connections
_ (start peer)
;; Create a shared CRDT with initial value
lwwr-id #uuid "550e8400-e29b-41d4-a716-446655440000"]
(<?? S (lwwr/create-lwwr! stage
:id lwwr-id
:description "Shared counter"
:init-val {:counter 0}))
(println "Server started on ws://localhost:47297")
(println "Hosting LWWR:" lwwr-id)
{:peer peer :stage stage :lwwr-id lwwr-id}))
Client Side (JVM or Node.js via ClojureScript)
clojure
(ns my-app.client
(:require [replikativ.peer :refer [client-peer]]
[replikativ.stage :refer [create-stage! connect!]]
[replikativ.crdt.lwwr.stage :as lwwr]
[replikativ.crdt.lwwr.realize :refer [stream-into-atom!]]
[konserve.memory :refer [new-mem-store]]
[kabel.peer :refer [stop]]
[superv.async :refer [<?? S]]))
(defn start-client! []
(let [;; Create storage
store (<?? S (new-mem-store))
;; Create client peer (no server endpoint)
peer (<?? S (client-peer S store))
;; Create stage
stage (<?? S (create-stage! "[email protected]" peer))
;; Use the same CRDT ID as server
lwwr-id #uuid "550e8400-e29b-41d4-a716-446655440000"
user "[email protected]"
;; Create local CRDT (required before streaming)
_ (<?? S (lwwr/create-lwwr! stage :id lwwr-id))
;; Set up reactive atom to receive updates
val-atom (atom nil)]
;; Stream CRDT changes into atom
(stream-into-atom! stage [user lwwr-id] val-atom)
;; Connect to server - triggers initial sync
(<?? S (connect! stage "ws://localhost:47297"))
(println "Connected to server!")
(println "Current value:" @val-atom)
;; => {:counter 0}
;; Modify the CRDT - automatically syncs to server
(<?? S (lwwr/set-register! stage [user lwwr-id]
{:counter (inc (:counter @val-atom))}))
(Thread/sleep 100) ;; Wait for sync
(println "Updated value:" @val-atom)
;; => {:counter 1}
;; The atom automatically updates when server changes it too!
{:peer peer :stage stage :val-atom val-atom}))
Choosing the Right CRDT
| CRDT | Use Case | Key Feature | Example |
|------|----------|-------------|---------|
| LWWR | Simple shared state | Last write wins, no conflicts | User preferences, feature flags, simple counters |
| CDVCS | Version-controlled data | Git-like with branches & merges | Document editing, code repositories, audit trails |
| ORMap | Collaborative maps | Add/remove keys concurrently | Shopping cart, user directory, metadata |
| SimpleGSet | Accumulating collections | Grow-only set | Tags, categories, event logs |
Rule of thumb:
- Start with LWWR for simple use cases
- Use CDVCS when you need version history
- Use ORMap for collaborative key-value editing
- Use SimpleGSet when you never need to remove items
Documentation
General Documentation
- [Vision and Motivation](vision.md) - Project goals, philosophy, and the problem replikativ solves
- [Related Work](related_work.md) - Comparison with swarm.js, irmin, IPFS, and other CRDT implementations
- [Changelog](CHANGELOG.md) - Version history and release notes
JavaScript / ClojureScript Usage
- [JavaScript Integration](javascript.md) - Overview of JavaScript bindings (experimental)
- [JavaScript API Reference](npm/doc/api.md) - Complete API documentation for JavaScript users
- [JavaScript Tutorial](npm/doc/tutorial.md) - Step-by-step guide for using replikativ from JavaScript
Code Examples
Test files serve as comprehensive examples of replikativ usage:- [integration_test.cljs](test/replikativ/integration_test.cljs) - Full cross-platform sync example (JVM ↔ Node.js)
- [integration_server.clj](test/replikativ/integration_server.clj) - Server setup for integration testing
- [lwwr_test.clj](test/replikativ/lwwr_test.clj) - Last-Writer-Wins Register operations and patterns
- [cdvcs_test.clj](test/replikativ/cdvcs_test.clj) - Git-like CDVCS operations, commits, and merges
- [ormap_test.clj](test/replikativ/ormap_test.clj) - Observed-Remove Map usage
- [merging_ormap_test.clj](test/replikativ/merging_ormap_test.clj) - Merging ORMap with custom merge functions
API Documentation (Local)
For detailed Clojure/ClojureScript API documentation, generate HTML docs locally:bash
clojure -X:codox
Then open doc/index.html in your browser.
Roadmap (suggestions)
0.3.0
- Investigate JS side integration of http://y-js.org/
- Investigate integration with similar systems, eg. IPFS pubsub
- Split middleware from replicated datatype implementations
- Improve network IO library kabel (Android support) [DONE]
- Move hashing into fetch middleware to simplify parallelization. [DONE]
- Experimental automatic Gossip protocol
- Experimental Snapshot Isolation
- Build reasonable small support libraries to partition application data for
- Add a monitoring interface as a cljs library with basic web views for
- Introduce
clojure.specto stage/... API.
0.4.0
- Authentication with signed public-private key signatures
- Model some level of consistency between CRDTs, probably Snapshot Isolation, to
- Implement more useful CRDTs (counter, vector-clock, ...)
0.5.0
- Use p2p block distribution similar to BitTorrent for immutable values (similar
- support WebRTC for value distribution similar to BitTorrent
- Java bindings
Long-term (1.0.0)
- Encryption of transaction with CRDT key encrypted by userkeys, public key
- Distribute bandwidth between CRDTs.
- Negotiate middlewares with versioning.
- Implement diverse prototypes, from real-time to "big-data".
Contributors
- Konrad Kuehne
- Christian Weilbach
Support
If you would like to get some commercial support for replikativ, feel free to
contact us at lambdaforge.
License
Copyright © 2013-2018 Christian Weilbach, Konrad Kühne
Distributed under the Eclipse Public License, the same as Clojure.
Members
-
datahike ★ PINNED
Versioned, fast, distributed Datalog engine for everyone.
Clojure ★ 1.8k 9d agoExplain → -
raster ★ PINNED
Fast, functional numerical computing for Clojure/JVM.
Clojure ★ 45 4m agoExplain → -
stratum ★ PINNED
Versioned, fast and scalable columnar database.
Clojure ★ 66 5d agoExplain → -
ansatz ★ PINNED
Dependently typed Clojure DSL with a Lean4 compatible kernel.
Clojure ★ 38 3d agoExplain → -
yggdrasil ★ PINNED
Git-like, causal space-time lattice abstraction over systems supporting this memory model.
Clojure ★ 17 3d agoExplain → -
replikativ ★ PINNED
An open, scalable and distributive p2p infrastructure.
Clojure ★ 342 3mo agoExplain → -
konserve
A clojuresque key-value/document store protocol with core.async.
Clojure ★ 318 19d agoExplain → -
superv.async
This is a Clojure(Script) library that extends core.async with error handling and includes a number of convenience functions and macros.
Clojure ★ 178 5mo agoExplain → -
hasch
Cross-platform (JVM and JS atm.) edn data structure hashing for Clojure.
Clojure ★ 128 4mo agoExplain → -
kabel
A library for simple wire-like connectivity semantics.
Clojure ★ 116 7d agoExplain → -
datalog-parser
Generic datalog parser compliant to datomic, datascript and datahike queries.
Clojure ★ 72 3mo agoExplain → -
hitchhiker-tree
Functional, persistent, off-heap, high performance data structure
Clojure ★ 46 3y agoExplain → -
superficie
Surface syntax for Clojure to help exposition/onboarding.
Clojure ★ 38 2mo agoExplain → -
datahike-server ▣
Datahike remote system
Clojure ★ 36 2y agoExplain → -
geheimnis
Cross-platform cryptography between cljs and clj.
Clojure ★ 35 5mo agoExplain → -
datahike-frontend
A front-end connecting to a Datahike back-end.
Clojure ★ 33 6y agoExplain → -
proximum
Versioned, fast and scalable nearest neighbor search.
Clojure ★ 28 1mo agoExplain → -
incognito
Safe transport of unknown record types in distributed systems.
Clojure ★ 22 5mo agoExplain → -
durable-persistence
Explorations in durable persistent datastructures for Clojure.
Clojure ★ 22 9y agoExplain → -
datahike-jdbc
Datahike JDBC data storage backend
Clojure ★ 20 1y agoExplain → -
katzen
Generalized algebraic theories and categorical programming for Clojure.
Clojure ★ 18 15d agoExplain → -
scriptum
Lucene with git-like semantics and Clojure integration.
Clojure ★ 18 1mo agoExplain → -
muschel
Bash interpreter with git-like memory and fine grained access control.
Clojure ★ 17 10d agoExplain → -
datahike-postgres
Datahike with Postgres as data storage
Clojure ★ 17 5y agoExplain → -
spindel
Cross-platform FRP runtime with a git-like memory model.
Clojure ★ 16 3d agoExplain → -
beichte
Static purity and effect analysis for Clojure.
Clojure ★ 16 2mo agoExplain → -
dvergr
FRP-based LLM agent framework with git-like memory model.
Clojure ★ 15 2h agoExplain → -
rechentafel
A spreadsheet evaluator for Clojure/Script.
Clojure ★ 14 1mo agoExplain → -
chat42
A small web chat demonstration with replikativ.
Clojure ★ 14 9y agoExplain → -
pg-datahike
Postgres compatibility layer for Datahike.
Clojure ★ 13 7d agoExplain → -
topiq
A distributed social network for serious discussions and funny topiqs :).
Clojure ★ 13 6y agoExplain → -
filesync-replikativ
A filesystem synchronization tool similar to Dropbox over replikativ.
Clojure ★ 12 9y agoExplain → -
kontor
A trans-national accounting kernel with modules for all business aspects.
Clojure ★ 11 10d agoExplain → -
twitter-collector
A simple twitter collector using replikativ.
Clojure ★ 11 9y agoExplain → -
konserve-carmine
A redis backend with carmine for konserve.
Clojure ★ 10 5y agoExplain → -
mesalog
CSV data loader for Datalog databases
Clojure ★ 9 2mo agoExplain → -
kabel-auth
Authentication middleware for kabel.
Clojure ★ 9 5mo agoExplain → -
datahike-s3
Datahike backend for S3.
Clojure ★ 8 1y agoExplain → -
persistent-sorted-set ⑂
Fast B-tree based persistent sorted set for Clojure/Script
Clojure ★ 7 11h agoExplain → -
beleg
A lightweight contractor invoice management system built with Clojure.
Clojure ★ 7 5mo agoExplain → -
mercurius
Payment provider for open source licenses with payment requirements.
Clojure ★ 7 3mo agoExplain → -
zufall
random name generator
Clojure ★ 7 3y agoExplain → -
datahike-redis
No description.
Clojure ★ 6 1y agoExplain → -
chat42app
A react native demo for chat42.
Clojure ★ 6 9y agoExplain → -
flechtwerk
flechtwerk provides visualization of commit graphs of CDVCS.
Clojure ★ 5 10y agoExplain → -
briefkasten
A mail client that can sync and index with Datahike and Scriptum (Lucene).
Clojure ★ 4 4mo agoExplain → -
konserve-jdbc
A JDBC backend for konserve.
Clojure ★ 4 2mo agoExplain → -
datahike-client
A datahike remote client
Clojure ★ 4 5y agoExplain → -
konserve-leveldb
A LevelDB backend for konserve.
Clojure ★ 4 5y agoExplain → -
replikativ-demo
Example project for replikativ in clj.
Clojure ★ 4 9y agoExplain → -
einbetten
Embedding helpers for Clojure.
Clojure ★ 3 5mo agoExplain → -
konserve-lmdb
High performance LMDB backend for konserve.
Clojure ★ 3 2mo agoExplain → -
konserve-rocksdb
A RocksDB backend for konserve
Clojure ★ 3 2mo agoExplain → -
replikativ-cljs-demo
Example project for replikativ in cljs.
Clojure ★ 3 9y agoExplain → -
datahike-benchmark
Measuring of datahike performance
Clojure ★ 3 4y agoExplain → -
datahike-server-transactor ▣
Transactor implementation for datahike that uses datahike-server.
Clojure ★ 2 3y agoExplain → -
datahike-rocksdb
Datahike RocksDB support.
Clojure ★ 2 5mo agoExplain → -
datahike-dynamodb
DynamoDB backend for datahike.
Clojure ★ 2 1y agoExplain → -
polo-collector
A collector of trading data on the Poloniex exchange.
Clojure ★ 2 3y agoExplain → -
konserve-clutch
A CouchDB backend for konserve with clutch.
Clojure ★ 2 5y agoExplain → -
datahike-leveldb
Datahike with LevelDB as data storage
Clojure ★ 2 5y agoExplain → -
konserve-welle
A Riak backend for konserve with Welle.
Clojure ★ 2 9y agoExplain → -
spindel-tui
TUI library based on spindel.
Clojure ★ 1 12d agoExplain → -
konserve-gcs
Google Cloud Storage support for konserve.
Clojure ★ 1 4mo agoExplain → -
logging
Unified structured logging for replikativ
Clojure ★ 1 3mo agoExplain → -
konserve-redis
Redis backend for konserve.
Clojure ★ 1 2mo agoExplain → -
konserve-s3
S3 backend for konserve.
Clojure ★ 1 20d agoExplain → -
clj-rocksdb
Clojure API for RocksDB.
Clojure ★ 1 5mo agoExplain → -
pod-registry ⑂
Pod manifests describe where pods can be downloaded, etc.
Clojure ★ 1 9d agoExplain → -
konserve-sync
Online synchronization of konserve stores between different environments.
Clojure ★ 1 5d agoExplain → -
datahike-migrations
A migration tool for Datahike
Clojure ★ 1 5y agoExplain → -
sherpa
A version migration tool for Datahike.
Clojure ★ 1 3y agoExplain → -
pydatahike
Python bindings for Datahike.
Python ★ 1 3y agoExplain → -
sendandi
Protocol above datalog databases for common functions
Clojure ★ 1 4y agoExplain → -
wanderung-datascript
DataScript-Datahike migrations
Clojure ★ 1 4y agoExplain → -
wanderung-core
Migration protocols for Datahike
Clojure ★ 1 4y agoExplain → -
datahike-fdb
FoundationDB backend for Datahike
Clojure ★ 1 5y agoExplain → -
obhut
Docker setup for operational log analytics
★ 1 8y agoExplain → -
umap-rstr
UMAP (Uniform Manifold Approximation and Projection) for Clojure — a port of umap-learn on the raster typed-dispatch compiler.
Clojure ★ 0 14h agoExplain → -
evoc-rstr
EVoC (Embedding Vector Oriented Clustering) for Clojure — a port of the Tutte Institute's evoc on raster + umap-rstr.
Clojure ★ 0 14h agoExplain → -
pattern ⑂
Pattern is an extensible combinator-based pattern match and substitution library. It's amazingly powerful.
Clojure ★ 0 2d agoExplain → -
dvergr-sandbox
The sandbox repo used to initialize a dvergr sandbox.
Clojure ★ 0 6d agoExplain → -
circleci-orb
Developing a CircleCI orb for usage in all the replikativ repositories
Dockerfile ★ 0 1mo agoExplain → -
datahike-lmdb
LMDB integration for datahike.
Clojure ★ 0 2mo agoExplain → -
konserve-dynamodb
DynamoDB backend for konserve.
Clojure ★ 0 2mo agoExplain → -
souffleuse
A chatbot that announces meetings and releases
Clojure ★ 0 1y agoExplain → -
datahike-backend-template ▣
An implementation template for new Datahike backends
Clojure ★ 0 5y agoExplain → -
replikativ-fressianize
A fressian serializer for replikativ's transaction protocol.
Clojure ★ 0 9y agoExplain → -
gezwitscher
A basic clojure wrapper for twitter4j APIs.
Clojure ★ 0 9y agoExplain → -
katalog
Management platform for replikativ
Clojure ★ 0 10y agoExplain →
No repos match these filters.