{"id":46447251,"url":"https://github.com/crs48/xnet","last_synced_at":"2026-07-11T22:00:41.531Z","repository":{"id":342364770,"uuid":"1140922447","full_name":"crs48/xNet","owner":"crs48","description":"Local-first infrastructure and app for user-owned data: offline-first sync, CRDT collaboration, typed schemas, and secure identity/permissions","archived":false,"fork":false,"pushed_at":"2026-07-09T02:56:26.000Z","size":209072,"stargazers_count":5,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-09T03:07:09.190Z","etag":null,"topics":["collaborative-editing","crdt","data-sovereignty","decentralized","did","electron","event-sourcing","libp2p","local-first","offline-first","p2p","passkeys","react","sqlite","sync","typescript","ucan","yjs"],"latest_commit_sha":null,"homepage":"https://xnet.fyi","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crs48.png","metadata":{"files":{"readme":"README.md","changelog":"changelog-full.jpeg","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":"GOVERNANCE.md","roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":"MAINTAINERS.md","copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"crs48","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"crs48","thanks_dev":null,"custom":null}},"created_at":"2026-01-23T23:50:53.000Z","updated_at":"2026-07-09T02:49:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"fb9d07c9-df55-4553-9a07-4a595d7a3487","html_url":"https://github.com/crs48/xNet","commit_stats":null,"previous_names":["crs48/xnet"],"tags_count":226,"template":false,"template_full_name":null,"purl":"pkg:github/crs48/xNet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crs48%2FxNet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crs48%2FxNet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crs48%2FxNet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crs48%2FxNet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crs48","download_url":"https://codeload.github.com/crs48/xNet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crs48%2FxNet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35376135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collaborative-editing","crdt","data-sovereignty","decentralized","did","electron","event-sourcing","libp2p","local-first","offline-first","p2p","passkeys","react","sqlite","sync","typescript","ucan","yjs"],"created_at":"2026-03-05T23:50:35.463Z","updated_at":"2026-07-11T22:00:41.524Z","avatar_url":"https://github.com/crs48.png","language":"TypeScript","funding_links":["https://github.com/sponsors/crs48","https://buymeacoffee.com/crs48"],"categories":[],"sub_categories":[],"readme":"# xNet\n\n[![CI](https://github.com/crs48/xNet/actions/workflows/ci.yml/badge.svg)](https://github.com/crs48/xNet/actions/workflows/ci.yml)\n[![npm: @xnetjs/react](https://img.shields.io/npm/v/@xnetjs/react?label=%40xnetjs%2Freact\u0026logo=npm)](https://www.npmjs.com/package/@xnetjs/react)\n[![Electron App](https://img.shields.io/github/actions/workflow/status/crs48/xNet/electron-release.yml?label=electron%20app\u0026logo=electron\u0026logoColor=white)](https://github.com/crs48/xNet/actions/workflows/electron-release.yml)\n[![Demo App](https://img.shields.io/github/actions/workflow/status/crs48/xNet/deploy-site.yml?label=demo%20app\u0026logo=react\u0026logoColor=white)](https://xnet.fyi/app)\n[![Hub Image](https://img.shields.io/github/actions/workflow/status/crs48/xNet/hub-release.yml?label=hub%20image\u0026logo=docker\u0026logoColor=white)](https://github.com/crs48/xNet/actions/workflows/hub-release.yml)\n[![Demo Hub](https://img.shields.io/endpoint?url=https%3A%2F%2Fhub.xnet.fyi%2Fhealth%2Fbadge\u0026logo=railway\u0026logoColor=white)](https://hub.xnet.fyi/health)\n[![Docs](https://img.shields.io/github/actions/workflow/status/crs48/xNet/deploy-site.yml?label=docs\u0026logo=astro\u0026logoColor=white)](https://xnet.fyi/docs)\n[![GitHub Stars](https://img.shields.io/github/stars/crs48/xNet?style=flat\u0026logo=github)](https://github.com/crs48/xNet/stargazers)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![pnpm](https://img.shields.io/badge/pnpm-monorepo-F69220?logo=pnpm\u0026logoColor=white)](https://pnpm.io/)\n[![Turborepo](https://img.shields.io/badge/Turborepo-powered-EF4444?logo=turborepo\u0026logoColor=white)](https://turbo.build/)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/crs48/xNet/pulls)\n\nDecentralized data infrastructure and application. Local-first, P2P-synced, user-owned data.\n\nxNet is both the underlying infrastructure and the user-facing app — one product, one brand. It starts with documents and databases, then expands via plugins to support ERP, MCP integrations, and more.\n\n\u003e **This repository is one implementation of xNet.** xNet is also an open\n\u003e **protocol** you can re-implement in any language, over any database, and\n\u003e interoperate. See [`docs/specs/protocol/`](./docs/specs/protocol/) (normative\n\u003e spec), [`conformance/`](./conformance/) (golden vectors + a second-language\n\u003e kernel), and [xnet.fyi/docs/protocol](https://xnet.fyi/docs/protocol/overview/).\n\n## Try It Now\n\n**[Try the demo at xnet.fyi/app](https://xnet.fyi/app)** — no signup required, just use your device's passkey (Touch ID, Face ID, Windows Hello).\n\n\u003e **Demo mode:** Your data is stored locally in your browser (local-first). Encrypted backups sync to our demo hub with a 10MB quota and expire after 24 hours of inactivity. For reliable cross-device sync and permanent backups, [download the desktop app](https://xnet.fyi/download).\n\n## Deploy a Hub\n\n[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/xnet-hub)\n\n## Getting Started\n\n```bash\n# Install dependencies\npnpm install\n\n# Run the root Storybook catalog and workbenches\npnpm dev:stories\n\n# Build the static Storybook site\npnpm build:stories\n\n# Build all packages\npnpm build\n\n# Run unit tests (~2400 tests across 148 test files)\npnpm test\n\n# Run integration tests (real browser via Playwright)\npnpm --filter @xnetjs/integration-tests test\n\n# Type check\npnpm typecheck\n\n# Lint\npnpm lint\n```\n\n## Component Development\n\nxNet now ships a root Storybook workspace for isolated component development across shared UI and app-facing surfaces.\n\n- Run `pnpm dev:stories` from the repo root to launch Storybook on `http://127.0.0.1:6006`.\n- Use `pnpm build:stories` to produce the static catalog and `pnpm test:stories` to run Storybook tests against a running server.\n- In Electron dev builds, open the embedded Storybook surface from `Open Stories` in the system menu or command palette.\n- In Web dev builds, open the embedded route at `/stories`.\n\nCurrent Storybook coverage includes:\n\n- `@xnetjs/ui` primitives, composed components, comments, settings, and devtools catalogs\n- `@xnetjs/editor` rich collaborative editor workbench\n- `@xnetjs/views` database surface workbench\n- `@xnetjs/canvas` canvas workbench\n- selected Electron and Web renderer stories\n\n## Monorepo Structure\n\n```\npackages/           # 21 core SDK packages (@xnetjs/*)\napps/               # Electron, Web, Expo applications\nsite/               # Astro + Starlight documentation website\ntests/              # Browser-based integration tests (Playwright)\ndocs/               # Vision, explorations, implementation plans\n```\n\nSee the README in each directory for details:\n\n- [packages/README.md](./packages/README.md) -- All 21 packages with dependency graph\n- [apps/README.md](./apps/README.md) -- Electron, Web, Expo apps\n- [tests/README.md](./tests/README.md) -- Integration test suite\n- [site/README.md](./site/README.md) -- Documentation website\n\n## Packages\n\n### Foundation\n\n| Package                                 | Description                                           |\n| --------------------------------------- | ----------------------------------------------------- |\n| [@xnetjs/core](./packages/core)         | Types, content addressing (CIDs), permissions, RBAC   |\n| [@xnetjs/crypto](./packages/crypto)     | BLAKE3 hashing, Ed25519 signing, XChaCha20 encryption |\n| [@xnetjs/identity](./packages/identity) | DID:key generation, UCAN tokens, passkey storage      |\n\n### Infrastructure\n\n| Package                               | Description                                                             |\n| ------------------------------------- | ----------------------------------------------------------------------- |\n| [@xnetjs/storage](./packages/storage) | SQLite/memory adapters, blob store, chunk manager, snapshots            |\n| [@xnetjs/sync](./packages/sync)       | Change\\\u003cT\\\u003e, Lamport clocks, hash chains, Yjs security layer            |\n| [@xnetjs/data](./packages/data)       | Schema system, NodeStore, 15 property types, Yjs CRDT, built-in schemas |\n| [@xnetjs/network](./packages/network) | libp2p node, y-webrtc provider, peer scoring, security suite            |\n| [@xnetjs/query](./packages/query)     | Local query engine, MiniSearch full-text search, federated router       |\n| [@xnetjs/hub](./packages/hub)         | Signaling server, sync relay, backup, FTS5 search, sharding, federation |\n\n### Application\n\n| Package                                   | Description                                                                    |\n| ----------------------------------------- | ------------------------------------------------------------------------------ |\n| [@xnetjs/react](./packages/react)         | useQuery, useMutate, useNode, hub hooks, plugin hooks, sync infrastructure     |\n| [@xnetjs/sdk](./packages/sdk)             | Unified client, browser/node presets, re-exports                               |\n| [@xnetjs/editor](./packages/editor)       | TipTap collaborative editor, slash commands, wikilinks, drag-drop, mermaid     |\n| [@xnetjs/ui](./packages/ui)               | Radix UI primitives, composed components, theme system, design tokens          |\n| [@xnetjs/views](./packages/views)         | Table, Board, Gallery, Timeline, Calendar views with property renderers        |\n| [@xnetjs/canvas](./packages/canvas)       | Infinite canvas, R-tree spatial indexing, ELK.js auto-layout, Yjs-backed store |\n| [@xnetjs/devtools](./packages/devtools)   | 9-panel debug suite (node explorer, sync monitor, Yjs inspector, ...)          |\n| [@xnetjs/history](./packages/history)     | Time machine, undo/redo, audit trails, blame, diff, verification               |\n| [@xnetjs/plugins](./packages/plugins)     | Plugin registry, sandboxed scripts, AI generation, MCP server, webhooks        |\n| [@xnetjs/telemetry](./packages/telemetry) | Privacy-preserving telemetry, tiered consent, k-anonymity, scrubbing           |\n| [@xnetjs/formula](./packages/formula)     | Expression parser, AST evaluator, built-in function library                    |\n| [@xnetjs/vectors](./packages/vectors)     | HNSW vector index, semantic search, hybrid keyword+semantic search             |\n\n## Apps\n\n| App                         | Tech                                                 | Description                   |\n| --------------------------- | ---------------------------------------------------- | ----------------------------- |\n| [Electron](./apps/electron) | Electron + Vite + React + TanStack Router + Tailwind | Desktop (macOS/Windows/Linux) |\n| [Web](./apps/web)           | Vite + React + TanStack Router + Workbox PWA         | Browser progressive web app   |\n| [Expo](./apps/expo)         | Expo SDK 52 + React Native + React Navigation        | Mobile (iOS/Android)          |\n\n## Architecture\n\n```mermaid\nflowchart TB\n    subgraph Apps[\"Applications\"]\n        Electron[\"Electron\u003cbr/\u003e(Desktop)\"]\n        Web[\"Web PWA\"]\n        Expo[\"Expo\u003cbr/\u003e(Mobile)\"]\n    end\n\n    subgraph UI[\"UI Layer\"]\n        Editor[\"@xnetjs/editor\u003cbr/\u003e\u003csmall\u003eTipTap, slash commands,\u003cbr/\u003edrag-drop, mermaid\u003c/small\u003e\"]\n        Views[\"@xnetjs/views\u003cbr/\u003e\u003csmall\u003eTable, Board, Calendar,\u003cbr/\u003eTimeline, Gallery\u003c/small\u003e\"]\n        Canvas[\"@xnetjs/canvas\u003cbr/\u003e\u003csmall\u003eInfinite canvas,\u003cbr/\u003eR-tree, ELK.js\u003c/small\u003e\"]\n        UILib[\"@xnetjs/ui\u003cbr/\u003e\u003csmall\u003eRadix primitives,\u003cbr/\u003etheme system\u003c/small\u003e\"]\n    end\n\n    subgraph Client[\"Client Layer\"]\n        React[\"@xnetjs/react\u003cbr/\u003e\u003csmall\u003euseQuery, useMutate,\u003cbr/\u003euseNode, SyncManager\u003c/small\u003e\"]\n        SDK[\"@xnetjs/sdk\u003cbr/\u003e\u003csmall\u003eUnified client,\u003cbr/\u003ebrowser/node presets\u003c/small\u003e\"]\n        Devtools[\"@xnetjs/devtools\u003cbr/\u003e\u003csmall\u003e9-panel debug suite\u003c/small\u003e\"]\n        Plugins[\"@xnetjs/plugins\u003cbr/\u003e\u003csmall\u003eRegistry, sandbox,\u003cbr/\u003eAI generation, MCP\u003c/small\u003e\"]\n        Telemetry[\"@xnetjs/telemetry\u003cbr/\u003e\u003csmall\u003ePrivacy-first,\u003cbr/\u003econsent-gated\u003c/small\u003e\"]\n        History[\"@xnetjs/history\u003cbr/\u003e\u003csmall\u003eTime machine,\u003cbr/\u003eundo/redo, audit\u003c/small\u003e\"]\n    end\n\n    subgraph Data[\"Data Layer\"]\n        DataPkg[\"@xnetjs/data\u003cbr/\u003e\u003csmall\u003eSchema system, NodeStore,\u003cbr/\u003eYjs CRDT, 15 property types\u003c/small\u003e\"]\n        Query[\"@xnetjs/query\u003cbr/\u003e\u003csmall\u003eLocal engine,\u003cbr/\u003eMiniSearch FTS\u003c/small\u003e\"]\n        Vectors[\"@xnetjs/vectors\u003cbr/\u003e\u003csmall\u003eHNSW index,\u003cbr/\u003ehybrid search\u003c/small\u003e\"]\n        Formula[\"@xnetjs/formula\u003cbr/\u003e\u003csmall\u003eExpression parser,\u003cbr/\u003ecomputed properties\u003c/small\u003e\"]\n    end\n\n    subgraph Infra[\"Infrastructure Layer\"]\n        Sync[\"@xnetjs/sync\u003cbr/\u003e\u003csmall\u003eChange\u0026lt;T\u0026gt;, Lamport clocks,\u003cbr/\u003ehash chains, Yjs security\u003c/small\u003e\"]\n        Storage[\"@xnetjs/storage\u003cbr/\u003e\u003csmall\u003eSQLite, blobs,\u003cbr/\u003esnapshots\u003c/small\u003e\"]\n        Network[\"@xnetjs/network\u003cbr/\u003e\u003csmall\u003elibp2p, y-webrtc,\u003cbr/\u003epeer scoring\u003c/small\u003e\"]\n    end\n\n    subgraph Foundation[\"Foundation\"]\n        Identity[\"@xnetjs/identity\u003cbr/\u003e\u003csmall\u003eDID:key, UCAN tokens,\u003cbr/\u003epasskey storage\u003c/small\u003e\"]\n        Crypto[\"@xnetjs/crypto\u003cbr/\u003e\u003csmall\u003eBLAKE3, Ed25519,\u003cbr/\u003eXChaCha20\u003c/small\u003e\"]\n        Core[\"@xnetjs/core\u003cbr/\u003e\u003csmall\u003eCIDs, types,\u003cbr/\u003epermissions, RBAC\u003c/small\u003e\"]\n    end\n\n    Apps --\u003e UI \u0026 Client\n    UI --\u003e Client\n    Client --\u003e Data\n    Data --\u003e Infra\n    Infra --\u003e Foundation\n\n    subgraph Server[\"Server\"]\n        Hub[\"@xnetjs/hub\u003cbr/\u003e\u003csmall\u003eSignaling, sync relay,\u003cbr/\u003ebackup, FTS5, federation\u003c/small\u003e\"]\n    end\n\n    Network \u003c--\u003e Hub\n```\n\n### Hybrid Sync Model\n\n```mermaid\nflowchart LR\n    subgraph Local[\"Local Device\"]\n        UI[\"UI\"]\n        NodeStore[\"NodeStore\u003cbr/\u003e(structured data)\"]\n        YDoc[\"Y.Doc\u003cbr/\u003e(rich text)\"]\n        DB[(\"SQLite\")]\n    end\n\n    subgraph Remote[\"Remote Peers\"]\n        Peer1[\"Peer\u003cbr/\u003e(desktop)\"]\n        Peer2[\"Peer\u003cbr/\u003e(mobile)\"]\n        HubNode[\"Hub\u003cbr/\u003e(always-on)\"]\n    end\n\n    UI --\u003e|\"mutate()\"| NodeStore\n    UI --\u003e|\"edit\"| YDoc\n    NodeStore --\u003e|\"Change\u0026lt;T\u0026gt;\u003cbr/\u003eLWW\"| DB\n    YDoc --\u003e|\"Yjs updates\u003cbr/\u003eCRDT\"| DB\n\n    Local \u003c--\u003e|\"WebRTC / WebSocket\"| Remote\n```\n\n## Data Model\n\nEverything is a **Node** (universal container). A **Schema** defines what the Node is.\n\n```typescript\nimport { defineSchema, text, number, select } from '@xnetjs/data'\n\nconst InvoiceSchema = defineSchema({\n  name: 'Invoice',\n  namespace: 'xnet://myapp/',\n  document: 'yjs',\n  properties: {\n    title: text({ required: true }),\n    amount: number(),\n    status: select({\n      options: [\n        { id: 'draft', name: 'Draft' },\n        { id: 'sent', name: 'Sent' },\n        { id: 'paid', name: 'Paid' }\n      ] as const\n    })\n  }\n})\n```\n\n### Sync Strategies\n\n| Data Type               | Sync Mechanism      | Conflict Resolution   |\n| ----------------------- | ------------------- | --------------------- |\n| Rich text (documents)   | Yjs CRDT            | Character-level merge |\n| Structured data (nodes) | NodeStore + Lamport | Field-level LWW       |\n\n### Identity, Roles, and Authorization\n\nxNet schemas can include an `authorization` block that maps **identity (DID)** to roles and actions.\n\n- **Identity:** Every node has `createdBy: did:key:...`\n- **Roles:** Resolved from creator, person properties, or related nodes\n- **Actions:** Canonical actions are `read`, `write`, `delete`, `share`, `admin`\n- **Delegation:** Grants (UCAN-backed) allow secure permission delegation\n\n```typescript\nconst ProjectDocSchema = defineSchema({\n  name: 'ProjectDoc',\n  namespace: 'xnet://myapp/',\n  document: 'yjs',\n  properties: {\n    title: text({ required: true }),\n    owner: person(),\n    editors: person(),\n    project: relation({ schema: 'xnet://myapp/Project@1.0.0' })\n  },\n  authorization: {\n    roles: {\n      owner: role.creator(),\n      editor: role.property('editors'),\n      projectAdmin: role.relation('project', 'admin')\n    },\n    actions: {\n      read: allow('owner', 'editor', 'projectAdmin'),\n      write: allow('owner', 'editor', 'projectAdmin'),\n      delete: allow('owner', 'projectAdmin'),\n      share: allow('owner', 'projectAdmin'),\n      admin: allow('projectAdmin')\n    },\n    publicProps: ['title']\n  }\n})\n```\n\n\u003e Authorization builders (`allow`, `role`, etc.) come from the data auth module and compile to schema-level policy metadata.\n\n## Primary React Hooks\n\n```tsx\nimport { useQuery, useMutate, useNode, useIdentity, useCan, useGrants } from '@xnetjs/react'\n\n// Structured data\nfunction TaskList() {\n  const { data: tasks, loading } = useQuery(TaskSchema)\n  const { create, update, remove } = useMutate()\n\n  return (\n    \u003cul\u003e\n      {tasks.map((task) =\u003e (\n        \u003cli key={task.id}\u003e{task.title}\u003c/li\u003e\n      ))}\n      \u003cbutton onClick={() =\u003e create(TaskSchema, { title: 'New', status: 'todo' })}\u003eAdd\u003c/button\u003e\n    \u003c/ul\u003e\n  )\n}\n\n// Rich text with Yjs CRDT\nfunction PageEditor({ nodeId }: { nodeId: string }) {\n  const { data: page, doc, syncStatus, peerCount } = useNode(PageSchema, nodeId)\n  if (!doc) return null\n  return \u003cRichTextEditor ydoc={doc} /\u003e\n}\n\n// Identity + permissions\nfunction SharingPanel({ nodeId }: { nodeId: string }) {\n  const { did } = useIdentity()\n  const { allowed: canShare } = useCan(nodeId, 'share')\n  const { grant } = useGrants(nodeId)\n\n  return (\n    \u003cbutton\n      disabled={!canShare}\n      onClick={() =\u003e\n        canShare \u0026\u0026 grant({ to: 'did:key:z6MkRecipient...', actions: ['read', 'write'] })\n      }\n    \u003e\n      Share as {did.slice(0, 16)}...\n    \u003c/button\u003e\n  )\n}\n```\n\n### Hook Quick Reference\n\n| Hook          | Use for                                          |\n| ------------- | ------------------------------------------------ |\n| `useQuery`    | Read lists/single nodes with realtime updates    |\n| `useMutate`   | Create/update/delete/transactional writes        |\n| `useNode`     | Rich text nodes (`Y.Doc`), sync status, presence |\n| `useIdentity` | Current DID identity context                     |\n| `useCan`      | Check action permissions on a node               |\n| `useCanEdit`  | Quick editable state for UI gating               |\n| `useGrants`   | Grant, revoke, and inspect delegated access      |\n\n## Key Technologies\n\n| Layer      | Technology                                         |\n| ---------- | -------------------------------------------------- |\n| Sync       | Event-sourced immutable logs, Lamport clocks, LWW  |\n| CRDT       | Yjs (conflict-free collaboration)                  |\n| P2P        | libp2p + WebRTC                                    |\n| Storage    | SQLite (OPFS in browser, native on desktop/mobile) |\n| Identity   | DID:key + UCAN authorization                       |\n| Signing    | Ed25519 (via @noble/curves)                        |\n| Hashing    | BLAKE3 (via @noble/hashes)                         |\n| Encryption | XChaCha20-Poly1305                                 |\n| Search     | MiniSearch (local), FTS5 (hub)                     |\n| Build      | Turborepo, tsup, Vite                              |\n| Testing    | Vitest, Playwright (browser mode)                  |\n\n## Roadmap Status (Mar 2026)\n\n| Phase   | Focus                                                                           | Status      |\n| ------- | ------------------------------------------------------------------------------- | ----------- |\n| Phase 1 | Product reliability (navigation, search, daily-driver polish)                   | In progress |\n| Phase 2 | Collaboration + trust (invites, sharing UX, presence reliability)               | Next        |\n| Phase 3 | Platform clarity (package lifecycle, API simplification, multi-hub integration) | Planned     |\n\nSee [`docs/ROADMAP.md`](./docs/ROADMAP.md) for the detailed execution plan.\n\n## Documentation\n\n- [Site](./site) -- Astro + Starlight documentation website\n- [Protocol Spec](./docs/specs/protocol/) -- the normative, re-implementable standard (L0–L3 + conformance corpus)\n- [Vision](./docs/VISION.md) -- The big picture: micro-to-macro data sovereignty\n- [Tradeoffs](./docs/TRADEOFFS.md) -- Why hybrid sync (Yjs + event sourcing)\n- [Roadmap](./docs/ROADMAP.md) -- current 6-month execution plan (Mar-Sep 2026)\n\n## Project\n\n- [Governance](./GOVERNANCE.md) · [Trademark \u0026 Brand](./TRADEMARK.md) · [Code of Conduct](./CODE_OF_CONDUCT.md) · [Charter](./docs/CHARTER.md) · [Maintainers](./MAINTAINERS.md)\n- Contributions use the [DCO](https://developercertificate.org/) (`git commit -s`) — no CLA. See [CONTRIBUTING.md](./CONTRIBUTING.md).\n- The code is MIT (core) / FSL (`@xnetjs/cloud`). The **xNet** name and logo are trademarks — see the [trademark policy](./TRADEMARK.md). Independent implementations that pass the [conformance suite](./conformance) may call themselves **\"xNet-compatible\"** ([how](./docs/COMPATIBILITY.md)).\n\n## License\n\nMIT — see [`LICENSE`](./LICENSE). The `@xnetjs/cloud` package is source-available under\n[FSL-1.1-Apache-2.0](./packages/cloud/LICENSE) (converts to Apache-2.0 two years after\neach release).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrs48%2Fxnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrs48%2Fxnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrs48%2Fxnet/lists"}