kammer/RESEARCH_SUMMARY.md
Christopher Mühl d017987553 chore: scaffold SvelteKit project with Capacitor and Tailwind
- SvelteKit 2 (Svelte 5) with TypeScript, static adapter (SPA mode)
- Capacitor config for iOS/Android (so.toph.solidhaus)
- Tailwind CSS v4 via Vite plugin
- All dependencies: idb, nanoid, bwip-js, jspdf, Automerge, Solid
- Route stubs: dashboard, scan, items, locations, labels, settings
- Type definitions and ID generator utility
- Project specification and ontology files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 14:50:10 +01:00

8.1 KiB

SolidHaus — Technology Research Summary

Date: 2026-02-26


1. Solid Ecosystem (2026 Status)

Libraries

Library Description Status
@inrupt/solid-client CRUD operations on Solid Pods Stable v2.x
@inrupt/solid-client-authn-browser Browser-based Solid authentication Stable v2.x
@inrupt/vocab-common-rdf Common RDF vocabulary constants Stable
rdflib.js Full RDF library (parsing, serialization, stores) Stable, heavier

Solid Servers

  • Community Solid Server (CSS): Recommended for self-hosting. Written in TypeScript/Node.js, highly modular, active development.
  • NSS (Node Solid Server): Older, being deprecated in favor of CSS.

Key Findings

  • Inrupt SDK is well-documented and suitable for read/write operations
  • Solid Notifications (live updates) is still maturing — not suitable as primary sync mechanism
  • For multi-user, use CRDT layer (Automerge) for real-time sync, Solid for long-term RDF archive

2. CRDT Libraries Comparison

Library Language Data Types Status Notes
Automerge Rust+JS JSON documents, counters, text Production Best for structured data like inventory items
Yjs JS Map, Array, Text, XML Production Best for rich text, very performant
Loro Rust+JS Rich text, List, Map, Tree, Counter Newer Very promising, integrated tree CRDT
SyncedStore JS Yjs wrapper, plain JS objects Beta Easy integration with Svelte/Vue

Recommendation: Automerge

Automerge is the best fit for SolidHaus because:

  • JSON document model maps naturally to inventory items
  • automerge-repo provides ready-made sync infrastructure (WebSocket, IndexedDB storage)
  • Conflict resolution is automatic and deterministic
  • Offline-first by design — changes merge when reconnected
  • Well-maintained, production-ready

automerge-repo

The automerge-repo package provides:

  • Document management (create, find, change, delete)
  • Network adapters: WebSocket, BroadcastChannel, MessageChannel
  • Storage adapters: IndexedDB, filesystem
  • Sync protocol handling
import { Repo } from '@automerge/automerge-repo';
import { IndexedDBStorageAdapter } from '@automerge/automerge-repo-storage-indexeddb';
import { BrowserWebSocketClientAdapter } from '@automerge/automerge-repo-network-websocket';

const repo = new Repo({
  storage: new IndexedDBStorageAdapter(),
  network: [new BrowserWebSocketClientAdapter('wss://sync.toph.so')],
});

3. Barcode Scanning Options

Native (Capacitor)

Plugin Backend Formats Notes
@capacitor-mlkit/barcode-scanning Google ML Kit All 1D/2D formats Recommended. Fast, reliable. Android + iOS.
@capacitor/barcode-scanner OutSystems libs All 1D/2D formats Official Capacitor plugin. Also uses ML Kit/Vision.

Both support: QR Code, DataMatrix, Code 128, Code 39, EAN-13, UPC-A, Aztec, PDF417, and more.

Web

Library Size Speed Formats Notes
Barcode Detection API 0 Very fast QR, Code128, DataMatrix, EAN, UPC Chrome Android/Desktop only. No Safari.
html5-qrcode ~150KB Good QR, Code128, others Standalone, no framework dependency
@nicbright/web-barcode-reader ~200KB Good Many Another ZXing wrapper

Recommendation

Primary: @capacitor-mlkit/barcode-scanning — covers Android and iOS natively. Web fallback: Barcode Detection API (Chrome) → html5-qrcode (ZXing WASM) for other browsers.

Platform matrix:

Capacitor (Android) → ML Kit native     ✅ All formats
Capacitor (iOS)     → ML Kit native     ✅ All formats
Web (Chrome)        → Barcode Det. API  ✅ All formats
Web (Safari)        → html5-qrcode      ✅ QR + common formats
Web (Firefox)       → html5-qrcode      ✅ QR + common formats

4. SvelteKit + Capacitor (Mobile Strategy)

Why SvelteKit + Capacitor

  • SvelteKit provides file-based routing, SSR/SPA flexibility, excellent DX
  • Capacitor wraps the SvelteKit SPA in native WebViews with full native API access
  • Together: single codebase → web, Android, iOS
  • Well-documented integration path (official SvelteKit docs, Capacitor docs)

Setup Pattern

SvelteKit (adapter-static, SPA mode)
  → Vite build → /build/
    → Capacitor sync → Android/iOS native projects
      → Native APIs: Camera, Barcode Scanner, Haptics, Deep Links

Key config: ssr = false, prerender = false, fallback: 'index.html'

Native Features Used

Feature Capacitor Plugin
Barcode scanning @capacitor-mlkit/barcode-scanning
Camera (photos) @capacitor/camera
Haptics @capacitor/haptics
Deep links @capacitor/app (App.addListener)
File system @capacitor/filesystem
Status bar @capacitor/status-bar

Alternatives Considered

Option Verdict
NativeScript + Svelte Stuck on Svelte 4, not maintained for Svelte 5
Lynx (ByteDance) No Svelte support yet; only works with one framework currently
Tauri 2 Mobile Supports SvelteKit, but more bleeding-edge than Capacitor for mobile
PWA only Works on Android, limited on iOS (no custom URI schemes, limited deep links)

Desktop: Tauri 2 (Future)

Tauri 2 has official SvelteKit support and can build for Windows, Linux, macOS. Can share the same SvelteKit SPA codebase. Good option for a desktop companion app later.


5. URI Scheme & Deep Linking

QR Code Content

Use HTTPS URLs as QR content: https://haus.toph.so/{id}

This works universally:

  • Native app installed → App Links/Universal Links intercept → opens app
  • PWA installed (Android) → Chrome intercepts → opens PWA
  • Nothing installed → browser → landing page

Custom Scheme (haus://)

Register haus:// in Capacitor native app for direct launches. Works when native app is installed, but custom schemes have no fallback.

import { App } from '@capacitor/app';

App.addListener('appUrlOpen', (event) => {
  const itemId = parseItemId(event.url);
  if (itemId) {
    goto(`/items/${itemId}`);
  }
});

PWA Limitation

PWAs cannot register custom URI schemes. They can only handle HTTPS URLs within their scope on Android. iOS doesn't support PWA deep linking at all (as of early 2026). This is why Capacitor native is recommended.


6. NextGraph — CRDT-Native RDF (Future)

NextGraph is a research project that merges CRDT, RDF, and Solid concepts:

  • CRDT + RDF: RDF graphs as CRDTs (OR-set / SU-set)
  • Integrated engines: Embeds Automerge and Yjs
  • Triple store: Uses Oxigraph internally
  • Solid-compatible: Can expose data as Solid Pods
  • Features: E2EE, P2P sync, SPARQL queries, offline-first

Status (2026)

  • Alpha stage, funded by NLnet/NGI (EU)
  • Not production-ready
  • Most promising option for a unified CRDT+RDF+Solid stack

When to Adopt

If NextGraph reaches beta/stable:

  • Could replace Automerge + Solid Pod with a single layer
  • RDF would be natively CRDT-enabled (no separate sync + export)
  • Monitor progress: https://nextgraph.org/

7. Additional Notes

  1. Svelte 5 runes ($state, $derived, $effect) provide built-in reactive state management. No external state library needed — the reactive system is part of the language.

  2. Capacitor Haptics: Use Haptics.impact({ style: ImpactStyle.Medium }) on successful barcode scan for tactile feedback.

  3. IndexedDB via idb: The idb library provides a clean Promise-based wrapper. Works well for offline storage. Automerge can use automerge-repo-storage-indexeddb alongside for CRDT doc persistence.

  4. Label PDF generation: jsPDF + bwip-js (canvas-based QR rendering) → downloadable A4 PDF. Works entirely client-side, no server needed for label sheet generation.

  5. EAN/UPC product barcodes: The scanner can recognize existing product barcodes. Future feature: look up product info from Open Food Facts or similar open databases to pre-fill item details.