If you aren’t familiar with Ditto, we are a real-time database for mobile, web, IoT, and server apps that can magically sync data with or even without the internet.
But what's really interesting about our database is that you can use Ditto in your apps as a regular document database. When we first created Ditto, we took three parallel tracks to building our entire system:
- The database portion: the primary way that customers use Ditto today
- Replication and CRDTs: how customers can mutate data in a distributed way and allow for automatic conflict resolution
- The mesh network: how devices can talk to each other in a heterogenous way
Parts 2 and 3 only work if you call ditto.tryStartSync()
. However, we wanted to design a system where the database portion was always capable of reading or writing information. That means if your application never sets up any network configuration permissions or calls ditto.tryStartSync()
, the instance will only act as a local database.
The usage is incredibly simple. Here's an example using Swift
val ditto = Ditto()
// inserting a document
ditto.store["people"].upsert([
"name": "Alice",
"score": 21
])
// finding documents
let docs = ditto.store["people"].find('name == $args.name', [
"name": "Alice"
])
and on Android
val ditto = Ditto(androidDependencies)
// inserting a document
ditto.store["people"].upsert(
mapOf(
"name" to "Alice",
"score" to 21
)
)
// finding documents
val docs = ditto.store["people"].find('name == $args.name', mapOf(
"name" to "Alice"
))
For more information on our APIs and other supported programming languages checkout the concepts section of our documentation. All of the data store
operations will work exactly the same as a syncing instance of Ditto. That means your application is completely capable of running a live query on a local instance of Ditto as well.
let ditto = Ditto()
let liveQueries = ditto.store["cars"].findAll().observe({ documents in
updateUI(documents)
})
Taking advantage of a local-only Ditto instance in the same app as a syncing Ditto instance
Each ditto instance is self-contained. That means that an app can run multiple ditto instances at the same time. All you need to do is to take a bit of care
// constructing a local only instance
let dittoLocalOnly = Ditto(path: '/foo1')
// constructing a syncing version of Ditto
let dittoSyncing = Ditto(identity: .onlinePlayground(appID: "my-cool-app"), path: '/foo2')
try! dittoSyncing.tryStartSync()
// notice that the path values are different to ensure that there are no file system collisions.
Why would you want a syncing instance and a non-syncing instance in the same app? There could be many reasons. Perhaps, your application may need to simply store data locally without replication, still using the same interface of a regular Ditto instance that you're accustomed to, while at the same time requiring to sync another instance. Syncing Ditto instances can control specific data that syncs or does not sync between devices, but some users may want the added simplicity of managing multiple Ditto instances with distinct functionality.
Looking Ahead
Ditto is an end-to-end platform product that can sync data regardless of connectivity from the edge to the cloud. That said, this is really our bread and butter, so a lot of our engineering efforts are focused on the performance of the replication, the mesh network, and our Big Peer (that lives in the cloud). This means that a lot of comparable database features aren't up to par with, say, something like SQLite or Realm. But don't worry, we are definitely getting there!
What are we lacking right now?
- No indexing - Currently, we don't have any functionality for indexing your data. Don't worry, we are architecting this functionality as we speak.
- Non-CRDT serializatation - Remember we built a syncing-database, so every document is a fully composable nested CRDT. Even if you use it as a local database, we still create and serialize a CRDT to disc.
What about JavaScript?
Currently, running Ditto as a local database using our JavaScript SDK comes with some caveats. Our web experience currently is in-memory only. That means if you were to use the npm package @dittolive/ditto
in the web browser, your bundler will use our WebAssembly version. As a result, nothing in the store is persisted and a simple refresh of the web page will have all data evicted. We are actively working on a backing storage interface using the File System Access API for modern browsers and a fallback to IndexedDB this year.
The good news is that today you can get persistence if you are using our JS library in Electron or NodeJS. If you're curious why: unlike the browser, these platforms actually have native API access. So, when running Ditto in NodeJS or Electron environments, the NPM package will use a compiled native library as it's backing storage layer, and you will actually see Ditto files created!
A real app using Ditto as a local database - Vaxx
We wanted to test out how it would be to use Ditto as a local database in an app that would actually provide some use to the world. Since some cities have mandated that restaurants must check for vaccination records to receive service, we noticed that a lot of customers were endlessly scrolling on their phones to pull up a picture of their records. This was wasting a lot of the maitre d's time and slowing down seating. So we thought, what if we could create an app with a simple (yet edgy) name that would allow customers to immediately pull up their vaccine card? Well, with Ditto this is actually quite simple. We built it in just about 1 day and released it to the app store! Vaxx is running on Ditto, using it only as a local database, and doesn't sync anything at all. Vaxx is currently enjoying 55,000 active users with no promotion at all and still growing! In addition, if you just search for "Vaccine Card" in the U.S. Apple App Store, it's the first result.
We hope to create an Android version sometime in the coming months, so stay tuned!
Top comments (0)