Quick Start
Quick Start
DXOS is the developer platform for collaborative, local-first, privacy-preserving software. This guide shows how to use ECHO for peer-to-peer sync and HALO for decentralized identity.
DXOS works in any Node.js or Browser environment. There is a TypeScript API and a react
API.
In this guide
- Using with TypeScript.
- Using with React.
- Project templates.
- Deploy to Netlify.
Usage with TypeScript
DXOS can be used in both the node
and browser environments.
If you're using a browser environment, ensure you've set up your bundler to handle wasm
. Example vite config and project templates.
# If node-gyp fails during post-install, `brew install python-setuptools` before trying again.
npm install --save @dxos/client
Create and initialize a Client
:
import { Client } from '@dxos/client';
// create a client
const client = new Client();
const main = async () => {
await client.initialize();
// use client here
};
main();
An Options object can be passed to Client()
. See configuration examples.
Spaces are the main units of data storage and sharing (like collections
in other databases).
To begin manipulating data, use client.spaces.default
, or join or create a space.
See below for react
usage, otherwise see the TypeScript Guide.
Usage with React
Use @dxos/react-client
for react
hooks to access and manipulate data in ECHO and HALO.
npm install --save @dxos/react-client
Create a ClientProvider
to wrap your application. This allows nested components to use the hooks.
import React from 'react';
import { createRoot } from 'react-dom/client';
import { ClientProvider } from '@dxos/react-client';
import { useQuery, useSpaces } from '@dxos/react-client/echo';
import { useIdentity } from '@dxos/react-client/halo';
const createWorker = () =>
new SharedWorker(new URL('../shared-worker', import.meta.url), {
type: 'module',
name: 'dxos-client-worker',
});
const Component = () => {
// Get the user to log in before a space can be obtained.
const identity = useIdentity();
// Get the first available space, created with the identity.
const [space] = useSpaces();
// Grab everything in the space.
const objects = useQuery(space, {});
// Show the id of the first object returned.
return <>{objects[0]?.id}</>;
};
const App = () => (
<ClientProvider createWorker={createWorker}>
<Component />
</ClientProvider>
);
createRoot(document.body).render(<App />);
The SharedWorker
allows resources to be shared between tabs and windows. Put the following in a file called shared-worker.ts
in the same directory as your App
component above:
onconnect = async (event) => {
const { onconnect } = await import('@dxos/react-client/worker');
await onconnect(event);
};
Components will automatically re-render when the data changes. Change the data by mutating it as any regular JavaScript object.
For a step-by-step walkthrough, see the react tutorial.
Usage in a browser
DXOS recommends Vite as the bundler. Vite requires a plugin in order to serve the WebAssembly modules.
npm install --save vite-plugin-top-level-await vite-plugin-wasm
Add topLevelAwait
and wasm
to your vite.config.ts
:
//
// Copyright 2024 DXOS.org
//
import { defineConfig } from 'vite';
import topLevelAwait from 'vite-plugin-top-level-await';
import wasm from 'vite-plugin-wasm';
export default defineConfig({
plugins: [topLevelAwait(), wasm()],
worker: {
format: 'es',
plugins: [topLevelAwait(), wasm()],
},
});
Project templates
DXOS project templates are based on vite
, typescript
, react
, tailwind
, pwa
, and other opinions to get you going quickly.
Ensure node -v
is at version 18 or higher (recommend Node Version Manager).
Initialize an empty folder with npm create
like this:
npm create @dxos@latest
Note
If you encounter an error with EINVALIDPACKAGENAME
it's likely the npm/node versions are out of date. Ensure node -v
is 18 or higher and npm -v
is 9 or higher.
Then, use your favorite package manager such as yarn
, npm
or pnpm
:
cd <app-name>
npm install
npm run serve
This will start the development server and print a URL to the console. Opening two browser windows can demonstrate local state sync working:
Why this is cool:
- State is being reactively shared between all instances of the app running on the same device. If more peers join the space, all of them will see updates reactively.
- Data is stored locally, in-browser, in OPFS or IndexedDB. This enables privacy and gives end-users control over their data.
- Remote peers exchange data directly, peer-to-peer over secure WebRTC connections.
- User identity (public/private keys) are established securely and maintained by HALO for the whole device (browser profile), without a password.
- Everything works offline.
- Real-time collaboration is possible when online.
- There are no servers that store any data.
- There is no need for ORMs. ECHO objects are "plain javascript" objects that can be manipulated directly.
- There is no need for an API tier. The app has everything it needs on the client.
Deployment
By default DXOS template apps are static, Progressive Web Apps that work offline. They can be deployed with any regular static hosting technique like Netlify, Vercel, CloudFlare, GitHub Pages, an S3 bucket, and others.
The build command is npm run build
which produces a static bundle in the output folder out/<app-name>
, which can be changed in vite.config.ts
.
For example, with Netlify:
- Go to "Add new site", and click "Import an existing project."
- Link to your application's repository.
- Set the build command and output directory.
- Publish!
Next steps
- Step-by-step React tutorial
- ECHO with React
- ECHO with TypeScript
- ECHO with strongly typed objects
We hope you'll find the technology useful, and we welcome your ideas and contributions:
- Join the DXOS Discord
- DXOS repository on GitHub
- File a bug or idea in Issues
Happy building! ๐