Show HN: Syncular – offline-first SQL sync with TypeScript and Rust cores
Syncular: Server-Authoritative, Offline-First SQL Synchronization
Syncular is a robust synchronization engine designed for offline-first applications, leveraging dual cores written in TypeScript and Rust. It ensures that data remains consistent across clients while maintaining a strict server-side source of truth.
(Placeholder image for the Syncular logo)
🏗️ Core Architecture
The system operates on a principle where clients maintain a fully functional local SQLite database. In web environments, this is achieved via OPFS (Origin Private File System), while native environments use standard SQLite.
The Sync Workflow
Writes are handled through an optimistic outbox, ensuring the UI remains responsive. The server maintains a single, ordered commit log that serves as the ultimate authority.
The mathematical essence of the synchronization can be viewed as:
🛠️ Engineering Philosophy
Syncular is built with a "Spec-First" mentality. The SPEC.md file is the definitive authority; if the implementation deviates from the specification, the code is considered incorrect and must be updated.
The Test Doctrine
"Integration scenarios utilize a loopback in-memory transport. Fault injection is applied at the transport interface. Tests must wait for explicit readiness signals—
sleep timers are strictly banned. Real-socket tests are kept to a minimum and isolated."
Cross-Core Parity
To ensure the TypeScript and Rust cores behave identically, they are kept in lockstep using an implementation-agnostic conformance suite.
📂 Project Structure
The repository is organized into specialized packages to separate concerns:
| Path | Purpose | Key Details |
|---|---|---|
packages/core | Protocol | Codecs, shared types, and vector round-tripping. |
packages/server | Backend | handleSyncRequest logic; supports SQLite, Postgres, and D1. |
packages/server-hono | Bindings | Integration for Hono and Cloudflare Workers. |
packages/web-client | Web Core | TS client utilizing @sqlite.org/sqlite-wasm. |
packages/react | UI Hooks | React-specific wrappers for the client. |
packages/typegen | Typing | Schema IR and TS emitter for named queries. |
packages/crypto | Security | Per-column End-to-End Encryption (E2EE). |
packages/crdt-yjs | Merging | Yjs-based CRDT mergers for conflict resolution. |
packages/testing | Tooling | @syncular/testkit for in-memory loopback testing. |
packages/conformance | Validation | Scenario runner for cross-core parity. |
rust/ | Native Core | Rust implementation and C-ABI FFI crates. |
bindings/ | Platforms | Support for Tauri, React Native, Swift, Kotlin, and Flutter. |
apps/docs | Documentation | The official site at syncular.dev. |
🤖 Contribution & AI Policy
All contributors—whether human or machine—must adhere to the guidelines in AGENTS.md.
AI Assistance Rules
- LLMs are encouraged for writing tests, benchmarks, and documentation.
- LLMs may be used for production code.
- Requirement: Every line must be reviewed, understood, and defended by the submitter.
-
Low-effort, machine-generated PRs or issues will be closed without comment.
For a full breakdown of the agent policy, visit syncular.dev/llms.
🚀 Getting Started
To initialize a new project, use the following command:
bun create syncular-app my-app
Development Commands
To ensure your changes meet the project's strict quality standards, run the check suite:
# Install dependencies
bun install
# Run type-checking, linting, and tests
bun run check
For more information, refer to the Documentation or the Quickstart guide.