Skip to main content

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

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 SharedWorkeropen in new window 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.

Usage in a browser

DXOS recommends Viteopen in new window 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:

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()],
  },
});