Dexie Cloud Quickstart
Get up and running in a minute!
This guide will help you:
- Create a simple offline-first app with storage and sync
- Deploy it to your own free static hosting on GitHub
- Install it on mobile
- See it sync between mobile and desktop
- Go through the code to learn the details.
This app is an educational PWA with focus on clean, minimalistic and correct code.
Prerequisits
 |  |
---|---|
OS | MacOS, Linux or Windows with Git Bash (included in Git for Windows) |
Node | Version >= 18 |
Steps
-
Download our sample app and unzip it
-
Start a Terminal or Git Bash Console and
cd
to the extracted zip (~/Downloads/dexie-cloud-todo-app) and install dependenciesnpm install
-
Create your own database in our cloud:
npx dexie-cloud create
It will send you a one-time password. Fill it in to proceed with database creation.
-
Now, run our little script that configures your app and database for this sample
chmod +x ./configure-app.sh ./configure-app.sh
-
Start the app in dev mode:
npm run dev
Deploy the PWA using Github Pages
The app is easily deployed to any static hosting provider. After running npm run build
, the deployable PWA is all in the build
folder. If you already have a GitHub account, here are the steps to deploy the app on GitHub Pages:
-
Initialize a new Git repository in your project folder:
git init git add . git commit -m "Initial commit"
-
Create a new repository on GitHub (for your source but also the static hosting):
- Go to github.com and sign in
- Click the “+” icon in the top right corner
- Select “New repository”
- Name your repository (e.g., “my-dexie-cloud-app”)
- Don’t initialize with README, .gitignore, or license (since you already have files)
-
Connect your local repository to GitHub:
git remote add origin https://github.com/<yourusername>/<your-repo-name>.git git branch -M main git push -u origin main
-
Deploy using GitHub Pages:
npm run build # Deploy the PWA to GitHub Pages: npm run deploy # White-list the origin: npx dexie-cloud whitelist https://<yourusername>.github.io
Your PWA will be available at https://<yourusername>.github.io/<your-repo-name>/dexie-cloud-todo-app/.
For reference: The original app is deployed on https://dexie.github.io/Dexie.js/dexie-cloud-todo-app/ (open ↗)
See Sync in Action
- Install the PWA on your phone by navigating to https://<yourusername>.github.io/<your-repo-name>/dexie-cloud-todo-app/ on your phone browser
- Select “save to home screen” and choose to install it as an app.
- Navigate to the app on your computer as well. Install it as a Desktop app (optionally)
- Login as Alice on computer and Bob on the phone.
- Let Alice create a Todo-list and share it to Bob.
- See how everything is instantly synced between the two.
- Turn WiFi off to test offline. Play around. Turn it on again and see it sync. Try different scenarios such as one offline client deletes a list while the other one adds a new item to it - and then let them sync their actions.
Guide to the Source Code
Data Layer
- db.ts exports the singleton TodoDB instance.
- TodoDB - a sub class of Dexie that contains database declaration and sync configuration.
- TodoItem - the shape of a to-do item, declared as a simple typescript interface.
- TodoList - the shape and logic of a to-do list - declared as a class with methods for sharing, deleting etc - operations that involves transactions and logic, perfectly encapsulated in class! Please look at its methods to learn how realms, members, sharing and deletion should be done in order to preserve consistency across various offline use cases.
Whether to encapsulate logic in a class as we do with TodoList is only a question of taste. It could equally well have been a pure interface just like we did with TodoItem. However, having the consistency logic close to the model is a way to encourage correct usage of the model.
Visual Components
- TodoLists - a very simple example useLiveQuery()
- TodoListView - showcases the
usePermissions()
hook and how limited user access can disable certain actions. Also how to edit the name inline without any complex state management. - TodoItemView - shows another example of
usePermissions()
and inline editing - SyncStatusIcon - showcases
useObservable()
and how to reflect the current offline state to the user. - Invites - showcases in-app presentation of invites.
Roles and Access Control
- roles.json - defining a set of permission per role.
- configureApp.sh - Showcases how to use the
dexie-cloud
CLI to import roles and demoUsers as well as white-listing the application URLs. It also creates an .env.local file with the database URL.
PWA stuff
- vite.config.ts - configures the PWA to make the app installable. It generates a web manifest with app icons, name, URL and screenshots.
- sw.ts - The minimal Service Worker that just caches assets for offline use as well as activates Dexie Cloud’s background sync.
Other Resources
- Dexie Cloud Tutorial - a step-by-step guide (without any pre-baked sample app)
- Dexie Cloud Starter - a nextjs based app with additional features:
- Social login
- Collaborative Text Editing with Tiptap and Y.js
- Full-text search with Lunr + Dexie
Table of Contents
- API Reference
- Access Control in Dexie Cloud
- Add demo users
- Add public data
- Authentication in Dexie Cloud
- Best Practices
- Building Addons
- Collection
- Collection.and()
- Collection.clone()
- Collection.count()
- Collection.delete()
- Collection.desc()
- Collection.distinct()
- Collection.each()
- Collection.eachKey()
- Collection.eachPrimaryKey()
- Collection.eachUniqueKey()
- Collection.filter()
- Collection.first()
- Collection.keys()
- Collection.last()
- Collection.limit()
- Collection.modify()
- Collection.offset()
- Collection.or()
- Collection.primaryKeys()
- Collection.raw()
- Collection.reverse()
- Collection.sortBy()
- Collection.toArray()
- Collection.uniqueKeys()
- Collection.until()
- Compound Index
- Consistency in Dexie Cloud
- Consistent add() operator
- Consistent remove() operator
- Consistent replacePrefix() operator
- Consuming Dexie as a module
- Custom Emails in Dexie Cloud
- DBCore
- DBCoreAddRequest
- DBCoreCountRequest
- DBCoreCursor
- DBCoreDeleteRangeRequest
- DBCoreDeleteRequest
- DBCoreGetManyRequest
- DBCoreGetRequest
- DBCoreIndex
- DBCoreKeyRange
- DBCoreMutateRequest
- DBCoreMutateResponse
- DBCoreOpenCursorRequest
- DBCorePutRequest
- DBCoreQuery
- DBCoreQueryRequest
- DBCoreQueryResponse
- DBCoreRangeType
- DBCoreSchema
- DBCoreTable
- DBCoreTableSchema
- DBCoreTransaction
- DBCoreTransactionMode
- DBPermissionSet
- Deprecations
- Derived Work
- Design
- Dexie Cloud API
- Dexie Cloud API Limits
- Dexie Cloud Best Practices
- Dexie Cloud CLI
- Dexie Cloud Docs
- Dexie Cloud Quickstart
- Dexie Cloud Quickstart
- Dexie Cloud REST API
- Dexie Cloud Web Hooks
- Dexie Constructor
- Dexie.AbortError
- Dexie.BulkError
- Dexie.ConstraintError
- Dexie.DataCloneError
- Dexie.DataError
- Dexie.DatabaseClosedError
- Dexie.IncompatiblePromiseError
- Dexie.InternalError
- Dexie.InvalidAccessError
- Dexie.InvalidArgumentError
- Dexie.InvalidStateError
- Dexie.InvalidTableError
- Dexie.MissingAPIError
- Dexie.ModifyError
- Dexie.NoSuchDatabaseErrorError
- Dexie.NotFoundError
- Dexie.Observable
- Dexie.Observable.DatabaseChange
- Dexie.OpenFailedError
- Dexie.PrematureCommitError
- Dexie.QuotaExceededError
- Dexie.ReadOnlyError
- Dexie.SchemaError
- Dexie.SubTransactionError
- Dexie.Syncable
- Dexie.Syncable.IDatabaseChange
- Dexie.Syncable.IPersistentContext
- Dexie.Syncable.ISyncProtocol
- Dexie.Syncable.StatusTexts
- Dexie.Syncable.Statuses
- Dexie.Syncable.registerSyncProtocol()
- Dexie.TimeoutError
- Dexie.TransactionInactiveError
- Dexie.UnknownError
- Dexie.UnsupportedError
- Dexie.UpgradeError()
- Dexie.VersionChangeError
- Dexie.VersionError
- Dexie.[table]
- Dexie.addons
- Dexie.async()
- Dexie.backendDB()
- Dexie.close()
- Dexie.currentTransaction
- Dexie.debug
- Dexie.deepClone()
- Dexie.defineClass()
- Dexie.delByKeyPath()
- Dexie.delete()
- Dexie.derive()
- Dexie.events()
- Dexie.exists()
- Dexie.extend()
- Dexie.fakeAutoComplete()
- Dexie.getByKeyPath()
- Dexie.getDatabaseNames()
- Dexie.hasFailed()
- Dexie.ignoreTransaction()
- Dexie.isOpen()
- Dexie.js
- Dexie.name
- Dexie.on()
- Dexie.on.blocked
- Dexie.on.close
- Dexie.on.error
- Dexie.on.populate
- Dexie.on.populate-(old-version)
- Dexie.on.ready
- Dexie.on.storagemutated
- Dexie.on.versionchange
- Dexie.open()
- Dexie.override()
- Dexie.semVer
- Dexie.setByKeyPath()
- Dexie.shallowClone()
- Dexie.spawn()
- Dexie.table()
- Dexie.tables
- Dexie.transaction()
- Dexie.transaction()-(old-version)
- Dexie.use()
- Dexie.verno
- Dexie.version
- Dexie.version()
- Dexie.vip()
- Dexie.waitFor()
- DexieCloudOptions
- DexieError
- Docs Home
- Download
- EntityTable
- Export and Import Database
- Get started with Dexie Cloud
- Get started with Dexie in Angular
- Get started with Dexie in React
- Get started with Dexie in Svelte
- Get started with Dexie in Vue
- Hello World
- How To Use the StorageManager API
- Inbound
- IndexSpec
- Indexable Type
- IndexedDB on Safari
- Invite
- Member
- Migrating existing DB to Dexie
- MultiEntry Index
- PersistedSyncState
- Privacy Policy
- Promise
- Promise.PSD
- Promise.catch()
- Promise.finally()
- Promise.on.error
- Promise.onuncatched
- Questions and Answers
- Realm
- Releasing Dexie
- Road Map
- Road Map: Dexie 5.0
- Road Map: Dexie Cloud
- Role
- Run Dexie Cloud on Own Servers
- Sharding and Scalability
- Simplify with yield
- Support Ukraine
- SyncState
- Table
- Table Schema
- Table.add()
- Table.bulkAdd()
- Table.bulkDelete()
- Table.bulkGet()
- Table.bulkPut()
- Table.bulkUpdate()
- Table.clear()
- Table.count()
- Table.defineClass()
- Table.delete()
- Table.each()
- Table.filter()
- Table.get()
- Table.hook('creating')
- Table.hook('deleting')
- Table.hook('reading')
- Table.hook('updating')
- Table.limit()
- Table.mapToClass()
- Table.name
- Table.offset()
- Table.orderBy()
- Table.put()
- Table.reverse()
- Table.schema
- Table.toArray()
- Table.toCollection()
- Table.update()
- Table.upsert()
- Table.where()
- The main limitations of IndexedDB
- Transaction
- Transaction.abort()
- Transaction.on.abort
- Transaction.on.complete
- Transaction.on.error
- Transaction.table()
- Tutorial
- Typescript
- Typescript (old)
- Understanding the basics
- UserLogin
- Version
- Version.stores()
- Version.upgrade()
- WhereClause
- WhereClause.above()
- WhereClause.aboveOrEqual()
- WhereClause.anyOf()
- WhereClause.anyOfIgnoreCase()
- WhereClause.below()
- WhereClause.belowOrEqual()
- WhereClause.between()
- WhereClause.equals()
- WhereClause.equalsIgnoreCase()
- WhereClause.inAnyRange()
- WhereClause.noneOf()
- WhereClause.notEqual()
- WhereClause.startsWith()
- WhereClause.startsWithAnyOf()
- WhereClause.startsWithAnyOfIgnoreCase()
- WhereClause.startsWithIgnoreCase()
- Y.js
- db.cloud.configure()
- db.cloud.currentUser
- db.cloud.currentUserId
- db.cloud.events.syncComplete
- db.cloud.invites
- db.cloud.login()
- db.cloud.logout()
- db.cloud.options
- db.cloud.permissions()
- db.cloud.persistedSyncState
- db.cloud.roles
- db.cloud.schema
- db.cloud.sync()
- db.cloud.syncState
- db.cloud.userInteraction
- db.cloud.usingServiceWorker
- db.cloud.version
- db.cloud.webSocketStatus
- db.members
- db.realms
- db.roles
- db.syncable.connect()
- db.syncable.delete()
- db.syncable.disconnect()
- db.syncable.getOptions()
- db.syncable.getStatus()
- db.syncable.list()
- db.syncable.on('statusChanged')
- db.syncable.setFilter()
- dexie-cloud-addon
- dexie-react-hooks
- liveQuery()
- unhandledrejection-event
- useDocument()
- useLiveQuery()
- useObservable()
- usePermissions()
- y-dexie