├── pnpm-workspace.yaml ├── .gitignore ├── landscape-schema ├── src │ └── mod.ts ├── package.json └── tsconfig.json ├── temporary-technology-info ├── ditto │ ├── logo.dark.png │ ├── logo.light.png │ ├── details.md │ └── data.js ├── package.json └── validate.js ├── landscape-content-snapshot ├── src │ └── generated │ │ ├── automerge │ │ ├── logo.dark.png │ │ ├── logo.light.png │ │ ├── details.md │ │ └── data.json │ │ ├── y-sweet │ │ ├── logo.dark.png │ │ ├── logo.light.png │ │ ├── details.md │ │ └── data.json │ │ ├── liveblocks-yjs │ │ ├── logo.dark.png │ │ ├── logo.light.png │ │ ├── details.md │ │ └── data.json │ │ ├── liveblocks-storage │ │ ├── logo.dark.png │ │ ├── logo.light.png │ │ ├── details.md │ │ └── data.json │ │ ├── ambient.d.ts │ │ ├── yjs │ │ ├── details.md │ │ ├── data.json │ │ ├── logo.light.svg │ │ └── logo.dark.svg │ │ ├── instant │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── electricsql │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── data.json │ │ └── details.md │ │ ├── rxdb │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ ├── jazz │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ ├── basic │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── tinybase │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── zero │ │ ├── details.md │ │ ├── logo.dark.svg │ │ └── logo.light.svg │ │ ├── triplit │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── convex │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── dxos │ │ ├── logo.light.svg │ │ ├── logo.dark.svg │ │ ├── details.md │ │ └── data.json │ │ ├── pouchdb │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ ├── powersync │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ ├── livestore │ │ ├── logo.light.svg │ │ ├── logo.dark.svg │ │ ├── details.md │ │ └── data.json │ │ ├── nextgraph │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ ├── ditto │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ ├── details.md │ │ └── data.json │ │ ├── couchdb │ │ ├── details.md │ │ ├── logo.dark.svg │ │ ├── logo.light.svg │ │ └── data.json │ │ └── loro │ │ ├── details.md │ │ └── data.json ├── package.json └── tsconfig.json ├── tsconfig.all.json ├── package.json ├── landscape-fetch-content ├── package.json ├── tsconfig.json └── src │ └── repos.ts ├── .github └── workflows │ └── generate-content-snapshot.yml └── README.md /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - '*' 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .vercel 4 | 5 | dist -------------------------------------------------------------------------------- /landscape-schema/src/mod.ts: -------------------------------------------------------------------------------- 1 | export * from './schema.js' 2 | -------------------------------------------------------------------------------- /temporary-technology-info/ditto/logo.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/temporary-technology-info/ditto/logo.dark.png -------------------------------------------------------------------------------- /temporary-technology-info/ditto/logo.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/temporary-technology-info/ditto/logo.light.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/automerge/logo.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/automerge/logo.dark.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/y-sweet/logo.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/y-sweet/logo.dark.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/y-sweet/logo.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/y-sweet/logo.light.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/automerge/logo.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/automerge/logo.light.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-yjs/logo.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/liveblocks-yjs/logo.dark.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-yjs/logo.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/liveblocks-yjs/logo.light.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-storage/logo.dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/liveblocks-storage/logo.dark.png -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-storage/logo.light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/localfirstfm/local-first-landscape/HEAD/landscape-content-snapshot/src/generated/liveblocks-storage/logo.light.png -------------------------------------------------------------------------------- /tsconfig.all.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [], 3 | "references": [ 4 | { "path": "./landscape-schema" }, 5 | { "path": "./landscape-fetch-content" }, 6 | { "path": "./landscape-content-snapshot" } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/ambient.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | const content: any 3 | export default content 4 | } 5 | 6 | declare module '*.png' { 7 | const content: any 8 | export default content 9 | } 10 | -------------------------------------------------------------------------------- /temporary-technology-info/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@localfirstfm/temporary-technology-info", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "dependencies": { 6 | "@localfirstfm/landscape-schema": "workspace:*" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/yjs/details.md: -------------------------------------------------------------------------------- 1 | # Yjs 2 | 3 | Sponsors-backed project for making anything on the web collaborative. Connect 4 | with us to build cool integrations. 5 | 6 | Visit [yjs.dev](https://yjs.dev) for more information. 7 | 8 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/instant/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/instant/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/y-sweet/details.md: -------------------------------------------------------------------------------- 1 | ## General 2 | 3 | Y-Sweet is an open-source Yjs server that uses S3(-compatible) object storage for persistence. 4 | 5 | ## Resources 6 | 7 | - [Website](https://y-sweet.dev) 8 | - [Documentation](https://docs.jamsocket.com/y-sweet) 9 | -------------------------------------------------------------------------------- /landscape-content-snapshot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@localfirstfm/landscape-content-snapshot", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "private": true, 6 | "dependencies": { 7 | "effect": "3.12.0", 8 | "@localfirstfm/landscape-schema": "workspace:*" 9 | }, 10 | "devDependencies": { 11 | "typescript": "^5.7.2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/electricsql/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/electricsql/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@localfirstfm/landscape-mono", 3 | "private": true, 4 | "scripts": { 5 | "build:ts": "tsc --build tsconfig.all.json", 6 | "generate:content-snapshot": "pnpm --filter @localfirstfm/landscape-fetch-content exec bun ./src/cli.ts --target-dir=../landscape-content-snapshot/src/generated --override-target-dir" 7 | }, 8 | "devDependencies": { 9 | "typescript": "^5.7.2", 10 | "@biomejs/biome": "1.9.4" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/rxdb/details.md: -------------------------------------------------------------------------------- 1 | # SuperSync 2 | 3 | SuperSync is a cool way to sync your data. 4 | 5 | ## Features 6 | 7 | - **SuperSync**: Sync your data with ease. 8 | - **Local-first**: Your data is stored locally, ensuring privacy and security. 9 | - **Cross-platform**: Works on all major platforms. 10 | - **Open-source**: The code is available for anyone to use and contribute to. 11 | - **Community-driven**: Join our community and help us improve the project. 12 | 13 | ## More info 14 | 15 | ... 16 | -------------------------------------------------------------------------------- /landscape-schema/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@localfirstfm/landscape-schema", 3 | "version": "0.0.2", 4 | "type": "module", 5 | "exports": { 6 | ".": { 7 | "types": "./dist/mod.d.ts", 8 | "default": "./dist/mod.js" 9 | } 10 | }, 11 | "types": "./dist/mod.d.ts", 12 | "files": ["dist", "src"], 13 | "scripts": { 14 | "build": "tsc" 15 | }, 16 | "dependencies": {}, 17 | "peerDependencies": { 18 | "effect": "3.12.x" 19 | }, 20 | "devDependencies": { 21 | "effect": "3.12.0", 22 | "typescript": "^5.7.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/jazz/details.md: -------------------------------------------------------------------------------- 1 | # Jazz 2 | 3 | ## Toolkit for backendless apps. 4 | 5 | Jazz gives you data without needing a database — plus auth, permissions, files and multiplayer without needing a backend. 6 | 7 | Do everything right from the frontend and ship better apps, faster. 8 | 9 | Open source. Self-host or use Jazz Cloud for zero-config magic. 10 | 11 | ## Features 12 | 13 | - Instant updates 14 | - Real-time sync 15 | - Multiplayer 16 | - File uploads 17 | - Social features 18 | - Permissions 19 | - E2E encryption 20 | - Authentication 21 | 22 | Find out how it works and more details at [jazz.tools](https://jazz.tools) 23 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/basic/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/basic/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/tinybase/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 8 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/tinybase/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 8 | -------------------------------------------------------------------------------- /landscape-fetch-content/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@localfirstfm/landscape-fetch-content", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "private": true, 6 | "scripts": { 7 | "build": "tsc", 8 | "fetch-content": "bun src/cli.ts --target-dir ../landscape-content-snapshot/src/generated" 9 | }, 10 | "exports": { 11 | "./repos": "./src/repos.ts" 12 | }, 13 | "dependencies": { 14 | "@localfirstfm/landscape-schema": "workspace:*", 15 | "effect": "3.12.0", 16 | "@effect/cli": "0.51.0", 17 | "@effect/platform": "0.72.0", 18 | "@effect/platform-node": "0.68.0" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "22.10.2", 22 | "typescript": "^5.7.2" 23 | } 24 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/zero/details.md: -------------------------------------------------------------------------------- 1 | # Zero 2 | 3 | Zero is a general-purpose sync engine for the web. 4 | 5 | You put Zero in front of your database or web service, and we distribute your backend all the way to main thread of the UI. You get a client-side API that _looks_ like an embedded db, but to which you can issue arbitrary _hybrid queries_ that span the entire database, including the server. 6 | 7 | ![code sample](https://i.imgur.com/dfdeD7y.png) 8 | 9 | Behind the scenes, we synchronize queries results continuously to a client-side persistent cache. This cache is used automatically for future queries whenever possible. 10 | 11 | ## More info 12 | 13 | To learn more, see [zerosync.dev](https://zerosync.dev/). 14 | -------------------------------------------------------------------------------- /temporary-technology-info/validate.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { readdir } from 'node:fs/promises' 3 | import { join } from 'node:path' 4 | 5 | const directories = [ 6 | 'y-sweet', 7 | 'zero', 8 | 'jazz', 9 | 'liveblocks-storage', 10 | 'powersync', 11 | 'triplit', 12 | 'convex', 13 | 'electricsql', 14 | 'automerge', 15 | 'basicdb', 16 | 'ditto', 17 | 'dxos', 18 | 'liveblocks-yjs', 19 | ] 20 | 21 | async function validateAll() { 22 | for (const dir of directories) { 23 | try { 24 | const module = await import(`./${dir}/data.js`) 25 | console.log(`✓ ${dir} validated successfully`) 26 | } catch (error) { 27 | console.error(`✗ Error in ${dir}:`, error.message) 28 | } 29 | } 30 | } 31 | 32 | validateAll() 33 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/rxdb/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/rxdb/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/zero/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/zero/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-schema/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "target": "es2022", 7 | "allowJs": true, 8 | "moduleDetection": "force", 9 | "isolatedModules": true, 10 | "verbatimModuleSyntax": true, 11 | /* Strictness */ 12 | "strict": true, 13 | "noUncheckedIndexedAccess": true, 14 | "noImplicitOverride": true, 15 | /* If transpiling with TypeScript: */ 16 | "module": "NodeNext", 17 | "sourceMap": true, 18 | /* AND if you're building for a library: */ 19 | "declaration": true, 20 | /* If your code doesn't run in the DOM: */ 21 | "lib": ["es2022", "dom"], 22 | "rootDir": "./src", 23 | "outDir": "./dist", 24 | "tsBuildInfoFile": "./dist/.tsbuildinfo", 25 | "incremental": true, 26 | "composite": true 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-yjs/details.md: -------------------------------------------------------------------------------- 1 | # Liveblocks 2 | 3 | [Liveblocks](https://liveblocks.io) provides customizable pre-built features for human and AI collaboration, used to make your product multiplayer, engaging, and AI‑ready. All without derailing your roadmap. 4 | 5 | ## Liveblocks Yjs 6 | 7 | [Liveblocks Yjs](https://liveblocks.io/sync-datastore/yjs) is a realtime sync engine designed for building collaborative text editors such as Notion and Google Docs. Liveblocks permanently stores Yjs data in each room, handling scaling and maintenance for you. 8 | 9 | ### Links 10 | 11 | - [Get started](https://liveblocks.io/docs/get-started/text-editor) 12 | - [API reference](https://liveblocks.io/docs/api-reference/liveblocks-yjs) 13 | - [Examples](https://liveblocks.io/examples) 14 | - [More info](https://liveblocks.io/docs/platform/sync-datastore/liveblocks-yjs) 15 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/triplit/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/triplit/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/convex/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/convex/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /landscape-fetch-content/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "target": "es2022", 7 | "allowJs": true, 8 | "moduleDetection": "force", 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "verbatimModuleSyntax": true, 12 | /* Strictness */ 13 | "strict": true, 14 | "noUncheckedIndexedAccess": true, 15 | "noImplicitOverride": true, 16 | /* If transpiling with TypeScript: */ 17 | "module": "NodeNext", 18 | "moduleResolution": "NodeNext", 19 | "sourceMap": true, 20 | /* AND if you're building for a library: */ 21 | "declaration": true, 22 | /* If your code doesn't run in the DOM: */ 23 | "lib": ["es2022", "dom"], 24 | "rootDir": "./src", 25 | "outDir": "./dist", 26 | "tsBuildInfoFile": "./dist/.tsbuildinfo", 27 | "incremental": true, 28 | "composite": true 29 | }, 30 | "include": ["src/**/*.ts"] 31 | } 32 | -------------------------------------------------------------------------------- /landscape-content-snapshot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options: */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "target": "es2022", 7 | "allowJs": true, 8 | "moduleDetection": "force", 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "verbatimModuleSyntax": true, 12 | /* Strictness */ 13 | "strict": true, 14 | "noUncheckedIndexedAccess": true, 15 | "noImplicitOverride": true, 16 | /* If transpiling with TypeScript: */ 17 | "module": "NodeNext", 18 | "moduleResolution": "NodeNext", 19 | "sourceMap": true, 20 | /* AND if you're building for a library: */ 21 | "declaration": true, 22 | /* If your code doesn't run in the DOM: */ 23 | "lib": ["es2022"], 24 | "rootDir": "./src", 25 | "outDir": "./dist", 26 | "tsBuildInfoFile": "./dist/.tsbuildinfo", 27 | "incremental": true, 28 | "composite": true 29 | }, 30 | "include": ["src", "src/**/*.json"] 31 | } 32 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/dxos/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-storage/details.md: -------------------------------------------------------------------------------- 1 | # Liveblocks 2 | 3 | [Liveblocks](https://liveblocks.io) provides customizable pre-built features for human and AI collaboration, used to make your product multiplayer, engaging, and AI‑ready. All without derailing your roadmap. 4 | 5 | ## Liveblocks Storage 6 | 7 | [Liveblocks Storage](https://liveblocks.io/sync-datastore/storage) is a realtime sync engine designed for multiplayer creative tools such as Figma, Pitch, and Spline. `LiveList`, `LiveMap`, and `LiveObject` conflict-free data types can be used to build all sorts of multiplayer tools. Liveblocks permanently stores Storage data in each room, handling scaling and maintenance for you. 8 | 9 | ### Links 10 | 11 | - [Get started](https://liveblocks.io/docs/get-started/custom) 12 | - [API reference](https://liveblocks.io/docs/api-reference/liveblocks-client#Storage) 13 | - [Examples](https://liveblocks.io/examples) 14 | - [More info](https://liveblocks.io/docs/platform/sync-datastore/liveblocks-storage) -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/dxos/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/triplit/details.md: -------------------------------------------------------------------------------- 1 | # Triplit 2 | 3 | Triplit is the database that's in sync with your front-end. 4 | 5 | ## Get Started with Triplit Cloud or Self-Hosted today 6 | 7 | Website: [https://triplit.dev](https://triplit.dev) 8 | Github: [aspen-cloud/triplit](https://github.com/aspen-cloud/triplit) 9 | 10 | ## Features 11 | 12 | 🔄 Real-time sync with incremental updates and conflict resolution at the property level 13 | 🏠 Local caching powered by a full-fledged client-side database 14 | 💽 Durable server-side storage with an admin dashboard 15 | 😃 Optimistic updates to make every interaction feel fast 16 | 🔗 Relational querying for complex data models 17 | 🛫 Offline-mode with automatic reconnection and consistency guarantees 18 | 🔙 Rollback and retry management on failed updates 19 | 🗂️ Schemas for data safety and Typescript autocompletion 20 | 🔐 Authorization with row level granularity 21 | 🤝 Collaboration/Multiplayer powered by CRDTs 22 | 🏎️ Low latency with minimal network traffic using delta patches 23 | 📝 Simple API for querying and mutating data in both vanilla Javascript and frameworks like React 24 | -------------------------------------------------------------------------------- /temporary-technology-info/ditto/details.md: -------------------------------------------------------------------------------- 1 | ## General 2 | 3 | Lorem ipsum dolor sit amet consectetur. Penatibus viverra quam massa leo suspendisse. Est porttitor donec integer luctus sed sed ipsum in adipiscing. Nunc pharetra lacus iaculis tristique penatibus dolor sit. 4 | 5 | ![Architecture diagram](https://i.imgur.com/xCOK0b7.jpeg) 6 | 7 | ## The Story 8 | 9 | Lorem ipsum dolor sit amet consectetur. Penatibus viverra quam massa leo suspendisse. Est porttitor donec integer luctus sed sed ipsum in adipiscing. Nunc pharetra lacus iaculis tristique penatibus dolor sit. Lorem ipsum dolor sit amet consectetur. Penatibus viverra quam massa leo suspendisse. Est porttitor donec integer luctus sed sed ipsum in adipiscing. Nunc pharetra lacus iaculis tristique penatibus dolor sit. Lorem ipsum dolor sit amet consectetur. Penatibus viverra quam massa leo suspendisse. Est porttitor donec integer luctus sed sed ipsum in adipiscing. Nunc pharetra lacus iaculis tristique penatibus dolor sit. 10 | 11 | ## Resources 12 | 13 | Lorem ipsum dolor sit amet consectetur. Penatibus viverra quam massa leo suspendisse. 14 | 15 | - [Website](https://ditto.live) 16 | - [Documentation](https://docs.ditto.live/home/introduction) 17 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/dxos/details.md: -------------------------------------------------------------------------------- 1 | # DXOS 2 | 3 | The new standard for building collaborative local-first software. 4 | 5 | DXOS is an open source framework for building real-time, collaborative web applications that run entirely on the client and communicate peer-to-peer, without the need for centralized servers. 6 | 7 | To show off the power of DXOS, we've built [Composer](https://dxos.org/composer). A local-first workspace that is designed for small team collaboration. 8 | 9 | ## Features 10 | 11 | - **Client-side databases that scale**: ECHO is an open source database architecture that incorporates transparent data replication and conflict resolution for secure and scalable local storage. 12 | - **Seamless Public/Private key identities**: HALO seamlessly manages digital identities using public/private key pairs allowing nuanced control over access to applications, databases, and networked devices. 13 | - **Performant Peer-to-Peer networks**: MESH extends existing internet protocols to enable secure and resilient peer-to-peer networks without the need for centralized server infrastructure. 14 | - **Seamless Collaboration**: Add realtime collaboration to your local-first application without the complexity of building your own sync engine. 15 | 16 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/pouchdb/details.md: -------------------------------------------------------------------------------- 1 | # PouchDB 2 | 3 | [Apache® PouchDB](https://pouchdb.com/) is the open-source, in-browser JavaScript database that lets you save data locally, so you can keep going regardless of network coverage. 4 | 5 | It’s the sibling technology of [CouchDB](https://couchdb.apache.org/), and pairs with it to save data locally and then sync when your device re-establishes internet connectivity. 6 | 7 | ## Use Cases 8 | 9 | - **Healthcare workers in a place with patchy Internet:**: PouchDB gives high-fidelity access to your patients’ data well keeping it secure. 10 | - **Field technicians repairing critical infrastructure:**: PouchDB keeps track of work orders and collects all field info, including photos. 11 | - **First responders working in a disaster area**: PouchDB coordinates relief efforts on the ground without getting in the way. 12 | 13 | ## Key Advantages 14 | 15 | - **Open, proven, well-specified replication**: Build with flexibility and confidence thanks to PouchDB and CouchDB’s refined, battle-hardened and publicly spec’d replication protocol. 16 | - **Doesn't lose data on conflicts**: Enjoy full control over conflict resolution logic unlike last-write-wins, PouchDB won't lose any writes and is more flexible than CRDTs. 17 | - **Bring your own architecture**: Build upon flexible date topology. Use PouchDB for P2P, client-server and multi-primary scenarios or as a local cache. 18 | 19 | ## Getting Started 20 | 21 | - [Website](https://pouchdb.com/) 22 | - [Documentation](https://pouchdb.com/api.html) 23 | - [Github](https://github.com/pouchdb/pouchdb) 24 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/convex/details.md: -------------------------------------------------------------------------------- 1 | # Convex 2 | 3 | [Convex](https://convex.dev) is the open-source reactive database designed to 4 | make life easy for web app developers, whether human or LLM. Fetch data and 5 | perform business logic with strong consistency by writing pure TypeScript. 6 | 7 | Convex provides a database, a place to write your server functions, and client 8 | libraries. It makes it easy to build and scale dynamic live-updating apps. 9 | [Read the docs to learn more](https://docs.convex.dev/understanding/). 10 | 11 | ## Features 12 | 13 | - **Functions**: Functions run on the backend and are written in JavaScript (or TypeScript). They are automatically available as APIs accessed through client libraries. Queries read data from the Convex database and are automatically cached and reactive. Mutations transactionally write to the database. Actions call external APIs. 14 | - **Database**: The Convex database provides a relational data model, stores JSON-like documents, and can be used with or without a schema. It "just works," giving you predictable query performance in an easy-to-use interface. 15 | - **Authentication**: Convex has built-in authentication and also supports integrating with any other OpenID Connect authentication provider. 16 | - **Scheduling**: Run a function one or repeatedly in the feature, composing Convex functions into durable workflows. 17 | - **File Storage**: Store and retrieve files of all file types in built-in file storage. 18 | - **Search**: Add text or vector indexes to search over data in your Convex database. 19 | - **Dashboard**: View your Convex deployment's data, functions, and logs in our built-in dashboard. -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/instant/details.md: -------------------------------------------------------------------------------- 1 | # Instant 2 | 3 | Instant is a modern Firebase. We make you productive by giving your frontend a real-time database. 4 | 5 | You write [relational queries](https://www.instantdb.com/docs/instaql) in the shape of the data you want and Instant handles all the data fetching, permission checking, and offline caching. When you [change data](https://www.instantdb.com/docs/instaml), optimistic updates and rollbacks are handled for you as well. Plus, every query is multiplayer by default. 6 | 7 | We also support [ephemeral](https://www.instantdb.com/docs/presence-and-topics) updates, like cursors, or who's online. Currently we have SDKs for [Javascript](https://www.instantdb.com/docs/start-vanilla), [React](https://www.instantdb.com/docs/), and [React Native](https://www.instantdb.com/docs/start-rn). 8 | 9 | How does it look? Here's a barebones chat app in about 12 lines: 10 | 11 | ```javascript 12 | // ༼ つ ◕_◕ ༽つ Real-time Chat 13 | // ---------------------------------- 14 | // * Updates instantly 15 | // * Multiplayer 16 | // * Works offline 17 | 18 | import { init, tx, id } from "@instantdb/react"; 19 | 20 | const db = init({ 21 | appId: process.env.NEXT_PUBLIC_APP_ID, 22 | }); 23 | 24 | function Chat() { 25 | // 1. Read 26 | const { isLoading, error, data } = db.useQuery({ 27 | messages: {}, 28 | }); 29 | 30 | // 2. Write 31 | const addMessage = (message) => { 32 | db.transact(tx.messages[id()].update(message)); 33 | }; 34 | 35 | // 3. Render! 36 | return ; 37 | } 38 | ``` 39 | 40 | Want to see for yourself? try a demo in your browser. 41 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/automerge/details.md: -------------------------------------------------------------------------------- 1 | # Automerge 2 | 3 | [Get Started](https://automerge.org/docs/quickstart/) 4 | 5 | --- 6 | 7 | Automerge is a toolkit which makes building collaborative, local first applications which don't depend on servers feel as easy as building local only prototypes. We do this by thinking of the problem of local first collaboration as a version control problem - every peer has a different version of the data and Automerge provides tools to easily synchronise different versions, examine, history, and merge changes. 8 | 9 | This gives us a number of benefits: 10 | 11 | ### Network Topology Agnosticism 12 | 13 | Every peer is the same, there is no special server/client relationship. This means that you can use a sync server - just a very available peer - and opportunistically use peer to peer connections when available. It also means that sync servers are fungible, you can run one, your users can run one, etc. 14 | 15 | ### Local first 16 | 17 | You always have a full local copy of the data, and local reads and writes are always committed instantly. If your sync server is unavailable, that's fine, you'll merge when you reconnect - or even just when you connect to a _different_ sync server. 18 | 19 | ### Rich change history 20 | 21 | Automerge tracks very fine grained (typically per keystroke) and rich (native representations for maps, lists, and rich text) changes. This allows us to avoid most conflicts, and provide good APIs for conflict resolution. It also means that you can always examine any part of the history of the document to review changes. 22 | 23 | ### Unified collaboration model 24 | 25 | Because of the rich change history Automerge tracks, the programming model for synchronous real-time collaboration, and asynchronous "I was working from a cabin in the woods for a week" collaboration is the same. 26 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/jazz/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/jazz/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/tinybase/details.md: -------------------------------------------------------------------------------- 1 | # TinyBase 2 | 3 | A reactive& sync. 4 | 5 | Get started 6 | 7 | Try the demos 8 | 9 | Read the docs 10 | 11 | --- 12 | 13 | ## It's _Reactive_ 14 | 15 | TinyBase lets you listen to changes made to any part of your data. This means 16 | your app will be fast, since you only spend rendering cycles on things that 17 | change. The optional bindings to React and pre-built components let you easily 18 | build fully reactive UIs on top of TinyBase. You even get a built-in undo 19 | stack, and developer tools! 20 | 21 | ## It's _Database-Like_ 22 | 23 | Consumer app? Enterprise app? Or even a game? Model key-value data and tabular 24 | data with optional typed schematization, whatever its data structures. There 25 | are built-in indexing, metric aggregation, and tabular relationships APIs - 26 | and a powerful query engine to select, join, filter, and group data 27 | (reactively!) without SQL. 28 | 29 | ## It _Synchronizes_ 30 | 31 | TinyBase has native CRDT support, meaning that you can deterministically 32 | synchronize and merge data across multiple sources, clients, and servers. And 33 | although TinyBase is an in-memory data store, you can easily persist your data 34 | to file, browser storage /persister-browser, IndexedDB, SQLite or PostgreSQL 35 | databases, and more. 36 | 37 | ## It's Built For A _Local-First_ World 38 | 39 | TinyBase works anywhere that JavaScript does, but it's especially great for 40 | local-first apps: where data is stored locally on the user's device and that 41 | can be run offline. It's tiny by name, tiny by nature: just 5.3kB - 11.5kB and 42 | with no dependencies - yet 100% tested, fully documented, and of course, open 43 | source! 44 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/powersync/details.md: -------------------------------------------------------------------------------- 1 | 2 | ## PowerSync Introduction 3 | 4 | [PowerSync](https://powersync.com) keeps backend databases in sync with on-device SQLite databases embedded in a client SDK. It enables instantly-responsive local-first & offline-first apps that remain available even when network connectivity is poor or non-existent. 5 | 6 | PowerSync is designed to be backend database agnostic, with support for Postgres, MongoDB, and MySQL as of April 2025. 7 | 8 | PowerSync is also designed to be client-side framework agnostic, and offers a wide range of client SDKs, including Flutter, React Native & Expo, web (JavaScript), Node.js, Kotlin Multiplatform, Swift and .NET. 9 | 10 | ## The Story 11 | 12 | PowerSync is a product of JourneyApps, a software company headquartered in Denver, Colorado. The original product of JourneyApps was the JourneyApps Platform, a full-stack app platform focused on industrial companies, with a sync engine as a subcomponent (originally also named PowerSync). 13 | 14 | The PowerSync engine in the JourneyApps Platform has been used for years in production by a range of Fortune 500 customers in industries such as manufacturing, mining, energy and others. These customers typically have a need to sync a high volume of relational data to users in harsh field conditions, such as remote locations where users are frequently offline. Usage in these kinds of demanding environments has led JourneyApps to battle-harden the PowerSync engine over several years, and these customers continue to rely on the PowerSync engine for critical daily business operations. 15 | 16 | In 2022, JourneyApps decided to spin off the PowerSync engine into the standalone PowerSync product (consisting of a sync service and SDK) allowing the creation of offline-first apps that sync data from backend databases to local SQLite on-device databases. 17 | 18 | ## Resources 19 | 20 | - [Website](https://powersync.com) 21 | - [Documentation](https://docs.powersync.com/intro/powersync-overview) 22 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/livestore/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/livestore/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/nextgraph/details.md: -------------------------------------------------------------------------------- 1 | 2 | > Build local-first, collaborative and decentralized apps, with CRDTs, and end-to-end encryption. 3 | 4 | ## Framework and Platform 5 | 6 | NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. 7 | 8 | This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create decentralized apps featuring: live collaboration on rich-text documents, peer-to-peer communication with end-to-end encryption, offline-first, local-first, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing semantic data (RDF), rich text, and structured data formats like JSON, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of CRDTs. Documents can be linked together, signed, shared securely, queried using the SPARQL language and organized into sites and containers. 9 | 10 | More info [on our website](https://nextgraph.org) 11 | 12 | 13 | ## Features 14 | 15 | - **Linked Data**: link documents and data together with RDF and DID URIs, then query all your data with SPARQL. Comaptible with Solid. 16 | - **Social Network**: NextGraph offers decentralized social network features (DM, timeline, share). Compatible with ActivityPub 17 | - **Portable & Interoperable**: Your data always remains under your control. It isn't tied to a specific app, format, domain name or server. 18 | - **Malleable Software**: switch viewers and editors and reuse them at will. Enjoy ready-made components that can be reused. 19 | - **Local-first**: Your data is stored locally, ensuring availability and privacy. 20 | - **End-to-end encrypted**: All documents are encrypted in the client, and the servers (brokers) cannot see their content. 21 | - **Cross-platform**: Works on all major platforms. 22 | - **Open-source**: The code is available for anyone to use and contribute to, in permissive licensing. 23 | 24 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/livestore/details.md: -------------------------------------------------------------------------------- 1 | # LiveStore 2 | 3 | LiveStore is a TypeScript library that provides a unique approach to building data-intensive, **local-first** applications for the web and mobile (Expo). It combines the architectural benefits of **Event Sourcing** with the power and familiarity of **SQLite**, enhanced by a **signals-based reactivity system**. 4 | 5 | - **Event-Driven:** Instead of direct state mutation, all changes are captured as immutable, ordered **events**. This event log forms the definitive history of state transitions and is the single source of truth. This enables **undo/redo** functionality, **auditability**, and **easier schema migrations**. 6 | - **Pluggable Synchronization:** The **event log** is the unit of synchronization between clients and the backend. The log is synchronized using a push/pull mechanism with client-side rebasing (similar to Git). LiveStore is agnostic to what syncing provider you use and can work with any backend as long as it can persist an event log. 7 | - **Reactive SQLite**: LiveStore processes the event log to materialize the application's state into a local and reactive SQLite database. This database runs **in-memory** to allow for **instant and synchronous queries** directly within your components without `isLoading` states. The database is also **persisted** in the browser and can be used even when offline. 8 | - **Developer Tools**: Includes powerful Devtools for inspecting the real-time state database, browsing the event log, analyzing query performance, visualizing the reactivity graph, monitoring sync status, and executing direct SQLite queries. *(Note: Devtools access may be sponsor-only post-launch)* 9 | - **Open Source & Independent:** Available under an open source license and developed independently, focusing on sustainable development aligned with user needs. 10 | 11 | ## Resources 12 | 13 | - [Website](https://next.livestore.dev) 14 | - [Documentation](https://next.livestore.dev/docs/) 15 | - [GitHub](https://github.com/livestorejs/livestore) 16 | - [Examples](https://github.com/livestorejs/livestore/tree/main/examples/standalone) 17 | - [Discord](https://discord.gg/RbMcjUAPd7) 18 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/powersync/logo.dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/powersync/logo.light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/ditto/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/ditto/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/couchdb/details.md: -------------------------------------------------------------------------------- 1 | # CouchDB 2 | 3 | Apache CouchDB ™ lets you access your data where you need it. The [Couch Replication Protocol](https://docs.couchdb.org/en/stable/replication/protocol.html) is implemented in a variety of projects and products that span every imaginable computing environment from **globally distributed server-clusters**, over **mobile phones** to **web browsers**. Store your data **safely**, on your own servers, or with any leading cloud provider. Your web- and native applications love CouchDB, because it speaks **JSON natively** and supports **binary data** for all your data storage needs. 4 | The [Couch Replication Protocol](https://docs.couchdb.org/en/stable/replication/protocol.html) lets your data flow seamlessly between server clusters to mobile phones and web browsers, enabling a compelling [offline-first](https://offlinefirst.org/) user-experience while maintaining high performance and strong reliability. CouchDB comes with a **developer-friendly** query language, and optionally MapReduce for simple, efficient, and comprehensive data retrieval. 5 | 6 | ## Key Advantages 7 | 8 | - **Couch Replication Protocol:** A custom protocol for syncing JSON documents P2P is behind CouchDB and makes it a first choice for distributed systems. Starting a replication is as simple as a single request or a few clicks through Fauxton, CouchDB’s out-of-the-box UI. 9 | - **HTTP/JSON API:** Because it uses the CouchDB REST API, CouchDB is an HTTP server where practically everything in CouchDB has a URL. The flexibility means CouchDB works with any stack and you can get going without libraries. 10 | - **Designed for reliability:** CouchDB won’t lose your data. Ever. It takes [preventing data corruption](https://neighbourhood.ie/blog/2025/02/26/how-couchdb-prevents-data-corruption-fsync) very seriously, and all processes — including long-running replications — are resumable and designed to be interrupted. 11 | 12 | ## More info 13 | 14 | - [CouchDB](http://couchdb.apache.org/) 15 | - [Check out the docs](https://docs.couchdb.org/en/stable/) 16 | - [CouchDB on GitHub](https://github.com/apache/couchdb) 17 | - [Join our community on Slack](https://join.slack.com/t/couchdb/shared_invite/zt-fa9zim0j-H04m4o_KcLdWeOxEAcwM8g) 18 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/couchdb/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 31 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/couchdb/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 31 | -------------------------------------------------------------------------------- /.github/workflows/generate-content-snapshot.yml: -------------------------------------------------------------------------------- 1 | name: Generate Content Snapshot 2 | 3 | on: 4 | schedule: 5 | # Runs at 00:00 UTC every day 6 | - cron: '0 0 * * *' 7 | # Allow manual trigger 8 | workflow_dispatch: 9 | # Also when pushing to main 10 | push: 11 | branches: 12 | - main 13 | 14 | jobs: 15 | generate: 16 | runs-on: ubuntu-latest 17 | environment: CI 18 | permissions: 19 | contents: write 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - uses: oven-sh/setup-bun@v2 25 | 26 | # Add pnpm cache 27 | - name: Cache pnpm modules 28 | uses: actions/cache@v3 29 | with: 30 | path: ~/.pnpm-store 31 | key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} 32 | restore-keys: | 33 | ${{ runner.os }}-pnpm- 34 | 35 | - run: bun install -g pnpm 36 | - run: pnpm install 37 | - run: pnpm build:ts 38 | 39 | - name: Generate content snapshot 40 | run: pnpm generate:content-snapshot --show-full-errors 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | - name: Check for changes 45 | id: git-check 46 | run: | 47 | git add . 48 | # Set output whether there are changes staged 49 | echo "changes=$(git diff --staged --quiet && echo 'false' || echo 'true')" >> $GITHUB_OUTPUT 50 | 51 | - name: Commit and push if there are changes 52 | if: steps.git-check.outputs.changes == 'true' 53 | env: 54 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 55 | run: | 56 | git config --local user.email "github-actions[bot]@users.noreply.github.com" 57 | git config --local user.name "github-actions[bot]" 58 | git commit -m "chore: update content snapshot [skip ci]" 59 | git push 60 | 61 | - name: Trigger localfirst.fm rebuild 62 | # Ensure this only runs if the push was successful or the whole job succeeded 63 | if: success() 64 | uses: peter-evans/repository-dispatch@v3 65 | with: 66 | token: ${{ secrets.LOCALFIRST_FM_PAT }} 67 | repository: schickling/localfirst.fm 68 | event-type: content-snapshot-updated 69 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/basic/details.md: -------------------------------------------------------------------------------- 1 | # Basic 2 | 3 | **Basic** is building infrastructure for personalized, multiplayer, local-first apps where users own their data. 4 | 5 | We set out to build a complete solution for local-first apps — and realized that a sync engine alone doesn’t solve the problem of user-owned data. That led us to create **personal data stores**: an independent, portable database owned and controlled by the *user*, not the app. 6 | 7 | ## Personal Data Stores 8 | 9 | Most apps today are built on a simple assumption: data lives on the app’s servers. Users generate it, and apps store all the data from all their users in a single, centralized database. This model has caused many of the web’s biggest problems: lock-in, privacy issues, broken interoperability, and walled gardens. 10 | 11 | **Basic flips that model.** Instead of one app owning data from many users, each user owns their own data — and apps just plug into it. It’s a small shift with big benefits: 12 | 13 | - **User control**: Data lives with the user, not the platform. They can revoke access at any time. 14 | - **Interoperability**: Apps don’t need to manually integrate with each other — it’s built in. This unlocks deeply personalized experiences and a “universal shared memory” across apps. 15 | - **Portability**: Users can switch tools without losing their data or starting over. 16 | - **Simpler apps**: Developers don’t need to build auth, sync, or complex backends — just good apps. 17 | 18 | ## Building on Basic 19 | 20 | **Basic** is a complete framework for building local-first apps. It includes auth, database, sync, and client SDKs. 21 | 22 | - **Auth**: Users authenticate with their own PDS. Basic makes this seamless by providing a default PDS for each user, enabling quick onboarding. 23 | - **Database & Schema**: Apps define a schema — a simple, declarative way to describe your data. You define your tables and fields; Basic handles the rest. This abstraction makes syncing across devices easy, without worrying about migrations or conflicts. 24 | - **Sync**: Basic comes with a built-in sync engine, fully integrated with the React SDK. We're working on support for more clients (like React Native) and even compatibility with other sync engines. 25 | 26 | ## Getting Started 27 | 28 | - [Check out the docs](https://docs.basic.tech) to learn more. 29 | - [Read more about personal data stores](https://docs.basic.tech/readings/user-owned-data-stores). 30 | - [Join our Discord](https://discord.gg/M57gcazvYk) to chat with the team or ask questions. -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/ditto/details.md: -------------------------------------------------------------------------------- 1 | # Ditto 2 | 3 | Resilient Edge Device Connectivity. Servers and Cloud, Optional. The only mobile database with built-in edge device connectivity and resiliency 4 | 5 | ## Keep mission-critical systems online when it matters most 6 | 7 | Ditto is the only edge-native, mobile database that can consistently support your business anytime, anywhere. Edge-native solutions are built specifically to thrive on mobile and edge devices, without relying solely on cloud-based services. 8 | 9 | - **Build flexible operations** that are both latency-sensitive and resilient without reliance on network hardware, edge servers, or the cloud. 10 | - **Decentralize your systems** to remove single points of failure that lead to operational bottlenecks. 11 | - **Drive consistent revenue and customer service** anywhere, regardless of connectivity or bandwidth. 12 | - **Offline-first mobile database**: Even when your devices are completely offline, they can awlays read, write, and process data. 13 | - **Cross-platform**: Works on all major platforms. 14 | - **CRDT-powered conflict resolution**: To resolve concurrency conflicts that appear in decentralized models, as well as enable delta-based sync, Ditto harnesses the power of conflict-free replicated data types (CRDT) technology. 15 | 16 | ## P2P Sync 17 | 18 | ### Automatic Device Discovery and Mesh Networking 19 | 20 | Out-of-the-box support for BLE, P2P Wifi, LAN, and more enables real-time sync in disconnected or bandwidth-constrained environments. 21 | 22 | ### Direct Peer-to-Peer Sync 23 | 24 | Out-of-the-box suport for direct peer-to-peer sync between devices, without the need for a central server. 25 | 26 | ### Opportunistic Cloud Sync 27 | 28 | Anytime internet is available within the mesh, devices sync with your existing cloud systems. 29 | 30 | ## Core Features 31 | 32 | - **Intelligent Rainbow Connection**: Ditto manages multiple P2P and IP-based transports at the same time and optimizes your sync for speed based on available bandwidth. 33 | - **Opportunistic Cloud Sync**: Opportunistically sync with Ditto Server whenever a device within the mesh has internet. 34 | - **Bidirectional Cloud Connector**: Bidirectionally sync from Ditto Server to your existing systems. 35 | - **Cross-Platform Support**: Build and sync across your preferred languages, frameworks, and platforms. 36 | - **Conflict Resolution with CRDTs**: Simultaneous and offline changes are automatically resolved 37 | - **Expressive query system**: Find what you need with advanced filters, sorting, transactions. 38 | - **Reactive Design Patterns**: No more polling code for changes, register queries and get updates in real-time. 39 | - **Bring your own authentication**: Whether it's JWT, OAuth 2.0 or SAML. Bring your own identity providers. 40 | 41 | 42 | ## Learn More 43 | - [Ditto Website](https://www.ditto.com) 44 | - [Ditto Docs](https://docs.ditto.live/sdk/latest/quickstarts/quickstarts-landing) 45 | - [Ditto GitHub](https://github.com/getditto) 46 | 47 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/loro/details.md: -------------------------------------------------------------------------------- 1 | Loro is a [CRDTs(Conflict-free Replicated Data Types)](https://crdt.tech/) library that makes building [local-first](https://www.inkandswitch.com/essay/local-first/) and collaborative apps easier. You can now use it in [Rust](https://crates.io/crates/loro), [JS](https://www.npmjs.com/package/loro-crdt) (via WASM), [Swift](https://swiftpackageindex.com/loro-dev/loro-swift) and [Python](https://pypi.org/project/loro/). 2 | 3 | ## Features 4 | 5 | **Features Provided by CRDTs** 6 | 7 | - P2P Synchronization 8 | - Automatic Merging 9 | - Local Availability 10 | - Scalability 11 | - Delta Updates 12 | 13 | **Supported CRDT Algorithms** 14 | 15 | - 📝 Text Editing with [Fugue](https://arxiv.org/abs/2305.00583) 16 | - 📙 [Rich Text CRDT](https://loro.dev/blog/loro-richtext) 17 | - 🌲 [Moveable Tree](https://loro.dev/docs/tutorial/tree) 18 | - 🚗 [Moveable List](https://loro.dev/docs/tutorial/list) 19 | - 🗺️ [Last-Write-Wins Map](https://loro.dev/docs/tutorial/map) 20 | 21 | **Advanced Features in Loro** 22 | 23 | - 🚀 [Fast Document Loading](https://loro.dev/blog/v1.0) 24 | - ⏱️ Fast [Time Travel](https://loro.dev/docs/tutorial/time_travel) Through History 25 | - 🏛️ [Version Control with Real-Time Collaboration](https://loro.dev/blog/v1.0#version-control) 26 | - 📦 [Shallow Snapshot](https://loro.dev/docs/advanced/shallow_snapshot) that Works like Git Shallow Clone 27 | 28 | ## Example 29 | 30 | ```ts 31 | import { expect, test } from "vitest"; 32 | import { LoroDoc, LoroList } from "loro-crdt"; 33 | 34 | test("sync example", () => { 35 | // Sync two docs with two rounds of exchanges 36 | 37 | // Initialize document A 38 | const docA = new LoroDoc(); 39 | const listA: LoroList = docA.getList("list"); 40 | listA.insert(0, "A"); 41 | listA.insert(1, "B"); 42 | listA.insert(2, "C"); 43 | 44 | // Export all updates from docA 45 | const bytes: Uint8Array = docA.export({ mode: "update" }); 46 | 47 | // Simulate sending `bytes` across the network to another peer, B 48 | 49 | const docB = new LoroDoc(); 50 | // Peer B imports the updates from A 51 | docB.import(bytes); 52 | 53 | // B's state matches A's state 54 | expect(docB.toJSON()).toStrictEqual({ 55 | list: ["A", "B", "C"], 56 | }); 57 | 58 | // Get the current version of docB 59 | const version = docB.oplogVersion(); 60 | 61 | // Simulate editing at B: delete item 'B' 62 | const listB: LoroList = docB.getList("list"); 63 | listB.delete(1, 1); 64 | 65 | // Export the updates from B since the last sync point 66 | const bytesB: Uint8Array = docB.export({ mode: "update", from: version }); 67 | 68 | // Simulate sending `bytesB` back across the network to A 69 | 70 | // A imports the updates from B 71 | docA.import(bytesB); 72 | 73 | // A has the same state as B 74 | expect(docA.toJSON()).toStrictEqual({ 75 | list: ["A", "C"], 76 | }); 77 | }); 78 | ``` 79 | 80 | ## DevTools 81 | 82 | ### Loro Inspector 83 | 84 | You can use the [Loro Inspector](https://inspector.loro.dev) to inspect the state and history of a Loro document. -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/electricsql/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "electricsql", 4 | "Name": "ElectricSQL", 5 | "Website": "https://electric-sql.com", 6 | "Deployment": [ 7 | "Self-hosted", 8 | "Hosted" 9 | ], 10 | "License": "Apache 2.0", 11 | "AppTarget": { 12 | "Platform": { 13 | "data": [ 14 | "Browser", 15 | "React Native", 16 | "iOS", 17 | "Android", 18 | "macOS", 19 | "WASM", 20 | "Linux", 21 | "Node", 22 | "Javascript", 23 | "Typescript", 24 | "Elixir" 25 | ] 26 | } 27 | }, 28 | "ServerSideData": { 29 | "PersistenceMechanism": { 30 | "data": [ 31 | "Postgres" 32 | ] 33 | }, 34 | "DataModelParadigm": { 35 | "data": "Relational" 36 | } 37 | }, 38 | "ClientSideData": { 39 | "PersistenceMechanism": { 40 | "data": [ 41 | "In-Memory", 42 | "Browser File Cache", 43 | "Localstorage", 44 | "IndexedDB", 45 | "OPFS", 46 | "SQLite", 47 | "PGLite", 48 | "React Query", 49 | "TanStack Optimistic", 50 | "Cloudflare Durable Object Storage", 51 | "Cloudflare D1", 52 | "Redis", 53 | "Custom" 54 | ], 55 | "comment": "\n Electric syncs data out of Postgres into anything you like.\n From an in-memory state variable to a local embedded database.\n " 56 | }, 57 | "DataModel": { 58 | "data": "Log, Object or relational", 59 | "comment": "\n Data syncs in as a log of logical change operations.\n These can be materialized as collections of rows,\n or into an embedded database as relations in tables.\n " 60 | }, 61 | "OfflineReads": { 62 | "data": "Full Support", 63 | "comment": "Full support when shape is synced." 64 | }, 65 | "DataSize": { 66 | "data": "Limited by size of hard drive" 67 | } 68 | }, 69 | "SynchronizationStrategy": { 70 | "FullOrPartialReplication": { 71 | "data": [ 72 | "Partial Replication" 73 | ], 74 | "comment": "Partial replication via shapes." 75 | }, 76 | "ConflictHandling": { 77 | "data": "Flexible", 78 | "comment": "\n Electric handles read-path sync. It doesn't prescribe a solution for writes\n and thus avoids handling conflicts. It does provide documented patterns\n and framework integrations for handling writes and optimistic state.\n These implement a range of strategies for conflict handling.\n " 79 | }, 80 | "WhereResolutionOccurs": { 81 | "data": "Server" 82 | }, 83 | "WhatGetsSynced": { 84 | "data": { 85 | "ServerToClient": "\n Shape logs, in the form of a stream of change messages\n (inserts, updates and deletes) and control messages\n (up-to-date, must-refetch).\n " 86 | } 87 | }, 88 | "Authority": { 89 | "data": "Centralized", 90 | "comment": "Postgres is the source of truth, durability and total order." 91 | } 92 | }, 93 | "__generated": { 94 | "lastUpdated": "2025-04-16T12:53:20.000Z" 95 | } 96 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/basic/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "basic", 4 | "Name": "Basic.tech", 5 | "Description": "Infra for building personalized, multiplayer, local-first apps where users own their data", 6 | "MaturityLevel": "Beta", 7 | "Website": "https://basic.tech", 8 | "UniquenessNote": "Since data is synced to user-owned data stores, apps are interoperable by default. Apps can discover and reuse data schemas from other apps or use schema lenses to adapt to any app.", 9 | "Deployment": [ 10 | "Self-hosted", 11 | "Hosted" 12 | ], 13 | "License": "MIT", 14 | "AppTarget": { 15 | "LanguageSDK": { 16 | "data": [ 17 | "Typescript", 18 | "JavaScript" 19 | ] 20 | }, 21 | "FrameworkIntegrations": { 22 | "data": [ 23 | "Next.js", 24 | "React Native", 25 | "React" 26 | ] 27 | } 28 | }, 29 | "Networking": { 30 | "Protocol": { 31 | "data": [ 32 | "WebSockets", 33 | "HTTP" 34 | ] 35 | }, 36 | "Topology": { 37 | "data": "Client-Server" 38 | } 39 | }, 40 | "ServerSideData": { 41 | "PersistenceMechanism": { 42 | "data": [ 43 | "PostgreSQL", 44 | "SQLite" 45 | ] 46 | }, 47 | "DataModelParadigm": { 48 | "data": "Relational" 49 | }, 50 | "SchemaManagement": { 51 | "data": [ 52 | "Schema definition", 53 | "Validate schemas on write" 54 | ] 55 | } 56 | }, 57 | "ClientSideData": { 58 | "QueryAPI": { 59 | "data": [ 60 | "Async", 61 | "Reactive queries" 62 | ] 63 | }, 64 | "PersistenceMechanism": { 65 | "data": [ 66 | "IndexedDB" 67 | ] 68 | }, 69 | "DataModel": { 70 | "data": "Document" 71 | }, 72 | "OfflineReads": { 73 | "data": "Full Support" 74 | }, 75 | "OfflineWrites": { 76 | "data": "Local conflict resolution" 77 | } 78 | }, 79 | "SynchronizationStrategy": { 80 | "FullOrPartialReplication": { 81 | "data": [ 82 | "Full Replication" 83 | ] 84 | }, 85 | "ConflictHandling": { 86 | "data": "Server reconciliation" 87 | }, 88 | "WhereResolutionOccurs": { 89 | "data": "Server" 90 | } 91 | }, 92 | "AuthIdentity": { 93 | "Encryption": { 94 | "data": "Yes", 95 | "comment": "Encrypted at rest - End to end encryption optional" 96 | }, 97 | "AuthenticationMethod": { 98 | "data": [ 99 | "JWT Tokens" 100 | ] 101 | }, 102 | "AuthorizationPermissions": { 103 | "data": "Custom" 104 | } 105 | }, 106 | "UIRelated": { 107 | "Components": { 108 | "data": [ 109 | "React components for Auth" 110 | ] 111 | } 112 | }, 113 | "DevelopmentWorkflowsDX": { 114 | "DebuggingTools": { 115 | "data": [ 116 | "Dashboard" 117 | ] 118 | }, 119 | "CLI": { 120 | "data": "Yes" 121 | }, 122 | "TypeSupport": { 123 | "data": "Yes" 124 | } 125 | }, 126 | "__generated": { 127 | "lastUpdated": "2025-04-22T17:35:43.000Z" 128 | } 129 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/y-sweet/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "y-sweet", 4 | "Name": "Y-Sweet", 5 | "Website": "https://y-sweet.dev", 6 | "Deployment": [ 7 | "Self-hosted", 8 | "Hosted" 9 | ], 10 | "License": "MIT", 11 | "AppTarget": { 12 | "Platform": { 13 | "data": [ 14 | "Browser", 15 | "Node", 16 | "iOS", 17 | "Android", 18 | "macOS", 19 | "Linux" 20 | ], 21 | "comment": "Limited only by Yjs support." 22 | }, 23 | "LanguageSDK": { 24 | "data": [ 25 | "TypeScript", 26 | "Python" 27 | ] 28 | }, 29 | "FrameworkIntegrations": { 30 | "data": [ 31 | "React" 32 | ] 33 | } 34 | }, 35 | "Networking": { 36 | "Protocol": { 37 | "data": [ 38 | "WebSockets", 39 | "HTTP" 40 | ] 41 | }, 42 | "Topology": { 43 | "data": "Client-Server" 44 | } 45 | }, 46 | "ServerSideData": { 47 | "PersistenceMechanism": { 48 | "data": [ 49 | "S3-compatible object store" 50 | ] 51 | }, 52 | "DataModelParadigm": { 53 | "data": "Document" 54 | }, 55 | "ExistingDatabaseSupport": { 56 | "data": "Yes", 57 | "comment": "In the \"Figma architecture\" sense: ground-truth document data only lives on S3, but document metadata exists in your existing DB." 58 | } 59 | }, 60 | "ClientSideData": { 61 | "LocalRefreshLatency": { 62 | "data": "<1 ms" 63 | }, 64 | "PersistenceMechanism": { 65 | "data": [ 66 | "IndexedDB" 67 | ] 68 | }, 69 | "DataModel": { 70 | "data": "Document" 71 | }, 72 | "SchemaManagement": { 73 | "data": [ 74 | "No support" 75 | ] 76 | }, 77 | "OfflineReads": { 78 | "data": "Yes" 79 | }, 80 | "OptimisticUpdates": { 81 | "data": "Yes" 82 | }, 83 | "OfflineWrites": { 84 | "data": "Yes" 85 | } 86 | }, 87 | "SynchronizationStrategy": { 88 | "ConflictHandling": { 89 | "data": "Automatic via CRDT", 90 | "comment": "CRDT (YATA)" 91 | }, 92 | "WhereResolutionOccurs": { 93 | "data": "Server" 94 | }, 95 | "WhatGetsSynced": { 96 | "data": { 97 | "ClientToServer": "mutations" 98 | } 99 | }, 100 | "Authority": { 101 | "data": "Centralized" 102 | } 103 | }, 104 | "AuthIdentity": { 105 | "Encryption": { 106 | "data": "Yes", 107 | "comment": "Subject to the underlying object store used; most encrypt at rest by default; AES-GCM encryption on the client" 108 | }, 109 | "AuthenticationMethod": { 110 | "data": [ 111 | "Tokens" 112 | ], 113 | "comment": "Auth delegation from your application server based on temporary tokens." 114 | } 115 | }, 116 | "UIRelated": { 117 | "Components": { 118 | "data": [ 119 | "y.js plugins", 120 | "Presence" 121 | ], 122 | "comment": "Anything compatible with Yjs (Slate, BlockNote, Quill, Lexical, etc.)" 123 | } 124 | }, 125 | "__generated": { 126 | "lastUpdated": "2025-04-25T16:01:03.000Z" 127 | } 128 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/pouchdb/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 16 | 19 | 25 | 31 | 37 | 43 | 49 | 55 | 61 | 67 | 73 | 79 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/pouchdb/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 14 | 16 | 19 | 25 | 31 | 37 | 43 | 49 | 55 | 61 | 67 | 73 | 79 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/loro/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "loro", 4 | "Name": "Loro", 5 | "Description": "Make your JSON data collaborative and version-controlled with CRDTs", 6 | "MaturityLevel": "Production-Ready", 7 | "Logo": { 8 | "Light": "https://github.com/loro-dev/loro/blob/main/docs/Loro.svg", 9 | "Dark": "https://github.com/loro-dev/loro/blob/main/docs/Loro.svg" 10 | }, 11 | "Website": "https://loro.dev", 12 | "GitHub": "https://github.com/loro-dev/loro", 13 | "GetStarted": "https://loro.dev/docs/tutorial/get_started", 14 | "InitialReleaseDate": "2023-11-13T00:00:00.000Z", 15 | "Deployment": [ 16 | "Self-hosted" 17 | ], 18 | "License": "MIT", 19 | "AppTarget": { 20 | "Platform": { 21 | "data": [ 22 | "Browser", 23 | "Node", 24 | "iOS", 25 | "macOS", 26 | "WASM", 27 | "Linux" 28 | ] 29 | }, 30 | "LanguageSDK": { 31 | "data": [ 32 | "typescript", 33 | "javascript", 34 | "Rust", 35 | "Swift", 36 | "Python" 37 | ] 38 | }, 39 | "ClientBundleSize": { 40 | "data": "~900 kB" 41 | } 42 | }, 43 | "Networking": { 44 | "Protocol": { 45 | "data": [ 46 | "WebSockets", 47 | "HTTP" 48 | ] 49 | }, 50 | "Topology": { 51 | "data": "P2P" 52 | } 53 | }, 54 | "ServerSideData": { 55 | "PersistenceMechanism": { 56 | "data": [ 57 | "Custom" 58 | ] 59 | }, 60 | "DataModelParadigm": { 61 | "data": "Document" 62 | } 63 | }, 64 | "ClientSideData": { 65 | "QueryAPI": { 66 | "data": [ 67 | "Async" 68 | ] 69 | }, 70 | "LocalRefreshLatency": { 71 | "data": "~1ms" 72 | }, 73 | "PersistenceMechanism": { 74 | "data": [ 75 | "IndexedDB", 76 | "Custom" 77 | ] 78 | }, 79 | "DataModel": { 80 | "data": "Document" 81 | }, 82 | "OfflineReads": { 83 | "data": "Full Support" 84 | }, 85 | "OfflineWrites": { 86 | "data": "Local conflict resolution" 87 | }, 88 | "DataSize": { 89 | "data": "Up to 5-10 MB per document" 90 | } 91 | }, 92 | "SynchronizationStrategy": { 93 | "FullOrPartialReplication": { 94 | "data": [ 95 | "Full Replication" 96 | ] 97 | }, 98 | "ConflictHandling": { 99 | "data": "Automatic via CRDT" 100 | }, 101 | "WhereResolutionOccurs": { 102 | "data": "Client" 103 | }, 104 | "WhatGetsSynced": { 105 | "data": { 106 | "ClientToServer": "Ops", 107 | "ServerToClient": "Ops", 108 | "ClientToClient": "Ops" 109 | } 110 | }, 111 | "Authority": { 112 | "data": "Decentralized" 113 | } 114 | }, 115 | "UIRelated": { 116 | "RichTextEditing": { 117 | "data": "Yes" 118 | }, 119 | "Components": { 120 | "data": [ 121 | "ProseMirror", 122 | "CodeMirror" 123 | ] 124 | } 125 | }, 126 | "DevelopmentWorkflowsDX": { 127 | "DebuggingTools": { 128 | "data": [ 129 | "Data Inspector" 130 | ], 131 | "comment": "https://loro.dev/docs/advanced/inspector" 132 | }, 133 | "TypeSupport": { 134 | "data": "TypeScript" 135 | } 136 | }, 137 | "__generated": { 138 | "lastUpdated": "2025-04-30T09:20:37.000Z" 139 | } 140 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/couchdb/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "couchdb", 4 | "Name": "CouchDB", 5 | "Description": "The database that perfected Offline-First. Multi-primary sync, designed for reliability.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://couchdb.apache.org", 8 | "InitialReleaseDate": "2010-07-13T23:00:00.000Z", 9 | "Deployment": [ 10 | "Self-hosted" 11 | ], 12 | "License": "Apache-2.0", 13 | "AppTarget": { 14 | "Platform": { 15 | "data": [ 16 | "Linux", 17 | "macOS", 18 | "Windows", 19 | "Unix" 20 | ] 21 | }, 22 | "LanguageSDK": { 23 | "data": [ 24 | "HTTP", 25 | "JSON" 26 | ] 27 | }, 28 | "FrameworkIntegrations": { 29 | "data": [ 30 | "" 31 | ], 32 | "comment": "None directly; all via PouchDB." 33 | } 34 | }, 35 | "Networking": { 36 | "Protocol": { 37 | "data": [ 38 | "HTTP" 39 | ] 40 | }, 41 | "Topology": { 42 | "data": "P2P / Client-server / Mesh Network / Relay Server" 43 | } 44 | }, 45 | "ServerSideData": { 46 | "PersistenceMechanism": { 47 | "data": [ 48 | "Custom" 49 | ] 50 | }, 51 | "DataSize": { 52 | "data": "Unlimited" 53 | }, 54 | "DataModelParadigm": { 55 | "data": "Document" 56 | }, 57 | "SchemaManagement": { 58 | "data": [ 59 | "Schema definition", 60 | "Schema validation" 61 | ], 62 | "comment": "Definition and validation optional." 63 | } 64 | }, 65 | "SynchronizationStrategy": { 66 | "FullOrPartialReplication": { 67 | "data": [ 68 | "Full Replication", 69 | "Partial Replication" 70 | ], 71 | "comment": "Full Replication & Various Partial Replication Strategies" 72 | }, 73 | "ConflictHandling": { 74 | "data": "Flexible/Custom" 75 | }, 76 | "WhereResolutionOccurs": { 77 | "data": "Client and/or Server" 78 | }, 79 | "WhatGetsSynced": { 80 | "data": { 81 | "ClientToServer": "Full document revisions", 82 | "ServerToClient": "Full document revisions" 83 | }, 84 | "comment": "Efficient sync-list delta computation and efficient avoidance of redundant document sync." 85 | }, 86 | "Authority": { 87 | "data": "Default centralized, decentralized possible" 88 | }, 89 | "Latency": { 90 | "data": "~1–10ms", 91 | "comment": "Customisable for low-bandwidth and/or high-latency networks" 92 | }, 93 | "Concurrency": { 94 | "data": "Effectively unlimited" 95 | } 96 | }, 97 | "AuthIdentity": { 98 | "Encryption": { 99 | "data": "Transport-level encryption" 100 | }, 101 | "AuthenticationMethod": { 102 | "data": [ 103 | "Built-in", 104 | "JWT Tokens", 105 | "Basic Auth", 106 | "Proxy Auth" 107 | ] 108 | }, 109 | "AuthorizationPermissions": { 110 | "data": "RBAC" 111 | } 112 | }, 113 | "DevelopmentWorkflowsDX": { 114 | "DebuggingTools": { 115 | "data": [ 116 | "Data Inspector", 117 | "Network Inspector" 118 | ] 119 | }, 120 | "CLI": { 121 | "data": "Standard tooling like curl & jq suffices" 122 | }, 123 | "TypeSupport": { 124 | "data": "Full type support" 125 | } 126 | }, 127 | "__generated": { 128 | "lastUpdated": "2025-08-14T14:50:28.000Z" 129 | } 130 | } -------------------------------------------------------------------------------- /landscape-fetch-content/src/repos.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from 'effect' 2 | 3 | export const RepoInfo = Schema.Struct({ 4 | id: Schema.String, 5 | owner: Schema.String, 6 | repo: Schema.String, 7 | /** @default 'main' */ 8 | branch: Schema.optionalWith(Schema.String, { default: () => 'main' }), 9 | /** @default '' */ 10 | basePath: Schema.optionalWith(Schema.String, { default: () => '' }), 11 | }) 12 | 13 | export type RepoInfo = typeof RepoInfo.Type 14 | 15 | export const repos = Schema.decodeSync(Schema.Array(RepoInfo))([ 16 | { 17 | id: 'nextgraph', 18 | owner: 'nextgraph-org', 19 | repo: 'landscape-data', 20 | basePath: '', 21 | }, 22 | { 23 | id: 'yjs', 24 | owner: 'yjs', 25 | repo: 'local-first-landscape-data', 26 | basePath: 'yjs', 27 | }, 28 | { 29 | id: 'automerge', 30 | owner: 'automerge', 31 | repo: 'local-first-landscape-data', 32 | basePath: '', 33 | }, 34 | { 35 | id: 'electricsql', 36 | owner: 'electric-sql', 37 | repo: 'local-first-landscape-data', 38 | basePath: '', 39 | }, 40 | { 41 | id: 'jazz', 42 | owner: 'garden-co', 43 | repo: 'jazz-lofi-landscape', 44 | }, 45 | { 46 | id: 'zero', 47 | owner: 'rocicorp', 48 | repo: 'local-first-landscape-data', 49 | basePath: '', 50 | }, 51 | { 52 | id: 'liveblocks-yjs', 53 | owner: 'liveblocks', 54 | repo: 'local-first-landscape-data', 55 | basePath: 'liveblocks-yjs', 56 | }, 57 | { 58 | id: 'liveblocks-storage', 59 | owner: 'liveblocks', 60 | repo: 'local-first-landscape-data', 61 | basePath: 'liveblocks-storage', 62 | }, 63 | { 64 | id: 'livestore', 65 | owner: 'livestorejs', 66 | repo: 'local-first-landscape', 67 | }, 68 | { 69 | id: 'dxos', 70 | owner: 'dxos', 71 | repo: 'local-first-landscape-data', 72 | basePath: '', 73 | }, 74 | { 75 | id: 'basic', 76 | owner: 'basicdb', 77 | repo: 'local-first-landscape-data', 78 | basePath: '', 79 | }, 80 | { 81 | id: 'convex', 82 | owner: 'get-convex', 83 | repo: 'localfirst-landscape-data', 84 | basePath: '', 85 | }, 86 | { 87 | id: 'ditto', 88 | owner: 'getditto', 89 | repo: 'local-first-landscape-data', 90 | basePath: '', 91 | }, 92 | { 93 | id: 'powersync', 94 | owner: 'powersync-ja', 95 | repo: 'local-first-landscape-data', 96 | basePath: '', 97 | }, 98 | { 99 | id: 'triplit', 100 | owner: 'aspen-cloud', 101 | repo: 'local-first-landscape-data', 102 | basePath: '', 103 | }, 104 | { 105 | id: 'tinybase', 106 | owner: 'tinyplex', 107 | repo: 'tinybase-landscape-data', 108 | basePath: '', 109 | }, 110 | { 111 | id: 'y-sweet', 112 | owner: 'jamsocket', 113 | repo: 'y-sweet', 114 | basePath: 'local-first-landscape', 115 | }, 116 | { 117 | id: 'loro', 118 | owner: 'loro-dev', 119 | repo: 'loro-landscape-data', 120 | basePath: '', 121 | }, 122 | { 123 | id: 'instant', 124 | owner: 'instantdb', 125 | repo: 'local-first-landscape-data', 126 | basePath: '', 127 | }, 128 | { 129 | id: 'pouchdb', 130 | owner: 'neighbourhoodie', 131 | repo: 'pouchdb-landscape-data', 132 | basePath: '', 133 | }, 134 | { 135 | id: 'couchdb', 136 | owner: 'neighbourhoodie', 137 | repo: 'couchdb-landscape-data', 138 | basePath: '', 139 | }, 140 | { 141 | id: 'rxdb', 142 | owner: 'pubkey', 143 | repo: 'landscape-data-rxdb', 144 | basePath: '', 145 | }, 146 | ]) 147 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/nextgraph/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 37 | 43 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/nextgraph/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 37 | 43 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/pouchdb/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "pouchdb", 4 | "Name": "PouchDB", 5 | "Description": "Open source JavaScript database inspired by Apache CouchDB that is designed to run well within the browser.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://pouchdb.com/", 8 | "InitialReleaseDate": "2013-12-21T23:00:00.000Z", 9 | "Deployment": [ 10 | "Self-hosted" 11 | ], 12 | "License": "Apache-2.0", 13 | "AppTarget": { 14 | "Platform": { 15 | "data": [ 16 | "Browser", 17 | "Node" 18 | ] 19 | }, 20 | "LanguageSDK": { 21 | "data": [ 22 | "Typescript", 23 | "JavaScript" 24 | ] 25 | }, 26 | "FrameworkIntegrations": { 27 | "data": [ 28 | "React", 29 | "Svelte", 30 | "Vue", 31 | "Angular" 32 | ], 33 | "comment": "PouchDB can be used with all Javascript Frameworks, no special package required." 34 | }, 35 | "ClientBundleSize": { 36 | "data": "46KB", 37 | "comment": "46KB zipped" 38 | } 39 | }, 40 | "Networking": { 41 | "Protocol": { 42 | "data": [ 43 | "HTTP", 44 | "WebSockets" 45 | ] 46 | }, 47 | "Topology": { 48 | "data": "P2P / Client-server / Mesh Network / Relay Server" 49 | } 50 | }, 51 | "ClientSideData": { 52 | "QueryAPI": { 53 | "data": [ 54 | "Async" 55 | ] 56 | }, 57 | "PersistenceMechanism": { 58 | "data": [ 59 | "IndexedDB", 60 | "LevelDB", 61 | "SQLite", 62 | "Localstorage" 63 | ] 64 | }, 65 | "PersistenceFeatures": { 66 | "data": "Indexes" 67 | }, 68 | "DataModel": { 69 | "data": "Document & Event Sourcing" 70 | }, 71 | "SchemaManagement": { 72 | "data": [ 73 | "Schema definition" 74 | ], 75 | "comment": " validation & typing optional" 76 | }, 77 | "OfflineReads": { 78 | "data": "Full Support" 79 | }, 80 | "OptimisticUpdates": { 81 | "data": "Yes" 82 | }, 83 | "OfflineWrites": { 84 | "data": "Local conflict resolution" 85 | }, 86 | "DataSize": { 87 | "data": "Depends on the size of the shared data" 88 | } 89 | }, 90 | "SynchronizationStrategy": { 91 | "FullOrPartialReplication": { 92 | "data": [ 93 | "Full Replication", 94 | "Partial Replication" 95 | ], 96 | "comment": "Full Replication & Various Partial Replication Strategies" 97 | }, 98 | "ConflictHandling": { 99 | "data": "Flexible/Custom" 100 | }, 101 | "WhereResolutionOccurs": { 102 | "data": "Client and/or Server" 103 | }, 104 | "WhatGetsSynced": { 105 | "data": { 106 | "ClientToServer": "Full document revisions", 107 | "ServerToClient": "Full document revisions" 108 | }, 109 | "comment": "Efficient sync-list delta computation and efficient avoidance of redundant document sync." 110 | }, 111 | "Authority": { 112 | "data": "Default centralized, decentralized possible" 113 | }, 114 | "Latency": { 115 | "data": "~1–10ms", 116 | "comment": "Customisable for low-bandwidth and/or high-latency networks" 117 | }, 118 | "Concurrency": { 119 | "data": "Effectively unlimited" 120 | } 121 | }, 122 | "AuthIdentity": { 123 | "Encryption": { 124 | "data": "Transport-level encryption", 125 | "comment": "Document encryption optional" 126 | }, 127 | "AuthenticationMethod": { 128 | "data": [ 129 | "Built-in", 130 | "JWT Tokens", 131 | "Basic Auth", 132 | "Proxy Auth" 133 | ] 134 | }, 135 | "AuthorizationPermissions": { 136 | "data": "RBAC" 137 | } 138 | }, 139 | "DevelopmentWorkflowsDX": { 140 | "DebuggingTools": { 141 | "data": [ 142 | "Data Inspector", 143 | "Network Inspector" 144 | ] 145 | }, 146 | "CLI": { 147 | "data": "N/A" 148 | }, 149 | "TypeSupport": { 150 | "data": "Full type support" 151 | } 152 | }, 153 | "__generated": { 154 | "lastUpdated": "2025-06-06T14:45:10.000Z" 155 | } 156 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/triplit/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "triplit", 4 | "Name": "Triplit", 5 | "Description": "The Typescript-first database that handles caching and syncing for your app automatically", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://triplit.dev", 8 | "InitialReleaseDate": "2023-07-27T00:00:00.000Z", 9 | "Deployment": [ 10 | "Self-hosted", 11 | "Hosted" 12 | ], 13 | "License": "GPL3", 14 | "AppTarget": { 15 | "Platform": { 16 | "data": [ 17 | "Browser", 18 | "Node", 19 | "Deno", 20 | "Bun", 21 | "Cloudflare Workers", 22 | "Hermes" 23 | ] 24 | }, 25 | "LanguageSDK": { 26 | "data": [ 27 | "Typescript" 28 | ] 29 | }, 30 | "FrameworkIntegrations": { 31 | "data": [ 32 | "React", 33 | "Vue", 34 | "Svelte", 35 | "Angular", 36 | "React Native" 37 | ] 38 | }, 39 | "ClientBundleSize": { 40 | "data": "~70kB (gzip) " 41 | } 42 | }, 43 | "Networking": { 44 | "Protocol": { 45 | "data": [ 46 | "WebSockets", 47 | "HTTP" 48 | ] 49 | }, 50 | "Topology": { 51 | "data": "Client-Server" 52 | } 53 | }, 54 | "ServerSideData": { 55 | "PersistenceMechanism": { 56 | "data": [ 57 | "SQLite", 58 | "Cloudflare Durable Object Storage", 59 | "Custom" 60 | ], 61 | "comment": "Pluggable with simple Key-Value interface" 62 | }, 63 | "DataModelParadigm": { 64 | "data": "Relational" 65 | }, 66 | "SchemaManagement": { 67 | "data": [ 68 | "Derived types", 69 | "Schema migrations", 70 | "Validate schemas on write" 71 | ] 72 | } 73 | }, 74 | "ClientSideData": { 75 | "QueryAPI": { 76 | "data": [ 77 | "Async", 78 | "Reactive queries" 79 | ] 80 | }, 81 | "LocalRefreshLatency": { 82 | "data": "~1ms" 83 | }, 84 | "PersistenceMechanism": { 85 | "data": [ 86 | "IndexedDB", 87 | "SQLite", 88 | "Custom" 89 | ], 90 | "comment": "Adapter for k-v stores." 91 | }, 92 | "PersistenceFeatures": { 93 | "data": "Transactions" 94 | }, 95 | "DataModel": { 96 | "data": "Relational" 97 | }, 98 | "SchemaManagement": { 99 | "data": [ 100 | "Derived types" 101 | ] 102 | }, 103 | "OfflineReads": { 104 | "data": "Query Cache", 105 | "comment": "Subscribed queries have full db support including novel queries" 106 | }, 107 | "OptimisticUpdates": { 108 | "data": "Yes" 109 | }, 110 | "OfflineWrites": { 111 | "data": "Cached offline writes" 112 | }, 113 | "DataSize": { 114 | "data": "limited by device capabilities" 115 | } 116 | }, 117 | "SynchronizationStrategy": { 118 | "FullOrPartialReplication": { 119 | "data": [ 120 | "Partial Replication" 121 | ] 122 | }, 123 | "ConflictHandling": { 124 | "data": "LWW at the attribute level" 125 | }, 126 | "WhereResolutionOccurs": { 127 | "data": "Server" 128 | }, 129 | "WhatGetsSynced": { 130 | "data": { 131 | "ClientToServer": "Minimal deltas", 132 | "ServerToClient": "Normalized query results, depuded across subscriptions then minimal deltas for changes" 133 | } 134 | }, 135 | "Authority": { 136 | "data": "Centralized" 137 | } 138 | }, 139 | "AuthIdentity": { 140 | "AuthenticationMethod": { 141 | "data": [ 142 | "JWT Tokens" 143 | ] 144 | }, 145 | "AuthorizationPermissions": { 146 | "data": "Custom mapping from token attributes to query filters" 147 | } 148 | }, 149 | "DevelopmentWorkflowsDX": { 150 | "DebuggingTools": { 151 | "data": [ 152 | "DevTools", 153 | "Network Inspector", 154 | "Data Inspector", 155 | "Dashboard" 156 | ] 157 | }, 158 | "CLI": { 159 | "data": "Yes" 160 | }, 161 | "TypeSupport": { 162 | "data": "Yes" 163 | } 164 | }, 165 | "__generated": { 166 | "lastUpdated": "2025-04-29T03:07:26.000Z" 167 | } 168 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/tinybase/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "tinybase", 4 | "Name": "TinyBase", 5 | "Description": "A reactive data store & sync engine.", 6 | "MaturityLevel": "Mature", 7 | "Logo": { 8 | "Light": "https://tinybase.org/favicon.svg", 9 | "Dark": "https://tinybase.org/favicon.svg" 10 | }, 11 | "Website": "https://tinybase.org", 12 | "GitHub": "https://github.com/tinyplex/tinybase", 13 | "InitialReleaseDate": "2022-01-17T00:00:00.000Z", 14 | "NotableAdopters": [ 15 | { 16 | "Name": "Athena Crisis", 17 | "URL": "https://athenacrisis.com" 18 | }, 19 | { 20 | "Name": "TinyHub", 21 | "URL": "https://tinyhub.org" 22 | } 23 | ], 24 | "Deployment": [ 25 | "Self-hosted" 26 | ], 27 | "License": "MIT", 28 | "AppTarget": { 29 | "Platform": { 30 | "data": [ 31 | "Browser", 32 | "Node", 33 | "React Native", 34 | "Deno", 35 | "Cloudflare Workers" 36 | ] 37 | }, 38 | "LanguageSDK": { 39 | "data": [ 40 | "TypeScript", 41 | "JavaScript" 42 | ] 43 | }, 44 | "FrameworkIntegrations": { 45 | "data": [ 46 | "React", 47 | "React Native" 48 | ] 49 | }, 50 | "ClientBundleSize": { 51 | "data": "5.3kB - 11.5kB", 52 | "comment": "The clue is in the name!" 53 | } 54 | }, 55 | "Networking": { 56 | "Protocol": { 57 | "data": [ 58 | "WebSockets", 59 | "HTTP" 60 | ] 61 | }, 62 | "Topology": { 63 | "data": "P2P via Relay Servers", 64 | "comment": "Client-server is also made possible by an API that lets the server participate as a peer." 65 | } 66 | }, 67 | "ServerSideData": { 68 | "PersistenceMechanism": { 69 | "data": [ 70 | "Cloudflare Durable Object Storage", 71 | "SQLite", 72 | "Postgres", 73 | "Custom" 74 | ] 75 | }, 76 | "DataSize": { 77 | "data": "Up to 5-10 MB per store", 78 | "comment": "The server can also use a database like SQLite or Postgres for larger data." 79 | }, 80 | "DataModelParadigm": { 81 | "data": "Relational", 82 | "comment": "Both relational and key-value data can be stored and synced." 83 | } 84 | }, 85 | "ClientSideData": { 86 | "QueryAPI": { 87 | "data": [ 88 | "Sync", 89 | "Reactive queries" 90 | ] 91 | }, 92 | "LocalRefreshLatency": { 93 | "data": "~1ms" 94 | }, 95 | "PersistenceMechanism": { 96 | "data": [ 97 | "SQLite", 98 | "IndexedDB", 99 | "PGLite via OPFS", 100 | "SQLite", 101 | "Yjs", 102 | "Custom" 103 | ] 104 | }, 105 | "PersistenceFeatures": { 106 | "data": "Indexes" 107 | }, 108 | "DataModel": { 109 | "data": "Document" 110 | }, 111 | "OfflineReads": { 112 | "data": "Full Support" 113 | }, 114 | "OfflineWrites": { 115 | "data": "Local conflict resolution" 116 | }, 117 | "DataSize": { 118 | "data": "Up to 5-10 MB per store" 119 | } 120 | }, 121 | "SynchronizationStrategy": { 122 | "FullOrPartialReplication": { 123 | "data": [ 124 | "Full Replication" 125 | ] 126 | }, 127 | "ConflictHandling": { 128 | "data": "Automatic via CRDT" 129 | }, 130 | "WhereResolutionOccurs": { 131 | "data": "Client", 132 | "comment": "Server can also resolve conflicts." 133 | }, 134 | "WhatGetsSynced": { 135 | "data": { 136 | "ClientToServer": "Cell- or value-level changes", 137 | "ServerToClient": "Cell- or value-level changes", 138 | "ClientToClient": "Cell- or value-level changes" 139 | } 140 | } 141 | }, 142 | "UIRelated": { 143 | "Components": { 144 | "data": [ 145 | "React", 146 | "ReactDom" 147 | ] 148 | } 149 | }, 150 | "DevelopmentWorkflowsDX": { 151 | "DebuggingTools": { 152 | "data": [ 153 | "Data Inspector" 154 | ] 155 | }, 156 | "TypeSupport": { 157 | "data": "TypeScript, inferred from Schemas" 158 | } 159 | }, 160 | "__generated": { 161 | "lastUpdated": "2025-04-18T20:59:16.000Z" 162 | } 163 | } -------------------------------------------------------------------------------- /temporary-technology-info/ditto/data.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { LandscapeSchema } from '@localfirstfm/landscape-schema' 3 | 4 | export const data = LandscapeSchema.make({ 5 | Version: 1, 6 | Id: 'ditto', 7 | Name: 'Ditto', 8 | Description: 9 | 'Real-time, peer-to-peer data synchronization across devices and platforms without relying on the cloud, even in offline or unreliable network conditions.', 10 | Website: 'https://ditto.live', 11 | Deployment: ['Hosted', 'Self-hosted'], 12 | License: 'Proprietary', 13 | Logo: { 14 | Light: 'https://path-to-light-logo.png', 15 | Dark: 'https://path-to-dark-logo.png', 16 | }, 17 | AppTarget: { 18 | Platform: { 19 | data: ['Browser', 'iOS', 'Android', 'macOS', 'WASM'], 20 | }, 21 | LanguageSDK: { 22 | data: ['Swift', 'Kotlin', 'JavaScript', 'C#', 'c++', 'Java'], 23 | }, 24 | FrameworkIntegrations: { 25 | data: ['React Native', 'Flutter', 'Jetpack Compose', 'SwiftUI'], 26 | }, 27 | }, 28 | Networking: { 29 | Protocol: { 30 | data: ['WiFi LAN', 'Bluetooth', 'P2P WiFi', 'TCP', 'HTTP', 'WebSockets'], 31 | comment: `We've developed an intelligent sync system that automatically discovers local devices, establishes a connection, and seamlessly switches between active transports when syncing data (Bluetooth, P2P WiFi, LAN, Websockets) so that if one transport goes down, it automatically switches to the next best one, optimizing for speed. "Resilient Networking" in this context means networking that can network in any environment and dynamically "heal" itself if connections break`, 32 | }, 33 | Topology: { 34 | data: 'P2P', 35 | }, 36 | }, 37 | ServerSideData: { 38 | PersistenceMechanism: { 39 | data: ['Custom'], 40 | }, 41 | DataModelParadigm: { 42 | data: 'Document', 43 | }, 44 | ExistingDatabaseSupport: { 45 | data: 'HTTP/Webhooks and real-time via CDC Connectors (Kafka-based)', 46 | }, 47 | DataSize: { 48 | data: 'No theoretical limit', 49 | comment: 50 | 'No theoretical limit, due to cloud scaling, but we offer benchmarking and performance services to validate & scale cloud resources for larger use cases.', 51 | }, 52 | }, 53 | ClientSideData: { 54 | QueryAPI: { 55 | data: ['Async'], 56 | }, 57 | LocalRefreshLatency: { 58 | data: '10ms-2s', 59 | comment: 60 | 'Depends on cardinality, query optimization plan, and local data size.', 61 | }, 62 | PersistenceMechanism: { 63 | data: ['SQLite'], 64 | }, 65 | DataModel: { 66 | data: 'Document', 67 | comment: 'Queries are SQL, records are document-oriented.', 68 | }, 69 | OfflineReads: { 70 | data: 'Full Support', 71 | }, 72 | OfflineWrites: { 73 | data: 'Full local conflict resolution', 74 | }, 75 | DataSize: { 76 | data: 'up to the size of the hard drive', 77 | }, 78 | }, 79 | SynchronizationStrategy: { 80 | FullOrPartialReplication: { 81 | data: ['Full Replication', 'Partial Replication'], 82 | }, 83 | ConflictHandling: { 84 | data: 'Automatic via CRDT', 85 | }, 86 | WhereResolutionOccurs: { 87 | data: 'Client', 88 | }, 89 | WhatGetsSynced: { 90 | data: { 91 | ClientToClient: 'document deltas', 92 | }, 93 | comment: 94 | 'Ditto has client-to-client deltas, and the server is running the same CRDT as the client, and is not required.', 95 | }, 96 | Authority: { 97 | data: 'Decentralized', 98 | comment: 'Decentralized via authentication servers.', 99 | }, 100 | }, 101 | AuthIdentity: { 102 | Encryption: { 103 | data: 'Built-in e2ee', 104 | }, 105 | AuthenticationMethod: { 106 | data: ['JWT Tokens'], 107 | }, 108 | AuthorizationPermissions: { 109 | data: 'Custom-mapped ACLs', 110 | }, 111 | }, 112 | UIRelated: { 113 | Components: { 114 | data: ['Presence'], 115 | comment: 116 | 'SDK provides which peers you are connected to, and over what transports.', 117 | }, 118 | }, 119 | DevelopmentWorkflowsDX: { 120 | DebuggingTools: { 121 | data: ['DevTools', 'Data Inspector', 'Network Inspector'], 122 | comment: 'Open source debugging and diagnostic tools for developers.', 123 | }, 124 | }, 125 | }) 126 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/nextgraph/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "nextgraph", 4 | "Name": "NextGraph", 5 | "Description": "Decentralized and local-first web 3.0 ecosystem (everything apps and framework/SDK)", 6 | "MaturityLevel": "Alpha", 7 | "Website": "https://nextgraph.org", 8 | "GitHub": "https://git.nextgraph.org/NextGraph/nextgraph-rs", 9 | "UniquenessNote": "convergence of Linked Data, P2P, and local-first", 10 | "InitialReleaseDate": "2024-09-02T00:00:00.000Z", 11 | "Deployment": [ 12 | "Self-hosted", 13 | "Hosted" 14 | ], 15 | "License": "MIT", 16 | "AppTarget": { 17 | "Platform": { 18 | "data": [ 19 | "Browser", 20 | "Node", 21 | "iOS", 22 | "Android", 23 | "macOS", 24 | "WASM", 25 | "Linux" 26 | ] 27 | }, 28 | "LanguageSDK": { 29 | "data": [ 30 | "TypeScript", 31 | "JavaScript", 32 | "Rust", 33 | "Python" 34 | ] 35 | }, 36 | "FrameworkIntegrations": { 37 | "data": [ 38 | "React", 39 | "Svelte" 40 | ] 41 | }, 42 | "ClientBundleSize": { 43 | "data": "4 kB compressed", 44 | "comment": "not including Automerge or Yjs dependencies" 45 | } 46 | }, 47 | "Networking": { 48 | "Protocol": { 49 | "data": [ 50 | "WebSockets" 51 | ] 52 | }, 53 | "Topology": { 54 | "data": "P2P via Relay Servers" 55 | } 56 | }, 57 | "ServerSideData": { 58 | "PersistenceMechanism": { 59 | "data": [ 60 | "Custom" 61 | ] 62 | }, 63 | "DataModelParadigm": { 64 | "data": "Document", 65 | "comment": "Document-oriented and graph (RDF)" 66 | } 67 | }, 68 | "ClientSideData": { 69 | "QueryAPI": { 70 | "data": [ 71 | "Async", 72 | "Sync", 73 | "Signals-based Reactivity" 74 | ] 75 | }, 76 | "PersistenceMechanism": { 77 | "data": [ 78 | "Yjs", 79 | "OPFS", 80 | "RocksDB" 81 | ] 82 | }, 83 | "PersistenceFeatures": { 84 | "data": "Indexes", 85 | "comment": "also with Full-text search and Transactions" 86 | }, 87 | "DataModel": { 88 | "data": "Document", 89 | "comment": "Document-oriented and graph (RDF)" 90 | }, 91 | "SchemaManagement": { 92 | "data": [ 93 | "Schema definition", 94 | "Schema validation on write" 95 | ] 96 | }, 97 | "OfflineReads": { 98 | "data": "Full Support" 99 | }, 100 | "OptimisticUpdates": { 101 | "data": "Yes" 102 | }, 103 | "OfflineWrites": { 104 | "data": "Local conflict resolution" 105 | } 106 | }, 107 | "SynchronizationStrategy": { 108 | "FullOrPartialReplication": { 109 | "data": [ 110 | "Full Replication", 111 | "Partial Replication" 112 | ] 113 | }, 114 | "ConflictHandling": { 115 | "data": "Automatic via CRDT", 116 | "comment": "supports Automerge, Yjs and RDF" 117 | }, 118 | "WhereResolutionOccurs": { 119 | "data": "Client" 120 | }, 121 | "WhatGetsSynced": { 122 | "data": { 123 | "ClientToClient": "Commits" 124 | } 125 | }, 126 | "Authority": { 127 | "data": "Decentralized" 128 | } 129 | }, 130 | "AuthIdentity": { 131 | "Encryption": { 132 | "data": "Yes", 133 | "comment": "end-to-end encryption + encryption at rest" 134 | }, 135 | "AuthenticationMethod": { 136 | "data": [ 137 | "Built-in", 138 | "Public keys" 139 | ] 140 | }, 141 | "AuthorizationPermissions": { 142 | "data": "Cryptographic Capabilities" 143 | } 144 | }, 145 | "UIRelated": { 146 | "RichTextEditing": { 147 | "data": "Yes" 148 | }, 149 | "Components": { 150 | "data": [ 151 | "reusable Editors", 152 | "reusable Viewers", 153 | "Auth with Wallet", 154 | "Malleable software" 155 | ] 156 | } 157 | }, 158 | "DevelopmentWorkflowsDX": { 159 | "CLI": { 160 | "data": "Command line interface tools for developers and end-users" 161 | }, 162 | "TypeSupport": { 163 | "data": "type support via LDO" 164 | } 165 | }, 166 | "__generated": { 167 | "lastUpdated": "2025-04-29T14:47:05.000Z" 168 | } 169 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/livestore/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "livestore", 4 | "Name": "LiveStore", 5 | "Description": "Client-centric local-first data layer for high-performance apps", 6 | "MaturityLevel": "Beta", 7 | "Website": "https://livestore.dev", 8 | "GitHub": "https://github.com/livestore-dev/livestore", 9 | "GetStarted": "https://livestore.dev", 10 | "InitialReleaseDate": "2021-12-01T00:00:00.000Z", 11 | "Deployment": [ 12 | "Self-hosted" 13 | ], 14 | "AppTarget": { 15 | "Platform": { 16 | "data": [ 17 | "Browser", 18 | "Node", 19 | "iOS", 20 | "Android" 21 | ] 22 | }, 23 | "LanguageSDK": { 24 | "data": [ 25 | "TypeScript" 26 | ] 27 | }, 28 | "FrameworkIntegrations": { 29 | "data": [ 30 | "React", 31 | "React Native", 32 | "Solid" 33 | ] 34 | }, 35 | "ClientBundleSize": { 36 | "data": "~500kb gzipped", 37 | "comment": "For web apps, LiveStore ships with a SQLite WASM build (~600kb / 300kb gzipped) and the library itself is around 500kb / 170kb gzipped." 38 | } 39 | }, 40 | "Networking": { 41 | "Protocol": { 42 | "data": [ 43 | "WebSockets", 44 | "HTTP", 45 | "SSE" 46 | ], 47 | "comment": "Given LiveStore supports arbitrary sync backends, any kind of network protocol can be used." 48 | }, 49 | "Topology": { 50 | "data": "Client-Server" 51 | } 52 | }, 53 | "ServerSideData": { 54 | "PersistenceMechanism": { 55 | "data": [ 56 | "Cloudflare D1", 57 | "Postgres", 58 | "SQLite", 59 | "Custom" 60 | ], 61 | "comment": "Almost anything works as long as it can persist an eventlog." 62 | }, 63 | "DataSize": { 64 | "data": "10GB", 65 | "comment": "Theoretically there isn't an upper limit to the eventlog size however at some point it might become impractical to sync the eventlog over the network." 66 | }, 67 | "DataModelParadigm": { 68 | "data": "Eventlog" 69 | } 70 | }, 71 | "ClientSideData": { 72 | "QueryAPI": { 73 | "data": [ 74 | "Reactive queries", 75 | "Signals-based Reactivity", 76 | "Sync" 77 | ] 78 | }, 79 | "LocalRefreshLatency": { 80 | "data": "~1ms", 81 | "comment": "LiveStore is designed to enable next-frame refresh latency by using an in-memory SQLite database with a signals-based reactivivity system." 82 | }, 83 | "PersistenceMechanism": { 84 | "data": [ 85 | "IndexedDB", 86 | "OPFS" 87 | ] 88 | }, 89 | "PersistenceFeatures": { 90 | "data": "Indexes" 91 | }, 92 | "DataModel": { 93 | "data": "Event Sourcing", 94 | "comment": "LiveStore follows the event sourcing pattern which separates writes into an eventlog and materializes state into a local SQLite database." 95 | }, 96 | "OfflineReads": { 97 | "data": "Full Support" 98 | }, 99 | "OptimisticUpdates": { 100 | "data": "Yes", 101 | "comment": "There isn't an explicit concept of \"optimistic updates\" in LiveStore. Events are always executed locally first and then synced to other clients. In case of a conflict, the event is rebased and replayed. This is similar to how Git works." 102 | }, 103 | "OfflineWrites": { 104 | "data": "Local conflict resolution" 105 | }, 106 | "DataSize": { 107 | "data": "<1GB", 108 | "comment": "The upper limit is mostly determined by the used browser or client device. SQLite stores data fairly efficiently, so you should rarely hit any limits in regards to size." 109 | } 110 | }, 111 | "SynchronizationStrategy": { 112 | "FullOrPartialReplication": { 113 | "data": [ 114 | "Full Replication" 115 | ] 116 | }, 117 | "ConflictHandling": { 118 | "data": "Automatic via CRDT" 119 | }, 120 | "WhereResolutionOccurs": { 121 | "data": "Client" 122 | }, 123 | "WhatGetsSynced": { 124 | "data": { 125 | "ClientToClient": "Ops" 126 | } 127 | } 128 | }, 129 | "DevelopmentWorkflowsDX": { 130 | "DebuggingTools": { 131 | "data": [ 132 | "DevTools", 133 | "Data Inspector", 134 | "Network Inspector" 135 | ] 136 | } 137 | }, 138 | "__generated": { 139 | "lastUpdated": "2025-04-29T14:51:46.000Z" 140 | } 141 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/electricsql/details.md: -------------------------------------------------------------------------------- 1 | ## General 2 | 3 | Electric is a [Postgres sync engine](https://electric-sql.com). It syncs data out of Postgres into anything you like. 4 | 5 | Electric handles read-path sync, [partial replication](https://electric-sql.com/docs/guides/shapes), [fan-out](https://electric-sql.com/docs/api/http#caching), and [data delivery](https://electric-sql.com/docs/api/http). So you can build fast, modern software on live, local data — without rolling your own sync engine. 6 | 7 | Electric works with [any Postgres](https://electric-sql.com/docs/guides/deployment#_1-running-postgres), [any data model](https://electric-sql.com/docs/guides/deployment#data-model-compatibility) and [any web framework](https://electric-sql.com/docs/guides/client-development). Data syncs [over HTTP](https://electric-sql.com/docs/api/http), allowing you to use your existing API and web stack to handle auth, writes and any arbitrary stream transformation. Because it's HTTP, it works with standard CDNs, allowing you to easily scale out low-latancy data delivery to [millions of concurrent clients](https://electric-sql.com/docs/reference/benchmarks#cloud). 8 | 9 | 10 | 11 | ## The Story 12 | 13 | Electric was founded by [James Arthur and Valter Balegas](https://electric-sql.com/about/team), in collaboration with two of the inventors of CRDTs, Marc Shapiro and Nuno Preguiça; and Annette Bieniusa, a world expert on distributed database technology. Kyle Mathews joined as the third founder in 2024, having previously built and sold Gatsby to Netlify. 14 | 15 | The original vision for Electric was to build on [research advances in eventually consistent database technology](https://electric-sql.com/docs/reference/literature) to build a next-generation geo-distributed database for the "AP" side of the CAP theorem. The team quickly pivoted to using the same techniques to provide a replication layer for existing open source databases and then focused on building an end-to-end local-first software stack as the killer app for this. 16 | 17 | When Kyle joined, he led a [clean re-write](https://electric-sql.com/blog/2024/07/17/electric-next) to simplify Electric and build a core system that worked well for read-path sync. This pushed a lot of complexity out of scope which, combined with the experience the team had gained building previous iterations, allowed Electric to quickly build a highly-scalable read-path sync engine based based on a [new HTTP protocol](https://electric-sql.com/docs/api/http). 18 | 19 | This new system [hit BETA](https://electric-sql.com/blog/2024/12/10/electric-beta-release) in December 2025 and [GA with a 1.0 release](https://electric-sql.com/blog/2025/03/17/electricsql-1.0-released) on the 17th March 2025. 20 | 21 | Electric is a funded startup, backed by VCs including [Spark Captial](https://www.sparkcapital.com), [Lunar Ventures](https://www.lunar.vc) and [StepFunction](https://www.stepfunction.vc). They are also backed by a range of leading database and devtools founders, including the founders of Supabase, Motherduck, Cockroach, Xata, Nile, Heroku and Ink & Switch and leading angels like Theo Brown and Chris Riccomini. 22 | 23 | The core technology of Electric is developed in Elixir and the company is also backed by José Valim, the creator of Elixir and integrated into Phoenix, the main Elixir web framework as [Phoenix.Sync](https://hexdocs.pm/phoenix_sync). Other notable framework integrations include [LiveStore](LiveStore.dev) and [@TanStack/optimistic](https://github.com/TanStack/optimistic). 24 | 25 | Electric also develop the popular [PGlite](https://pglite.dev) project, a lightweight embeddable Postgres database that can be used in the browser. The two products (the Electric sync engine and the PGlite database) can be used together or independently and are now built into leading developer tools such as Google's [Firebase Tools](https://www.npmjs.com/package/firebase-tools?activeTab=dependencies) and Supabase's AI project builder [database.build](https://database.build). 26 | 27 | ## Resources 28 | 29 | Electric is an open source project published on GitHub as [electric-sql/electric](https://github.com/electric-sql/electric). Everything is Apache 2.0 licensed. There's an open Discord community at [discord.electric-sql.com](https://discord.electric-sql.com) and the PGlite project has a separate website at [pglite.dev](https://pglite.dev). 30 | 31 | - [Website](https://electric-sql.com) 32 | - [Docs](https://electric-sql.com/docs/intro) 33 | - [GitHub](https://github.com/electric-sql/electric) 34 | - [Discord](https://discord.electric-sql.com) 35 | - [Bluesky](https://bsky.app/profile/electric-sql.com) 36 | - [PGlite](https://pglite.dev) 37 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/convex/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "convex", 4 | "Name": "Convex", 5 | "Description": "Convex is the open source, reactive database where queries are TypeScript code running right in the database. Just like React components react to state changes, Convex queries react to database changes.", 6 | "MaturityLevel": "Production-Ready", 7 | "Logo": { 8 | "Light": "https://static.convex.dev/logo/convex-logo.svg", 9 | "Dark": "https://static.convex.dev/logo/convex-logo-light.svg" 10 | }, 11 | "Website": "https://convex.dev", 12 | "GitHub": "https://github.com/get-convex/convex-backend", 13 | "GetStarted": "https://docs.convex.dev/tutorial/", 14 | "Deployment": [ 15 | "Self-hosted", 16 | "Hosted" 17 | ], 18 | "License": "FSL-1.1-Apache-2.0", 19 | "AppTarget": { 20 | "Platform": { 21 | "data": [ 22 | "Browser", 23 | "Node", 24 | "iOS", 25 | "Android", 26 | "macOS", 27 | "Linux" 28 | ] 29 | }, 30 | "LanguageSDK": { 31 | "data": [ 32 | "TypeScript", 33 | "JavaScript", 34 | "Kotlin", 35 | "Python", 36 | "Rust", 37 | "Swift" 38 | ] 39 | }, 40 | "FrameworkIntegrations": { 41 | "data": [ 42 | "Next.js", 43 | "Tanstack Start", 44 | "React", 45 | "React Native", 46 | "Svelte", 47 | "SwiftUI", 48 | "Vue", 49 | "Flutter" 50 | ] 51 | }, 52 | "ClientBundleSize": { 53 | "data": "~120KiB" 54 | } 55 | }, 56 | "Networking": { 57 | "Protocol": { 58 | "data": [ 59 | "WebSockets", 60 | "HTTP" 61 | ] 62 | }, 63 | "Topology": { 64 | "data": "Client-Server" 65 | } 66 | }, 67 | "ServerSideData": { 68 | "PersistenceMechanism": { 69 | "data": [ 70 | "Custom", 71 | "MySQL", 72 | "PostgreSQL", 73 | "SQLite" 74 | ] 75 | }, 76 | "DataModelParadigm": { 77 | "data": "Relational" 78 | }, 79 | "SchemaManagement": { 80 | "data": [ 81 | "Schema definition", 82 | "Validate schemas on write" 83 | ] 84 | } 85 | }, 86 | "ClientSideData": { 87 | "QueryAPI": { 88 | "data": [ 89 | "Reactive queries", 90 | "Async" 91 | ] 92 | }, 93 | "LocalRefreshLatency": { 94 | "data": "~10-100ms" 95 | }, 96 | "PersistenceMechanism": { 97 | "data": [] 98 | }, 99 | "PersistenceFeatures": { 100 | "data": "Transactions" 101 | }, 102 | "DataModel": { 103 | "data": "Relational" 104 | }, 105 | "DataSize": { 106 | "data": "Up to 1 MB per document" 107 | } 108 | }, 109 | "SynchronizationStrategy": { 110 | "FullOrPartialReplication": { 111 | "data": [ 112 | "Partial Replication" 113 | ] 114 | }, 115 | "ConflictHandling": { 116 | "data": "Custom conflict resolution supported" 117 | }, 118 | "WhereResolutionOccurs": { 119 | "data": "Server" 120 | }, 121 | "WhatGetsSynced": { 122 | "data": { 123 | "ClientToServer": "Mutations", 124 | "ServerToClient": "Query functions" 125 | } 126 | }, 127 | "Authority": { 128 | "data": "Centralized" 129 | }, 130 | "Latency": { 131 | "data": "~100ms" 132 | }, 133 | "Throughput": { 134 | "data": "10000 writes/sec" 135 | }, 136 | "Concurrency": { 137 | "data": "1M concurrent users" 138 | } 139 | }, 140 | "AuthIdentity": { 141 | "Encryption": { 142 | "data": "Yes", 143 | "comment": "All data is encrypted at rest for the hosted product" 144 | }, 145 | "AuthenticationMethod": { 146 | "data": [ 147 | "Built-in", 148 | "JWT Tokens" 149 | ] 150 | }, 151 | "AuthorizationPermissions": { 152 | "data": "Custom" 153 | } 154 | }, 155 | "UIRelated": { 156 | "RichTextEditing": { 157 | "data": "Yes", 158 | "comment": "https://www.convex.dev/components/prosemirror-sync" 159 | } 160 | }, 161 | "DevelopmentWorkflowsDX": { 162 | "DebuggingTools": { 163 | "data": [ 164 | "Dashboard" 165 | ] 166 | }, 167 | "CLI": { 168 | "data": "Yes" 169 | }, 170 | "TypeSupport": { 171 | "data": "Yes", 172 | "comment": "End to-end type safety from the schema to functions to the client" 173 | } 174 | }, 175 | "__generated": { 176 | "lastUpdated": "2025-04-14T22:29:55.000Z" 177 | } 178 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/dxos/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "dxos", 4 | "Name": "DXOS", 5 | "Description": "DXOS is an open source framework for building real-time, collaborative web applications.", 6 | "Website": "https://dxos.org", 7 | "Deployment": [ 8 | "Self-hosted" 9 | ], 10 | "License": "MIT", 11 | "AppTarget": { 12 | "Platform": { 13 | "data": [ 14 | "Browser", 15 | "Node" 16 | ] 17 | }, 18 | "LanguageSDK": { 19 | "data": [ 20 | "TypeScript" 21 | ] 22 | } 23 | }, 24 | "Networking": { 25 | "Protocol": { 26 | "data": [ 27 | "WebRTC", 28 | "WebSockets" 29 | ], 30 | "comment": "P2P connections are made via WebRTC, and client-server connections are made via WebSockets." 31 | }, 32 | "Topology": { 33 | "data": "P2P", 34 | "comment": "Always available data optionally provided by server-based peers." 35 | } 36 | }, 37 | "ServerSideData": { 38 | "PersistenceMechanism": { 39 | "data": [ 40 | "N/A" 41 | ] 42 | }, 43 | "DataModelParadigm": { 44 | "data": "Document" 45 | } 46 | }, 47 | "ClientSideData": { 48 | "QueryAPI": { 49 | "data": [ 50 | "Async", 51 | "Signals-based Reactivity" 52 | ] 53 | }, 54 | "LocalRefreshLatency": { 55 | "data": "10-50ms", 56 | "comment": "Data is stored as Automerge documents under the hood." 57 | }, 58 | "PersistenceMechanism": { 59 | "data": [ 60 | "IndexedDB" 61 | ] 62 | }, 63 | "PersistenceFeatures": { 64 | "data": "Indexes", 65 | "comment": "Custom indexes coming soon." 66 | }, 67 | "DataModel": { 68 | "data": "Document" 69 | }, 70 | "SchemaManagement": { 71 | "data": [ 72 | "Schema definition", 73 | "Schema migrations", 74 | "Schema validation on write" 75 | ], 76 | "comment": "Schemas are defined using Effect Schema, and are validated on write. Migrations are supported at the object level." 77 | }, 78 | "OfflineReads": { 79 | "data": "Full Support" 80 | }, 81 | "OptimisticUpdates": { 82 | "data": "Yes" 83 | }, 84 | "OfflineWrites": { 85 | "data": "Full local conflict resolution" 86 | }, 87 | "DataSize": { 88 | "data": "up to 5-10mb per object", 89 | "comment": "Objects are Automerge documents under the hood." 90 | } 91 | }, 92 | "SynchronizationStrategy": { 93 | "FullOrPartialReplication": { 94 | "data": [ 95 | "Full Replication" 96 | ], 97 | "comment": "Full replication of all spaces joined per identity." 98 | }, 99 | "ConflictHandling": { 100 | "data": "Automatic via CRDT", 101 | "comment": "Automerge is the CRDT used under the hood." 102 | }, 103 | "WhereResolutionOccurs": { 104 | "data": "Client" 105 | }, 106 | "WhatGetsSynced": { 107 | "data": { 108 | "ClientToClient": "see Automerge" 109 | }, 110 | "comment": "Automerge is the CRDT used under the hood." 111 | }, 112 | "Authority": { 113 | "data": "Decentralized" 114 | } 115 | }, 116 | "AuthIdentity": { 117 | "Encryption": { 118 | "data": "Transport-level encryption", 119 | "comment": "Data is not currently encrypted at rest. E2EE is planned via Keyhive." 120 | }, 121 | "AuthenticationMethod": { 122 | "data": [ 123 | "Public keys" 124 | ] 125 | }, 126 | "AuthorizationPermissions": { 127 | "data": "RBAC" 128 | } 129 | }, 130 | "UIRelated": { 131 | "RichTextEditing": { 132 | "data": "Yes", 133 | "comment": "Anything compatible with Automerge documents (e.g. CodeMirror, ProseMirror, etc.)" 134 | }, 135 | "Components": { 136 | "data": [ 137 | "Invitations", 138 | "Presence" 139 | ], 140 | "comment": "React components for performing invitations are provided. SDK provides which peers you are connected to." 141 | } 142 | }, 143 | "DevelopmentWorkflowsDX": { 144 | "DebuggingTools": { 145 | "data": [ 146 | "DevTools", 147 | "Data Inspector", 148 | "Network Inspector" 149 | ] 150 | }, 151 | "CLI": { 152 | "data": "CLI which contains a full client and commands for managing identities, spaces, etc." 153 | }, 154 | "TypeSupport": { 155 | "data": "Full type support via Effect Schema" 156 | } 157 | }, 158 | "__generated": { 159 | "lastUpdated": "2025-04-26T18:46:14.000Z" 160 | } 161 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-yjs/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "liveblocks-yjs", 4 | "Name": "Liveblocks Yjs", 5 | "MaturityLevel": "Production-ready", 6 | "Website": "https://liveblocks.io/sync-datastore/yjs", 7 | "InitialReleaseDate": "2023-09-05T00:00:00.000Z", 8 | "Deployment": [ 9 | "Hosted" 10 | ], 11 | "License": "Proprietary", 12 | "AppTarget": { 13 | "Platform": { 14 | "data": [ 15 | "Browser", 16 | "Node" 17 | ] 18 | }, 19 | "LanguageSDK": { 20 | "data": [ 21 | "TypeScript" 22 | ] 23 | }, 24 | "FrameworkIntegrations": { 25 | "data": [ 26 | "React" 27 | ] 28 | } 29 | }, 30 | "Networking": { 31 | "Protocol": { 32 | "data": [ 33 | "WebSockets", 34 | "HTTP" 35 | ] 36 | }, 37 | "Topology": { 38 | "data": "Client-Server" 39 | } 40 | }, 41 | "ServerSideData": { 42 | "PersistenceMechanism": { 43 | "data": [ 44 | "Cloudflare Durable Object Storage", 45 | "IndexedDB" 46 | ] 47 | }, 48 | "DataModelParadigm": { 49 | "data": "Document", 50 | "comment": "Each room is a digital space where people colalborate, and it corresponds with a document." 51 | }, 52 | "SchemaManagement": { 53 | "data": [ 54 | "None" 55 | ] 56 | }, 57 | "ExistingDatabaseSupport": { 58 | "data": "One-way sync with DBs", 59 | "comment": "Does not require a datastore, but you can migrate or automatically sync to your database with webhooks/REST API" 60 | } 61 | }, 62 | "ClientSideData": { 63 | "QueryAPI": { 64 | "data": [ 65 | "Yjs" 66 | ], 67 | "comment": "Standard Yjs API" 68 | }, 69 | "LocalRefreshLatency": { 70 | "data": "<1ms", 71 | "comment": "Changes on the client: <1ms. Other clients receive updates up to 60 times per second(16ms), configurable." 72 | }, 73 | "PersistenceMechanism": { 74 | "data": [ 75 | "Yjs" 76 | ] 77 | }, 78 | "DataModel": { 79 | "data": "Document" 80 | }, 81 | "SchemaManagement": { 82 | "data": [ 83 | "None" 84 | ] 85 | }, 86 | "OfflineReads": { 87 | "data": "Yes", 88 | "comment": "Beta option: `offlineSupport_experimental: true`" 89 | }, 90 | "OptimisticUpdates": { 91 | "data": "Yes" 92 | }, 93 | "OfflineWrites": { 94 | "data": "Yes", 95 | "comment": "Beta option: `offlineSupport_experimental: true`" 96 | }, 97 | "DataSize": { 98 | "data": "Limited by memory", 99 | "comment": "It depends on the in memory size of the Yjs store and the history of the document." 100 | } 101 | }, 102 | "SynchronizationStrategy": { 103 | "ConflictHandling": { 104 | "data": "Automatic via CRDT" 105 | }, 106 | "WhereResolutionOccurs": { 107 | "data": "Server" 108 | }, 109 | "WhatGetsSynced": { 110 | "data": { 111 | "ClientToServer": "Yjs encoded updates" 112 | } 113 | }, 114 | "Authority": { 115 | "data": "Centralized" 116 | } 117 | }, 118 | "AuthIdentity": { 119 | "AuthenticationMethod": { 120 | "data": [ 121 | "Built-in", 122 | "Full Custom" 123 | ] 124 | }, 125 | "AuthorizationPermissions": { 126 | "data": "ID tokens and access tokens", 127 | "comment": "ID tokens for permissions based on a per-room basis. Access tokens for permissions granted directly in the token" 128 | } 129 | }, 130 | "UIRelated": { 131 | "RichTextEditing": { 132 | "data": "Liveblocks Text Editor", 133 | "comment": "Wrapper around Yjs with TipTap, BlockNote, and Lexical plugins." 134 | }, 135 | "Components": { 136 | "data": [ 137 | "Comments/Threads", 138 | "Notifications", 139 | "AI Copilots", 140 | "Yjs plugins", 141 | "Presence" 142 | ], 143 | "comment": "All Liveblocks products integrate into each other. Learn more about the other products on [liveblocks.io](https://liveblocks.io)." 144 | } 145 | }, 146 | "DevelopmentWorkflowsDX": { 147 | "DebuggingTools": { 148 | "data": [ 149 | "DevTools", 150 | "Dashboard", 151 | "Data Inspector" 152 | ], 153 | "comment": "Viewing/editing data, events, usage, etc." 154 | }, 155 | "CLI": { 156 | "data": "CLI for installing examples, updating packages, creating your typescript config." 157 | } 158 | }, 159 | "__generated": { 160 | "lastUpdated": "2025-04-24T11:47:23.000Z" 161 | } 162 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/instant/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "instant", 4 | "Name": "InstantDB", 5 | "Description": "Instant is a modern Firebase. We make you productive by giving your frontend a real-time database.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://instantdb.com", 8 | "GitHub": "https://github.com/instantdb/instant", 9 | "GetStarted": "https://www.instantdb.com/tutorial", 10 | "Deployment": [ 11 | "Self-hosted", 12 | "Hosted" 13 | ], 14 | "License": "Apache", 15 | "AppTarget": { 16 | "Platform": { 17 | "data": [ 18 | "Browser", 19 | "Node", 20 | "iOS", 21 | "Android", 22 | "Desktop" 23 | ], 24 | "comment": "iOS and Android support via React native. Desktop via Electron and Tauri" 25 | }, 26 | "LanguageSDK": { 27 | "data": [ 28 | "TypeScript", 29 | "JavaScript" 30 | ] 31 | }, 32 | "FrameworkIntegrations": { 33 | "data": [ 34 | "React", 35 | "React Native" 36 | ] 37 | }, 38 | "ClientBundleSize": { 39 | "data": "~27kb gzipped" 40 | } 41 | }, 42 | "Networking": { 43 | "Protocol": { 44 | "data": [ 45 | "WebSockets", 46 | "HTTP" 47 | ] 48 | }, 49 | "Topology": { 50 | "data": "Client-Server" 51 | } 52 | }, 53 | "ServerSideData": { 54 | "PersistenceMechanism": { 55 | "data": [ 56 | "Postgres" 57 | ], 58 | "comment": "Support for bring your postgres coming" 59 | }, 60 | "DataModelParadigm": { 61 | "data": "Relational" 62 | }, 63 | "SchemaManagement": { 64 | "data": [ 65 | "Schema definition", 66 | "Validate schemas on write" 67 | ] 68 | } 69 | }, 70 | "ClientSideData": { 71 | "QueryAPI": { 72 | "data": [ 73 | "Async", 74 | "Reactive queries" 75 | ] 76 | }, 77 | "LocalRefreshLatency": { 78 | "data": "~1ms" 79 | }, 80 | "PersistenceMechanism": { 81 | "data": [ 82 | "IndexedDB" 83 | ] 84 | }, 85 | "PersistenceFeatures": { 86 | "data": "Indexes, Transactions" 87 | }, 88 | "DataModel": { 89 | "data": "Relational" 90 | }, 91 | "OfflineReads": { 92 | "data": "Query Cache" 93 | }, 94 | "OptimisticUpdates": { 95 | "data": "Yes" 96 | }, 97 | "OfflineWrites": { 98 | "data": "Queued offline writes" 99 | }, 100 | "DataSize": { 101 | "data": "Limited by device capabilities" 102 | } 103 | }, 104 | "SynchronizationStrategy": { 105 | "FullOrPartialReplication": { 106 | "data": [ 107 | "Partial Replication" 108 | ], 109 | "comment": "Use InstaQL queries to control which data is replicated" 110 | }, 111 | "ConflictHandling": { 112 | "data": "Last write wins at attribute level" 113 | }, 114 | "WhereResolutionOccurs": { 115 | "data": "Server" 116 | }, 117 | "WhatGetsSynced": { 118 | "data": { 119 | "ClientToServer": "Mutations", 120 | "ServerToClient": "Rows" 121 | }, 122 | "comment": "\"Mutations\" are instant logical operations `update`, `delete`. \"Rows\" are data that the client side engine uses to fulfill queries" 123 | }, 124 | "Authority": { 125 | "data": "Centralized" 126 | }, 127 | "Latency": { 128 | "data": "Close to network latency" 129 | }, 130 | "Throughput": { 131 | "data": "Hundreds of writes per second", 132 | "comment": "This is based on early 2025 usage." 133 | }, 134 | "Concurrency": { 135 | "data": "Effectively unlimited", 136 | "comment": "Server is horizontally scalable and shared-nothing. Running on top of Aurora. To see live connections go to instantdb.com" 137 | } 138 | }, 139 | "AuthIdentity": { 140 | "Encryption": { 141 | "data": "no" 142 | }, 143 | "AuthenticationMethod": { 144 | "data": [ 145 | "JWT Tokens" 146 | ] 147 | }, 148 | "AuthorizationPermissions": { 149 | "data": "Custom", 150 | "comment": "Permissions are defined using Instant's Rule Language which is builds on top of Google's CEL. For more details see: https://instantdb.com/docs/permissions" 151 | } 152 | }, 153 | "DevelopmentWorkflowsDX": { 154 | "DebuggingTools": { 155 | "data": [ 156 | "DevTools", 157 | "Data Inspector", 158 | "Dashboard" 159 | ] 160 | }, 161 | "CLI": { 162 | "data": "Yes" 163 | }, 164 | "TypeSupport": { 165 | "data": "Yes" 166 | } 167 | }, 168 | "__generated": { 169 | "lastUpdated": "2025-08-31T00:10:48.000Z" 170 | } 171 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/automerge/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "automerge", 4 | "Name": "Automerge", 5 | "Description": "Automerge enables local first applications by providing generic version control for JSON documents", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://automerge.org", 8 | "GitHub": "https://github.com/automerge/automerge", 9 | "GetStarted": "https://automerge.org/docs/hello/", 10 | "InitialReleaseDate": "2017-01-01T00:00:00.000Z", 11 | "NotableAdopters": [ 12 | { 13 | "Name": "GoodNotes", 14 | "URL": "https://github.com/automerge/automerge" 15 | }, 16 | { 17 | "Name": "Bowtie", 18 | "URL": "https://www.bowtie.security/" 19 | } 20 | ], 21 | "Deployment": [ 22 | "Self-hosted" 23 | ], 24 | "License": "MIT", 25 | "AppTarget": { 26 | "Platform": { 27 | "data": [ 28 | "Browser", 29 | "Node", 30 | "iOS", 31 | "Android", 32 | "macOS", 33 | "Linux", 34 | "Windows", 35 | "WASM" 36 | ], 37 | "comment": "Automerge itself supports all these platforms, but the automerge-repo companion library is currently only available in JavaScript environments (excluding React Native) and Swift environments. Other platforms are in development." 38 | }, 39 | "LanguageSDK": { 40 | "data": [ 41 | "JavaScript", 42 | "TypeScript", 43 | "Swift", 44 | "Rust", 45 | "Go", 46 | "Java", 47 | "Kotlin" 48 | ], 49 | "comment": "The officially supported languages are JavaScript, TypeScript, Swift, and Rust. Go, Java and Kotlin are best-effort but tend to lag behind the official implementations" 50 | }, 51 | "FrameworkIntegrations": { 52 | "data": [ 53 | "React", 54 | "Svelte" 55 | ] 56 | }, 57 | "ClientBundleSize": { 58 | "data": "~800Kb gzipped" 59 | } 60 | }, 61 | "Networking": { 62 | "Protocol": { 63 | "data": [ 64 | "WebSockets", 65 | "TCP" 66 | ], 67 | "comment": "The Automerge sync protocol runs over anything which provides an in-order byte stream" 68 | }, 69 | "Topology": { 70 | "data": "P2P", 71 | "comment": "Typical deployments use a central relay server with opportunistic peer-to-peer" 72 | } 73 | }, 74 | "ServerSideData": { 75 | "PersistenceMechanism": { 76 | "data": [ 77 | "Local file system", 78 | "Custom" 79 | ], 80 | "comment": "Automerge can use any storage mechanism which supports key/value storage with range queries. There are community maintained adapters for many storage backends including PostgreSQL and S3" 81 | }, 82 | "DataModelParadigm": { 83 | "data": "Document" 84 | } 85 | }, 86 | "ClientSideData": { 87 | "QueryAPI": { 88 | "data": [ 89 | "Async" 90 | ] 91 | }, 92 | "LocalRefreshLatency": { 93 | "data": "~10-100ms" 94 | }, 95 | "PersistenceMechanism": { 96 | "data": [ 97 | "IndexedDB", 98 | "Local file system", 99 | "Custom" 100 | ], 101 | "comment": "Automerge can use any storage mechanism which supports key/value storage with range queries" 102 | }, 103 | "DataModel": { 104 | "data": "Document" 105 | }, 106 | "OfflineReads": { 107 | "data": "Full Support" 108 | }, 109 | "OfflineWrites": { 110 | "data": "Local conflict resolution" 111 | }, 112 | "DataSize": { 113 | "data": "up to 5-10mb per doc" 114 | } 115 | }, 116 | "SynchronizationStrategy": { 117 | "FullOrPartialReplication": { 118 | "data": [ 119 | "Full Replication" 120 | ] 121 | }, 122 | "ConflictHandling": { 123 | "data": "Automatic via CRDT", 124 | "comment": "All changes are recorded and conflicts can be examined and resolved later" 125 | }, 126 | "WhereResolutionOccurs": { 127 | "data": "Client" 128 | }, 129 | "WhatGetsSynced": { 130 | "data": { 131 | "ClientToServer": "ops", 132 | "ServerToClient": "ops", 133 | "ClientToClient": "ops" 134 | }, 135 | "comment": "There is no distinction between client and server in Automerge" 136 | }, 137 | "Authority": { 138 | "data": "Decentralized" 139 | }, 140 | "Latency": { 141 | "data": "~10-100ms" 142 | } 143 | }, 144 | "AuthIdentity": { 145 | "Encryption": { 146 | "data": "Transport-level encryption" 147 | }, 148 | "AuthenticationMethod": { 149 | "data": [ 150 | "Full Custom" 151 | ] 152 | }, 153 | "AuthorizationPermissions": { 154 | "data": "Custom" 155 | } 156 | }, 157 | "UIRelated": { 158 | "RichTextEditing": { 159 | "data": "Yes" 160 | }, 161 | "Components": { 162 | "data": [ 163 | "ProseMirror plugin", 164 | "CodeMirror plugin", 165 | "React hooks" 166 | ] 167 | } 168 | }, 169 | "__generated": { 170 | "lastUpdated": "2025-04-29T17:35:36.000Z" 171 | } 172 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/jazz/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "jazz", 4 | "Name": "Jazz", 5 | "Description": "Toolkit for backendless apps.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://jazz.tools", 8 | "GitHub": "https://github.com/garden-co/jazz", 9 | "GetStarted": "https://jazz.tools/docs", 10 | "InitialReleaseDate": "2023-09-11T00:00:00.000Z", 11 | "Deployment": [ 12 | "Self-hosted", 13 | "Hosted" 14 | ], 15 | "License": "MIT", 16 | "AppTarget": { 17 | "Platform": { 18 | "data": [ 19 | "Browser", 20 | "Node", 21 | "iOS", 22 | "Android" 23 | ], 24 | "comment": "iOS and Android support via React Native." 25 | }, 26 | "LanguageSDK": { 27 | "data": [ 28 | "TypeScript" 29 | ] 30 | }, 31 | "FrameworkIntegrations": { 32 | "data": [ 33 | "React", 34 | "React Native", 35 | "Vue (experimental)", 36 | "Svelte (experimental)" 37 | ] 38 | }, 39 | "ClientBundleSize": { 40 | "data": "112kb gzipped (jazz-react)" 41 | } 42 | }, 43 | "Networking": { 44 | "Protocol": { 45 | "data": [ 46 | "WebSockets" 47 | ] 48 | }, 49 | "Topology": { 50 | "data": "P2P", 51 | "comment": "P2P via sync & storage servers. Servers are not stateless." 52 | } 53 | }, 54 | "ServerSideData": { 55 | "PersistenceMechanism": { 56 | "data": [ 57 | "SQLite", 58 | "Custom" 59 | ] 60 | }, 61 | "DataSize": { 62 | "data": "Unlimited, granular load & sync" 63 | }, 64 | "DataModelParadigm": { 65 | "data": "Document" 66 | }, 67 | "SchemaManagement": { 68 | "data": [ 69 | "Schema definition", 70 | "Derived types", 71 | "Schema migrations" 72 | ] 73 | }, 74 | "ExistingDatabaseSupport": { 75 | "data": "manual sync to existing DBs" 76 | } 77 | }, 78 | "ClientSideData": { 79 | "QueryAPI": { 80 | "data": [ 81 | "Sync", 82 | "Signals-based Reactivity" 83 | ] 84 | }, 85 | "LocalRefreshLatency": { 86 | "data": "~1ms" 87 | }, 88 | "PersistenceMechanism": { 89 | "data": [ 90 | "IndexedDB", 91 | "SQLite" 92 | ] 93 | }, 94 | "DataModel": { 95 | "data": "Document" 96 | }, 97 | "SchemaManagement": { 98 | "data": [ 99 | "Schema definition", 100 | "Derived types", 101 | "Schema migrations" 102 | ] 103 | }, 104 | "OfflineReads": { 105 | "data": "Full Support" 106 | }, 107 | "OptimisticUpdates": { 108 | "data": "Yes" 109 | }, 110 | "OfflineWrites": { 111 | "data": "Local conflict resolution" 112 | }, 113 | "DataSize": { 114 | "data": "limited by RAM", 115 | "comment": "Soon limited only by disk." 116 | } 117 | }, 118 | "SynchronizationStrategy": { 119 | "FullOrPartialReplication": { 120 | "data": [ 121 | "Partial Replication" 122 | ], 123 | "comment": "Partial replication on-demand or with explicit load depths." 124 | }, 125 | "ConflictHandling": { 126 | "data": "Automatic via CRDT" 127 | }, 128 | "WhereResolutionOccurs": { 129 | "data": "Client" 130 | }, 131 | "WhatGetsSynced": { 132 | "data": { 133 | "ClientToClient": "CoValue headers, CoValue session diffs (transactions)" 134 | } 135 | }, 136 | "Authority": { 137 | "data": "Decentralized" 138 | }, 139 | "Latency": { 140 | "data": "Close to network latency" 141 | }, 142 | "Throughput": { 143 | "data": "Roughly 5k transactions/s (structured data) or ~50MB/s (binary data)", 144 | "comment": "Soon: limited only by number of participants (updates of any size by up to 5k participants/s)" 145 | }, 146 | "Concurrency": { 147 | "data": "Support for granular prioritization" 148 | } 149 | }, 150 | "AuthIdentity": { 151 | "Encryption": { 152 | "data": "Yes", 153 | "comment": "Built-in e2ee" 154 | }, 155 | "AuthenticationMethod": { 156 | "data": [ 157 | "Built-in" 158 | ] 159 | }, 160 | "AuthorizationPermissions": { 161 | "data": "Built-in cryptographical hierarchical RBAC" 162 | } 163 | }, 164 | "UIRelated": { 165 | "RichTextEditing": { 166 | "data": "Yes", 167 | "comment": "ProseMirror integration" 168 | }, 169 | "Components": { 170 | "data": [ 171 | "File upload", 172 | "progressive image loading", 173 | "multiplayer cursors" 174 | ] 175 | } 176 | }, 177 | "DevelopmentWorkflowsDX": { 178 | "DebuggingTools": { 179 | "data": [ 180 | "Data Inspector" 181 | ] 182 | }, 183 | "CLI": { 184 | "data": "CLI for running local sync & storage server, for creating worker account" 185 | }, 186 | "TypeSupport": { 187 | "data": "Full type support without extra config" 188 | } 189 | }, 190 | "__generated": { 191 | "lastUpdated": "2025-04-29T12:51:37.000Z" 192 | } 193 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/liveblocks-storage/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "liveblocks-storage", 4 | "Name": "Liveblocks Storage", 5 | "MaturityLevel": "Production-ready", 6 | "Website": "https://liveblocks.io/sync-datastore/storage", 7 | "InitialReleaseDate": "2022-03-16T00:00:00.000Z", 8 | "Deployment": [ 9 | "Hosted" 10 | ], 11 | "License": "Proprietary", 12 | "AppTarget": { 13 | "Platform": { 14 | "data": [ 15 | "Browser", 16 | "Node" 17 | ] 18 | }, 19 | "LanguageSDK": { 20 | "data": [ 21 | "TypeScript" 22 | ] 23 | }, 24 | "FrameworkIntegrations": { 25 | "data": [ 26 | "React", 27 | "Zustand", 28 | "Redux" 29 | ] 30 | } 31 | }, 32 | "Networking": { 33 | "Protocol": { 34 | "data": [ 35 | "WebSockets", 36 | "HTTP" 37 | ] 38 | }, 39 | "Topology": { 40 | "data": "Client-Server" 41 | } 42 | }, 43 | "ServerSideData": { 44 | "PersistenceMechanism": { 45 | "data": [ 46 | "Cloudflare Durable Object Storage", 47 | "SQLite" 48 | ] 49 | }, 50 | "DataModelParadigm": { 51 | "data": "Document", 52 | "comment": "Each room is a digital space where people colalborate, and it corresponds with a document." 53 | }, 54 | "SchemaManagement": { 55 | "data": [ 56 | "Schema definition", 57 | "Schema validation" 58 | ] 59 | }, 60 | "ExistingDatabaseSupport": { 61 | "data": "One-way sync with DBs", 62 | "comment": "Does not require a datastore, but you can migrate or automatically sync to your database with webhooks/REST API" 63 | } 64 | }, 65 | "ClientSideData": { 66 | "QueryAPI": { 67 | "data": [ 68 | "Signals-based reactivity", 69 | "Reactive queries" 70 | ], 71 | "comment": "JS: via subscription. React: via selector hooks, mutation callbacks. Automatically converts live data structures to JSON for easy UI. Hooks update automatically on changes. Can retrieve deep into the data structure without causing unnecessary renders." 72 | }, 73 | "LocalRefreshLatency": { 74 | "data": "<1ms", 75 | "comment": "Changes on the client: <1ms. Other clients receive updates up to 60 times per second(16ms), configurable." 76 | }, 77 | "PersistenceMechanism": { 78 | "data": [ 79 | "Liveblocks Storage" 80 | ] 81 | }, 82 | "DataModel": { 83 | "data": "Document", 84 | "comment": "LiveObject" 85 | }, 86 | "SchemaManagement": { 87 | "data": [ 88 | "Schema definition" 89 | ] 90 | }, 91 | "OfflineReads": { 92 | "data": "Query Cache", 93 | "comment": "Previously accessed data is stored in-memory" 94 | }, 95 | "OptimisticUpdates": { 96 | "data": "Yes" 97 | }, 98 | "OfflineWrites": { 99 | "data": "Cached offline writes", 100 | "comment": "Full cached writes, stored in-memory, server will resolve conflict." 101 | }, 102 | "DataSize": { 103 | "data": "Limited by memory", 104 | "comment": "It depends on the in memory size of the Storage document." 105 | } 106 | }, 107 | "SynchronizationStrategy": { 108 | "ConflictHandling": { 109 | "data": "Automatic via LWW or fractional indexing", 110 | "comment": "Values: LWW, LiveObject: LWW at attribute level, LiveMap: LWW at entry level, LiveList: fractional indexing (for insertions) or LWW (for replacements)" 111 | }, 112 | "WhereResolutionOccurs": { 113 | "data": "Server" 114 | }, 115 | "WhatGetsSynced": { 116 | "data": { 117 | "ClientToServer": "ops", 118 | "ServerToClient": "ops, acks, and fix-ops (when conflict was resolved)" 119 | } 120 | }, 121 | "Authority": { 122 | "data": "Centralized" 123 | } 124 | }, 125 | "AuthIdentity": { 126 | "Encryption": { 127 | "data": "Transport-level (wss:// or https://)" 128 | }, 129 | "AuthenticationMethod": { 130 | "data": [ 131 | "JWT tokens", 132 | "Public key" 133 | ] 134 | }, 135 | "AuthorizationPermissions": { 136 | "data": "ID tokens and access tokens", 137 | "comment": "ID tokens for permissions based on a per-room basis. Access tokens for permissions granted directly in the token" 138 | } 139 | }, 140 | "UIRelated": { 141 | "Components": { 142 | "data": [ 143 | "Comments/Threads", 144 | "Notifications", 145 | "AI Copilots", 146 | "Presence" 147 | ], 148 | "comment": "All Liveblocks products integrate into each other. Learn more about the other products on [liveblocks.io](https://liveblocks.io)." 149 | } 150 | }, 151 | "DevelopmentWorkflowsDX": { 152 | "DebuggingTools": { 153 | "data": [ 154 | "DevTools", 155 | "Dashboard", 156 | "Data Inspector" 157 | ], 158 | "comment": "Viewing/editing data, events, usage, etc." 159 | }, 160 | "CLI": { 161 | "data": "CLI for installing examples, updating packages, creating your typescript config." 162 | }, 163 | "TypeSupport": { 164 | "data": "Full type support", 165 | "comment": "Via [`liveblocks.config.ts`](https://liveblocks.io/docs/api-reference/liveblocks-react#TypeScript)." 166 | } 167 | }, 168 | "__generated": { 169 | "lastUpdated": "2025-04-24T11:47:23.000Z" 170 | } 171 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/yjs/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "yjs", 4 | "Name": "Yjs", 5 | "Description": "Shared types to make anything collaborative", 6 | "MaturityLevel": "Mature", 7 | "Website": "https://yjs.dev", 8 | "GitHub": "https://github.com/yjs/yjs", 9 | "GetStarted": "https://learn.yjs.dev", 10 | "UniquenessNote": "Minimal, flexible, fast, easy to integrate, unopinionated", 11 | "InitialReleaseDate": "2015-01-26T23:00:00.000Z", 12 | "NotableAdopters": [ 13 | { 14 | "Name": "Evernote", 15 | "URL": "https://evernote.com" 16 | }, 17 | { 18 | "Name": "Project Jupyter", 19 | "URL": "https://jupyter.org/" 20 | }, 21 | { 22 | "Name": "La Suite", 23 | "URL": "https://lasuite.numerique.gouv.fr/en" 24 | }, 25 | { 26 | "Name": "NextCloud", 27 | "URL": "https://nextcloud.com/" 28 | } 29 | ], 30 | "Deployment": [ 31 | "Self-hosted", 32 | "Hosted", 33 | "Third-party integrations" 34 | ], 35 | "License": "MIT", 36 | "AppTarget": { 37 | "Platform": { 38 | "data": [ 39 | "Browser", 40 | "Node", 41 | "iOS", 42 | "React Native", 43 | "WASM" 44 | ], 45 | "comment": "We have language bindings to many popular programming languages. See y-crdt." 46 | }, 47 | "LanguageSDK": { 48 | "data": [ 49 | "TypeScript", 50 | "JavaScript", 51 | "Rust", 52 | "C#", 53 | "Swift", 54 | "Python", 55 | "Cffi", 56 | "Kotlin" 57 | ] 58 | }, 59 | "FrameworkIntegrations": { 60 | "data": [ 61 | "React", 62 | "React Native", 63 | "Vue", 64 | "Svelte", 65 | "Zustand" 66 | ], 67 | "comment": "There are several \"bindings\" that make Yjs work with different web frameworks. This list is probably not up to date." 68 | }, 69 | "ClientBundleSize": { 70 | "data": "~20kb", 71 | "comment": "About ~20kb gzipped. Your final bundle might be smaller as Yjs works well with dead-code elimination." 72 | } 73 | }, 74 | "Networking": { 75 | "Protocol": { 76 | "data": [ 77 | "WebRTC", 78 | "WebSockets", 79 | "Matrix", 80 | "Signal", 81 | "via integrations", 82 | "custom" 83 | ], 84 | "comment": "It is relatively easy sync Yjs through custom communication protocols." 85 | }, 86 | "Topology": { 87 | "data": "P2P / Client-server" 88 | } 89 | }, 90 | "ServerSideData": { 91 | "PersistenceMechanism": { 92 | "data": [ 93 | "Redis", 94 | "Leveldb", 95 | "DB-integrations", 96 | "custom" 97 | ], 98 | "comment": "It is relatively easy to persist Yjs data in your own database." 99 | }, 100 | "DataModelParadigm": { 101 | "data": "Document" 102 | }, 103 | "ExistingDatabaseSupport": { 104 | "data": "Via integrations and plugins" 105 | } 106 | }, 107 | "ClientSideData": { 108 | "QueryAPI": { 109 | "data": [ 110 | "Sync" 111 | ] 112 | }, 113 | "LocalRefreshLatency": { 114 | "data": "<1ms", 115 | "comment": "The in-memory data structures fire events instantaneously, without waiting for a database." 116 | }, 117 | "PersistenceMechanism": { 118 | "data": [ 119 | "IndexedDB", 120 | "DB-integrations", 121 | "custom" 122 | ] 123 | }, 124 | "PersistenceFeatures": { 125 | "data": "Transactions" 126 | }, 127 | "DataModel": { 128 | "data": "Document" 129 | }, 130 | "OfflineReads": { 131 | "data": "Full Support" 132 | }, 133 | "OptimisticUpdates": { 134 | "data": "Yes" 135 | }, 136 | "OfflineWrites": { 137 | "data": "Local conflict resolution" 138 | }, 139 | "DataSize": { 140 | "data": "Depends on the size of the shared data" 141 | } 142 | }, 143 | "SynchronizationStrategy": { 144 | "FullOrPartialReplication": { 145 | "data": [ 146 | "Full Replication" 147 | ] 148 | }, 149 | "ConflictHandling": { 150 | "data": "Automatic via CRDT" 151 | }, 152 | "WhereResolutionOccurs": { 153 | "data": "Client" 154 | }, 155 | "WhatGetsSynced": { 156 | "data": { 157 | "ClientToClient": "CRDT operations, awareness state, content attribution." 158 | } 159 | }, 160 | "Authority": { 161 | "data": "Decentralized" 162 | }, 163 | "Latency": { 164 | "data": "<1ms", 165 | "comment": "Depends on which provider you choose. But it's pretty fast." 166 | } 167 | }, 168 | "AuthIdentity": { 169 | "Encryption": { 170 | "data": "Unopinionated, via providers", 171 | "comment": "E.g. via secsync or matrix-crdt" 172 | }, 173 | "AuthenticationMethod": { 174 | "data": [ 175 | "Unopinionated, via providers" 176 | ] 177 | }, 178 | "AuthorizationPermissions": { 179 | "data": "Unopinionated, via providers" 180 | } 181 | }, 182 | "UIRelated": { 183 | "RichTextEditing": { 184 | "data": "Yes", 185 | "comment": "We have integrations with most popular rich-text editors like ProseMirror, Lexical, and CodeMirror." 186 | } 187 | }, 188 | "DevelopmentWorkflowsDX": { 189 | "DebuggingTools": { 190 | "data": [ 191 | "DevTools", 192 | "Data Inspector" 193 | ] 194 | }, 195 | "TypeSupport": { 196 | "data": "Full Support" 197 | } 198 | }, 199 | "__generated": { 200 | "lastUpdated": "2025-04-25T15:10:43.000Z" 201 | } 202 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/powersync/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "powersync", 4 | "Name": "PowerSync", 5 | "Description": "Syncs between SQLite on the client-side and Postgres, MongoDB, MySQL or SQL Server on the server-side.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://www.powersync.com", 8 | "GitHub": "https://github.com/powersync-ja", 9 | "UniquenessNote": "Sync Rules allow flexible dynamic partial syncing. Write path is fully customizable through your own backend.", 10 | "InitialReleaseDate": "2023-11-30T00:00:00.000Z", 11 | "Deployment": [ 12 | "Self-hosted", 13 | "Hosted" 14 | ], 15 | "License": "FSL-Apache 2.0 (Service) & Apache 2.0 (SDKs)", 16 | "AppTarget": { 17 | "Platform": { 18 | "data": [ 19 | "Browser", 20 | "iOS", 21 | "Android", 22 | "macOS", 23 | "WASM", 24 | "Linux" 25 | ] 26 | }, 27 | "LanguageSDK": { 28 | "data": [ 29 | "TypeScript", 30 | "Swift", 31 | "Kotlin", 32 | "Rust", 33 | "Dart", 34 | ".NET" 35 | ] 36 | }, 37 | "FrameworkIntegrations": { 38 | "data": [ 39 | "React", 40 | "React Native", 41 | "Vue", 42 | "Svelte", 43 | "SolidJS", 44 | "Flutter" 45 | ] 46 | } 47 | }, 48 | "Networking": { 49 | "Protocol": { 50 | "data": [ 51 | "WebSockets", 52 | "HTTP" 53 | ] 54 | }, 55 | "Topology": { 56 | "data": "Client-Server" 57 | } 58 | }, 59 | "ServerSideData": { 60 | "PersistenceMechanism": { 61 | "data": [ 62 | "Postgres", 63 | "MongoDB", 64 | "MySQL", 65 | "SQL Server" 66 | ], 67 | "comment": "Backend source databases: Postgres, MongoDB, MySQL, SQL Server. Storage of sync bucket data: MongoDB, Postgres" 68 | }, 69 | "DataSize": { 70 | "data": "No theoretical limit" 71 | }, 72 | "DataModelParadigm": { 73 | "data": "Relational" 74 | }, 75 | "ExistingDatabaseSupport": { 76 | "data": "Works with backend source databases: Postgres, MongoDB, MySQL, SQL Server" 77 | } 78 | }, 79 | "ClientSideData": { 80 | "QueryAPI": { 81 | "data": [ 82 | "Async", 83 | "Reactive queries" 84 | ] 85 | }, 86 | "PersistenceMechanism": { 87 | "data": [ 88 | "SQLite", 89 | "IndexedDB", 90 | "OPFS" 91 | ] 92 | }, 93 | "PersistenceFeatures": { 94 | "data": "FTS, Indexes, Transactions" 95 | }, 96 | "DataModel": { 97 | "data": "Relational", 98 | "comment": "Schemaless JSON synced and stored in SQLite and exposed as views to allow for relational queries based on client-side schema." 99 | }, 100 | "SchemaManagement": { 101 | "data": [ 102 | "Schema definition" 103 | ], 104 | "comment": "Client-side schema definition. Schema is used to expose views in SQLite based on schemaless synced data, generally avoiding the need for schema migrations." 105 | }, 106 | "OfflineReads": { 107 | "data": "Full Support", 108 | "comment": "Dynamic query support." 109 | }, 110 | "OptimisticUpdates": { 111 | "data": "Yes" 112 | }, 113 | "OfflineWrites": { 114 | "data": "Yes" 115 | } 116 | }, 117 | "SynchronizationStrategy": { 118 | "FullOrPartialReplication": { 119 | "data": [ 120 | "Full Replication", 121 | "Partial Replication" 122 | ], 123 | "comment": "Partial or full replica defined using [Sync Rules](https://docs.powersync.com/usage/sync-rules). Sync Rules can make use of authenticated JWT parameters or client parameters." 124 | }, 125 | "ConflictHandling": { 126 | "data": "Custom conflict resolution supported", 127 | "comment": "Developer defines an upload function which writes local mutations to backend database. Simplest implementation of this results in LWW. Can be customized by developer, including using CRDT data structures like [Yjs](https://www.powersync.com/blog/postgres-and-yjs-crdt-collaborative-text-editing-using-powersync), e.g." 128 | }, 129 | "WhereResolutionOccurs": { 130 | "data": "Server" 131 | }, 132 | "WhatGetsSynced": { 133 | "data": { 134 | "ClientToServer": "mutations", 135 | "ServerToClient": "ops" 136 | } 137 | }, 138 | "Authority": { 139 | "data": "Centralized" 140 | } 141 | }, 142 | "AuthIdentity": { 143 | "Encryption": { 144 | "data": "Yes", 145 | "comment": "transport-level and storage-level locally on the device using SQLCipher; E2EE can also be accomplished by syncing encrypted data and decrypting on client" 146 | }, 147 | "AuthenticationMethod": { 148 | "data": [ 149 | "JWT Tokens" 150 | ] 151 | }, 152 | "AuthorizationPermissions": { 153 | "data": "Custom", 154 | "comment": "Reads: Access to data is controlled by authenticated parameters in JWT used in Sync Rules\nWrites: Access controlled using developer's own backend (through which writes go to)" 155 | } 156 | }, 157 | "DevelopmentWorkflowsDX": { 158 | "DebuggingTools": { 159 | "data": [ 160 | "Dashboard", 161 | "Data Inspector" 162 | ], 163 | "comment": "[Dashboard](https://docs.powersync.com/usage/tools/powersync-dashboard), [Diagnostic tool to inspect synced data](https://github.com/powersync-ja/powersync-js/tree/main/tools/diagnostics-app)" 164 | }, 165 | "CLI": { 166 | "data": "CLI for managing cloud instances of PowerSync Service" 167 | } 168 | }, 169 | "__generated": { 170 | "lastUpdated": "2025-12-10T19:58:02.000Z" 171 | } 172 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Local-first Landscape 🗺️ 2 | 3 | A resource to learn about and compare tools in the local-first landscape. Whether you're a developer looking to experiment with local-first patterns or a technical leader making a strategic technology decision, this resource helps you navigate the growing ecosystem of local-first tools and make informed choices. 4 | 5 | ## Sub-packages 6 | 7 | This monorepo contains several packages that work together: 8 | 9 | - `landscape-schema`: Defines the TypeScript schema for the data that describes each technology in the landscape. 10 | - `landscape-fetch-content`: Contains the infrastructure to fetch the data for each technology from its designated GitHub repository (see below). 11 | - `landscape-content-snapshot`: A local cache of the fetched data from the technology repositories. 12 | 13 | ## Contributing Data 14 | 15 | The data for this landscape is maintained collaboratively. 16 | 17 | ### Suggesting a New Technology 18 | 19 | To suggest adding a new technology to the landscape, please open a Pull Request against the `packages/@localfirstfm/landscape-fetch-content/src/repos.ts` file in *this* repository. Add an entry for the new technology, specifying its unique ID, the GitHub owner and repository where its data will be maintained, and optionally a branch and base path within that repository. 20 | 21 | ### Editing Existing Technology Data 22 | 23 | To edit the information for an existing technology, you need to open a Pull Request against the specific GitHub repository where that technology's data is managed. Find the correct repository in the table below: 24 | 25 | | Technology | Data Repository | 26 | | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | 27 | | [Automerge](placeholder-homepage-automerge) | [`automerge/local-first-landscape-data`](https://github.com/automerge/local-first-landscape-data) | 28 | | [Basic](placeholder-homepage-basic) | [`basicdb/local-first-landscape-data`](https://github.com/basicdb/local-first-landscape-data) | 29 | | [Convex](placeholder-homepage-convex) | [`get-convex/localfirst-landscape-data`](https://github.com/get-convex/localfirst-landscape-data) | 30 | | [Ditto](placeholder-homepage-ditto) | [`localfirstfm/local-first-landscape`](https://github.com/localfirstfm/local-first-landscape) | 31 | | [DXOS](placeholder-homepage-dxos) | [`dxos/local-first-landscape-data`](https://github.com/dxos/local-first-landscape-data) | 32 | | [ElectricSQL](placeholder-homepage-electricsql) | [`electric-sql/local-first-landscape-data`](https://github.com/electric-sql/local-first-landscape-data) | 33 | | [Jazz](placeholder-homepage-jazz) | [`garden-co/jazz-lofi-landscape`](https://github.com/garden-co/jazz-lofi-landscape) | 34 | | [Liveblocks](placeholder-homepage-liveblocks) | [`liveblocks/local-first-landscape-data`](https://github.com/liveblocks/local-first-landscape-data) | 35 | | [LiveStore](placeholder-homepage-livestore) | [`livestorejs/local-first-landscape`](https://github.com/livestorejs/local-first-landscape) | 36 | | [NextGraph](https://nextgraph.org) | [`nextgraph-org/landscape-data`](https://github.com/nextgraph-org/landscape-data) | 37 | | [PowerSync](placeholder-homepage-powersync) | [`powersync-ja/local-first-landscape-data`](https://github.com/powersync-ja/local-first-landscape-data) | 38 | | [TinyBase](placeholder-homepage-tinybase) | [`tinyplex/tinybase-landscape-data`](https://github.com/tinyplex/tinybase-landscape-data) | 39 | | [Triplit](placeholder-homepage-triplit) | [`aspen-cloud/local-first-landscape-data`](https://github.com/aspen-cloud/local-first-landscape-data) | 40 | | [Y-Sweet](placeholder-homepage-y-sweet) | [`jamsocket/y-sweet`](https://github.com/jamsocket/y-sweet) | 41 | | [Yjs](placeholder-homepage-yjs) | [`yjs/local-first-landscape-data`](https://github.com/yjs/local-first-landscape-data) | 42 | | [Zero](placeholder-homepage-zero) | [`rocicorp/local-first-landscape-data`](https://github.com/rocicorp/local-first-landscape-data) | 43 | | [Instant](https://instantdb.com) | [`instantdb/local-first-landscape-data`](https://github.com/instantdb/local-first-landscape-data) | 44 | | [PouchDB](https://pouchdb.com/) | [`neighbourhoodie/pouchdb-landscape-data`](https://github.com/neighbourhoodie/pouchdb-landscape-data) | 45 | | [CouchDB](https://couchdb.apache.org/) | [`neighbourhoodie/couchdb-landscape-data`](https://github.com/neighbourhoodie/couch-landscape-data) | 46 | 47 | Make your changes to the relevant files in that repository. 48 | 49 | > [!NOTE] 50 | > The content for each technology is automatically pulled from its respective repository and regenerated **daily at 00:00 UTC**. Changes made in the source repositories will only be reflected in the website after the next daily update. 51 | 52 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/ditto/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "ditto", 4 | "Name": "Ditto", 5 | "Description": "Ditto is the only edge-native, mobile database that can consistently support your business anytime, anywhere. Edge-native solutions are built specifically to thrive on mobile and edge devices, without relying solely on cloud-based services.", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://www.ditto.com", 8 | "GitHub": "https://github.com/getditto", 9 | "GetStarted": "https://docs.ditto.live/home/introduction#sdk-quickstart-guides", 10 | "InitialReleaseDate": "2019-04-30T00:00:00.000Z", 11 | "Deployment": [ 12 | "Self-hosted", 13 | "Hosted" 14 | ], 15 | "License": "Proprietary", 16 | "AppTarget": { 17 | "Platform": { 18 | "data": [ 19 | "Browser", 20 | "iOS", 21 | "Android", 22 | "macOS", 23 | "Linux", 24 | "Windows", 25 | "WASM" 26 | ], 27 | "comment": "The various Ditto Edge SDKs may or may not suppport all environments listed. Other platforms are in development." 28 | }, 29 | "LanguageSDK": { 30 | "data": [ 31 | "Swift", 32 | "Kotlin - Android", 33 | "Java - Server", 34 | "Java - Android", 35 | "Dart", 36 | "React Native", 37 | "JavaScript Web", 38 | "C# - .NET", 39 | "Rust", 40 | "C++" 41 | ], 42 | "comment": "" 43 | }, 44 | "FrameworkIntegrations": { 45 | "data": [ 46 | "React Native", 47 | "Flutter", 48 | ".NET Maui", 49 | "Jetpack Compose", 50 | "SwiftUI" 51 | ] 52 | } 53 | }, 54 | "Networking": { 55 | "Protocol": { 56 | "data": [ 57 | "WiFi LAN", 58 | "Bluetooth", 59 | "P2P WiFi", 60 | "TCP", 61 | "HTTP", 62 | "WebSockets" 63 | ], 64 | "comment": "We've developed an intelligent sync system that automatically discovers local devices, establishes a connection, and seamlessly switches between active transports when syncing data (Bluetooth, P2P WiFi, LAN, Websockets) so that if one transport goes down, it automatically switches to the next best one, optimizing for speed. \"Resilient Networking\" in this context means networking that can network in any environment and dynamically \"heal\" itself if connections break" 65 | }, 66 | "Topology": { 67 | "data": "Mesh Network" 68 | } 69 | }, 70 | "ServerSideData": { 71 | "PersistenceMechanism": { 72 | "data": [ 73 | "Custom" 74 | ] 75 | }, 76 | "DataSize": { 77 | "data": "No theoretical limit", 78 | "comment": "No theoretical limit, due to cloud scaling, but we offer benchmarking and performance services to validate & scale cloud resources for larger use cases." 79 | }, 80 | "DataModelParadigm": { 81 | "data": "Document" 82 | }, 83 | "ExistingDatabaseSupport": { 84 | "data": "HTTP/Webhooks and real-time via CDC Connectors (Kafka-based)" 85 | } 86 | }, 87 | "ClientSideData": { 88 | "QueryAPI": { 89 | "data": [ 90 | "Async", 91 | "Reactive queries" 92 | ] 93 | }, 94 | "LocalRefreshLatency": { 95 | "data": "10ms-2s", 96 | "comment": "Depends on cardinality, query optimization plan, and local data size." 97 | }, 98 | "PersistenceMechanism": { 99 | "data": [ 100 | "SQLite" 101 | ] 102 | }, 103 | "PersistenceFeatures": { 104 | "data": "Indexes" 105 | }, 106 | "DataModel": { 107 | "data": "Document", 108 | "comment": "Queries are SQL, records are document-oriented." 109 | }, 110 | "OfflineReads": { 111 | "data": "Full Support", 112 | "comment": "Dynamic query support." 113 | }, 114 | "OptimisticUpdates": { 115 | "data": "Yes" 116 | }, 117 | "OfflineWrites": { 118 | "data": "Full local conflict resolution" 119 | }, 120 | "DataSize": { 121 | "data": "up to the size of the hard drive" 122 | } 123 | }, 124 | "SynchronizationStrategy": { 125 | "FullOrPartialReplication": { 126 | "data": [ 127 | "Full Replication", 128 | "Partial Replication" 129 | ], 130 | "comment": "Defined using [subscriptions](https://docs.ditto.live/key-concepts/syncing-data). Supports flexible [authorization](https://docs.ditto.live/key-concepts/authentication-and-authorization) model." 131 | }, 132 | "ConflictHandling": { 133 | "data": "Automatic via CRDT", 134 | "comment": "All changes are recorded and conflicts are resolved automatically" 135 | }, 136 | "WhereResolutionOccurs": { 137 | "data": "Client" 138 | }, 139 | "WhatGetsSynced": { 140 | "data": { 141 | "ClientToClient": "document deltas" 142 | }, 143 | "comment": "Ditto has client-to-client deltas, and the server is running the same CRDT as the client, and is not required." 144 | }, 145 | "Authority": { 146 | "data": "Decentralized", 147 | "comment": "Decentralized via authentication servers." 148 | } 149 | }, 150 | "AuthIdentity": { 151 | "Encryption": { 152 | "data": "Built-in e2ee" 153 | }, 154 | "AuthenticationMethod": { 155 | "data": [ 156 | "JWT Tokens" 157 | ] 158 | }, 159 | "AuthorizationPermissions": { 160 | "data": "Custom-mapped ACLs" 161 | } 162 | }, 163 | "UIRelated": { 164 | "Components": { 165 | "data": [ 166 | "Presence" 167 | ], 168 | "comment": "SDK provides which peers you are connected to, and over what transports." 169 | } 170 | }, 171 | "DevelopmentWorkflowsDX": { 172 | "DebuggingTools": { 173 | "data": [ 174 | "DevTools", 175 | "Data Inspector", 176 | "Network Inspector" 177 | ], 178 | "comment": "Open source debugging and diagnostic tools for developers." 179 | } 180 | }, 181 | "__generated": { 182 | "lastUpdated": "2025-04-30T15:39:55.000Z" 183 | } 184 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/rxdb/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1, 3 | "Id": "rxdb", 4 | "Name": "RxDB", 5 | "Description": "A fast, local-first, reactive Database for JavaScript Applications", 6 | "MaturityLevel": "Production-Ready", 7 | "Website": "https://rxdb.info/", 8 | "GitHub": "https://github.com/pubkey/rxdb", 9 | "GetStarted": "https://rxdb.info/quickstart.html", 10 | "UniquenessNote": "RxDB focuses on local-first reactivity (observable queries) with pluggable storage engines and multiple replication options (HTTP endpoints, CouchDB, GraphQL, WebSocket, WebRTC P2P).", 11 | "Deployment": [ 12 | "Self-hosted", 13 | "Third-party Integrations" 14 | ], 15 | "License": "FSL-Apach 2.0", 16 | "AppTarget": { 17 | "Platform": { 18 | "data": [ 19 | "Browser", 20 | "Node", 21 | "Android", 22 | "iOS", 23 | "Desktop" 24 | ], 25 | "comment": "Core targets web + Node; mobile via React Native / Capacitor / native bridges depending on storage/replication setup." 26 | }, 27 | "LanguageSDK": { 28 | "data": [ 29 | "typescript", 30 | "javascript" 31 | ] 32 | }, 33 | "FrameworkIntegrations": { 34 | "data": [ 35 | "React", 36 | "Angular", 37 | "Vue", 38 | "Svelte" 39 | ] 40 | }, 41 | "ClientBundleSize": { 42 | "data": "~40kB", 43 | "comment": "depends on the used storage" 44 | } 45 | }, 46 | "Networking": { 47 | "Protocol": { 48 | "data": [ 49 | "HTTP", 50 | "SSE", 51 | "WebSockets", 52 | "P2P WiFi", 53 | "WebRTC" 54 | ] 55 | }, 56 | "Topology": { 57 | "data": "Client-Server", 58 | "comment": "P2P is also possible via WebRTC replication." 59 | } 60 | }, 61 | "ServerSideData": { 62 | "PersistenceMechanism": { 63 | "data": [ 64 | "MongoDB", 65 | "SQLite", 66 | "Custom" 67 | ] 68 | }, 69 | "DataModelParadigm": { 70 | "data": "Document" 71 | }, 72 | "ExistingDatabaseSupport": { 73 | "data": "Yes", 74 | "comment": "Via replication plugins / custom replication endpoints (backend-dependent)" 75 | } 76 | }, 77 | "ClientSideData": { 78 | "QueryAPI": { 79 | "data": [ 80 | "Async", 81 | "Reactive queries", 82 | "Signals-based Reactivity" 83 | ] 84 | }, 85 | "PersistenceMechanism": { 86 | "data": [ 87 | "IndexedDB", 88 | "OPFS", 89 | "SQLite", 90 | "LocalStorage", 91 | "Custom" 92 | ], 93 | "comment": "Pluggable storage engines; exact options vary by environment and plugins." 94 | }, 95 | "PersistenceFeatures": { 96 | "data": "Indexes" 97 | }, 98 | "DataModel": { 99 | "data": "Document" 100 | }, 101 | "SchemaManagement": { 102 | "data": [ 103 | "Schema definition", 104 | "Schema migrations", 105 | "Schema validation on write", 106 | "Derived types" 107 | ], 108 | "comment": "Uses JSON Schema; migration support via plugins." 109 | }, 110 | "OfflineReads": { 111 | "data": "Full Support" 112 | }, 113 | "OptimisticUpdates": { 114 | "data": "Yes" 115 | }, 116 | "OfflineWrites": { 117 | "data": "Local conflict resolution" 118 | }, 119 | "DataSize": { 120 | "data": "Depends on which storage is used" 121 | } 122 | }, 123 | "SynchronizationStrategy": { 124 | "FullOrPartialReplication": { 125 | "data": [ 126 | "Full Replication", 127 | "Partial Replication" 128 | ] 129 | }, 130 | "ConflictHandling": { 131 | "data": "Custom conflict resolution supported", 132 | "comment": "Conflict handling depends on replication strategy; RxDB supports providing custom handlers (and can integrate CRDT-style approaches via plugins)." 133 | }, 134 | "WhereResolutionOccurs": { 135 | "data": "Client" 136 | }, 137 | "WhatGetsSynced": { 138 | "data": { 139 | "ClientToServer": "Docs", 140 | "ServerToClient": "Docs", 141 | "ClientToClient": "Docs" 142 | } 143 | }, 144 | "Authority": { 145 | "data": "Centralized", 146 | "comment": "Most deployments use a server; can be decentralized in P2P WebRTC setups." 147 | }, 148 | "Latency": { 149 | "data": "~10-100ms", 150 | "comment": "Network sync latency depends on transport; local reads are instant." 151 | }, 152 | "Throughput": { 153 | "data": "Varies by replication plugin/backend and document sizes" 154 | }, 155 | "Concurrency": { 156 | "data": "Multi-device + multi-tab capable (replication coordination is supported)" 157 | } 158 | }, 159 | "AuthIdentity": { 160 | "Encryption": { 161 | "data": "Yes", 162 | "comment": "Encryption-at-rest is available via plugins." 163 | }, 164 | "AuthenticationMethod": { 165 | "data": [ 166 | "Full Custom" 167 | ], 168 | "comment": "Authentication/authorization is typically handled by the replication backend (e.g., your API)." 169 | }, 170 | "AuthorizationPermissions": { 171 | "data": "Custom", 172 | "comment": "Usually enforced server-side in your replication endpoints/backends." 173 | } 174 | }, 175 | "UIRelated": { 176 | "RichTextEditing": { 177 | "data": "No" 178 | }, 179 | "Components": { 180 | "data": [], 181 | "comment": "RxDB is a database layer, not a UI component library." 182 | } 183 | }, 184 | "DevelopmentWorkflowsDX": { 185 | "DebuggingTools": { 186 | "data": [ 187 | "DevTools", 188 | "Data Inspector" 189 | ], 190 | "comment": "Includes development-mode checks; inspection/debugging often done via browser storage inspectors and logging." 191 | }, 192 | "CLI": { 193 | "data": "N/A" 194 | }, 195 | "TypeSupport": { 196 | "data": "TypeScript supported; typings depend on your schema and app setup" 197 | } 198 | }, 199 | "__generated": { 200 | "lastUpdated": "2025-12-15T12:50:12.000Z" 201 | } 202 | } -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/yjs/logo.light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /landscape-content-snapshot/src/generated/yjs/logo.dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 46 | 48 | 49 | 51 | image/svg+xml 52 | 54 | 55 | 56 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 93 | 94 | 95 | --------------------------------------------------------------------------------