Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5,219 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xNet

CI npm: @xnetjs/react Demo App License: MIT

xNet is a local-first workspace — documents, databases, and canvases that live on your device, sync everywhere, and belong to you. There is no account to create and no server in the middle: data is stored locally, synced peer-to-peer or through a hub you control, and signed with your own keys.

The xNet app: a document open in the workspace, with the explorer sidebar and live sync status

Try it

  • Open the demo — no signup; sign in with your device's passkey (Touch ID, Face ID, Windows Hello). Demo data lives in your browser, with encrypted backups on our demo hub (10MB, expires after 24 hours of inactivity).
  • Download the desktop app for permanent backups and reliable cross-device sync.
  • Deploy your own hub — an always-on relay and backup node that you run.

Alpha software. The @xnetjs/* packages, desktop app, and hub image all ship today — but APIs, schemas, and wire formats can still change between releases, sometimes without a migration path. Pin your versions, read the changelog before upgrading, and keep a backup you control (.xnetpack export is built in). Package version numbers are not a maturity signal; what is and isn't stable is written down in STABILITY.md.

Build with it

Everything in xNet is a node, and a schema describes what a node is:

import { defineSchema, text, number, select } from '@xnetjs/data'

const InvoiceSchema = defineSchema({
  name: 'Invoice',
  namespace: 'xnet://myapp/',
  document: 'yjs',
  properties: {
    title: text({ required: true }),
    amount: number(),
    status: select({
      options: [
        { id: 'draft', name: 'Draft' },
        { id: 'sent', name: 'Sent' },
        { id: 'paid', name: 'Paid' }
      ] as const
    })
  }
})

React hooks give you live queries, mutations, collaborative rich text, and permissions:

import { useQuery, useMutate, useNode, useIdentity, useCan, useGrants } from '@xnetjs/react'

// Structured data — live queries and writes
function TaskList() {
  const { data: tasks, loading } = useQuery(TaskSchema)
  const { create, update, remove } = useMutate()

  return (
    <ul>
      {tasks.map((task) => (
        <li key={task.id}>{task.title}</li>
      ))}
      <button onClick={() => create(TaskSchema, { title: 'New', status: 'todo' })}>Add</button>
    </ul>
  )
}

// Rich text — a synced Y.Doc per node
function PageEditor({ nodeId }: { nodeId: string }) {
  const { data: page, doc, syncStatus, peerCount } = useNode(PageSchema, nodeId)
  if (!doc) return null
  return <RichTextEditor ydoc={doc} />
}

// Identity and sharing — DIDs, permission checks, delegated grants
function SharingPanel({ nodeId }: { nodeId: string }) {
  const { did } = useIdentity()
  const { allowed: canShare } = useCan(nodeId, 'share')
  const { grant } = useGrants(nodeId)

  return (
    <button
      disabled={!canShare}
      onClick={() =>
        canShare && grant({ to: 'did:key:z6MkRecipient...', actions: ['read', 'write'] })
      }
    >
      Share as {did.slice(0, 16)}...
    </button>
  )
}

Under the hood: SQLite for storage (OPFS in the browser, native on desktop), Yjs CRDTs for rich text, an event-sourced change log for structured data, libp2p + WebRTC for peer-to-peer sync, and DID:key + UCAN for identity and sharing. The deep dives live in the docs.

An open protocol

This repository is one implementation of xNet. The protocol itself is an open standard you can re-implement in any language, over any database, and interoperate: see the normative spec, the conformance suite (golden vectors plus a second-language kernel), and xnet.fyi/docs/protocol. Independent implementations that pass conformance may call themselves "xNet-compatible" (how).

Develop

pnpm install
pnpm --filter xnet-web dev    # run the web app
pnpm dev:stories              # Storybook component catalog
pnpm build                    # build all packages
pnpm test                     # unit tests
pnpm typecheck && pnpm lint

The monorepo at a glance:

  • packages/ — the @xnetjs/* SDK packages, from crypto and storage up through React hooks, editor, views, and canvas
  • apps/ — Electron desktop, web PWA, and Expo mobile
  • site/ — the docs and landing site (Astro + Starlight)
  • tests/ — browser-based integration tests (Playwright)

Learn more

  • Vision — the big picture: micro-to-macro data sovereignty
  • Tradeoffs — why hybrid sync (Yjs + event sourcing)
  • Roadmap — the current six-month execution plan

Project

License

MIT — see LICENSE. The @xnetjs/cloud package is source-available under FSL-1.1-Apache-2.0 (converts to Apache-2.0 two years after each release).

About

Local-first infrastructure and app for user-owned data: offline-first sync, CRDT collaboration, typed schemas, and secure identity/permissions

Topics

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Contributors

Languages