ZAYEED preview
Home / Platforms

Four shells, one library

Sign in on one device, show a pairing code, type the six digits on the next one. From then on the two are the same library — and neither of them needs the network to keep working.

Web

React and Vite over a SQLite database in the browser's own origin-private file system, running in a dedicated worker. It is an installable PWA, so it gets an icon and a window and keeps working when the wifi does not. Nothing to deploy to a lab machine, and still a full replica rather than a thin client.

Windows and Linux

The same shared core inside a Tauri 2 shell, which adds the three things a browser cannot: a real file on disk — open, save and hand over a .mcq pack like any other document — a lockdown mode for the exam hall, and seeing another Zayeed device on the same network so two machines can sync with no server involved. macOS builds from the same source.

Android

Expo and React Native, with the database in expo-sqlite. It sits papers and it writes them: questions, the leniency stops, the live tester, sets and rules, certificates, and saving or opening a .mcq through the share sheet — the same shared core the browser renders, not a cut-down phone edition. It also sees the other Zayeed devices on the same network and syncs with them directly, which on Android means two small native modules: a multicast socket holding the wifi multicast lock Android otherwise uses to drop these packets, and a TCP listener. Above them the phone runs the unmodified discovery, pairing and merge code the desktop runs, so a phone's edits are not a special case of the merge. A teacher whose only computer is a phone is not an edge case in most of the world. The proof that none of it needs a server is a test that replaces the network with something that throws, then writes a question, builds a quiz, sits it, marks it and carries the result to a second device as a file. iOS builds from the same source, but no iOS build has been produced yet.

How they stay one library

Every shell holds a full local replica and writes to it immediately. Writes are recorded as operations in a log ordered by hybrid logical clocks, and replicas exchange operations when they can reach each other. There is no "the server is the truth and you are a cache" moment, because there is no moment when a candidate mid-exam can afford one.

When the two devices are not in the same building

Then they meet at a rendezvous relay. One device asks for a meeting code — nine characters, read down the phone or typed into a message — and the other types it in. The relay seats exactly two devices per code and forwards frames between them without opening one: the two shells run the same handshake they run on a local network, so what crosses the relay is already sealed, and the six digits the two screens show are derived from the handshake transcript. A relay that swapped a key would change that transcript and the two numbers would differ, which is the whole reason a relay in the middle is safe rather than trusted. Nothing is stored: a frame with no peer waiting is refused, not queued, and when either side leaves, the meeting and the code are spent.

Honest limit: no relay is hosted for the public. This is the server component, so the route is available to anyone running their own server — and there is still no hole-punching, so the two devices never form a direct connection through NAT.

A protocol bug the convergence test found. Pull cursors ordered by client HLC silently skip the operations of a replica that has been offline for a while. Cursors are ordered by server receipt instead. This is the kind of defect that shows up as one missing answer, months later, in an appeal.

The offline case is the normal case

System requirements

ShellRequiresStorageNotes
WebAny current Chromium, Firefox or SafariOPFSInstallable; no extension, no plugin.
WindowsWindows 10 or later, WebView2SQLite fileLockdown mode for invigilated sittings.
LinuxWebKitGTKSQLite fileSame build pipeline as Windows.
AndroidAndroid 8 or laterSQLite fileAuthoring, sitting and marking. Share-sheet save and open. Direct sync on the local network.
ServerNode 20+, SQLite or PostgresYour choiceOptional. Only needed for sync, LTI and join-by-code.

Write one question. Mark it four ways.

Install the desktop build, open the browser app, or scan into the Android shell. They are the same library, the same marks and the same rules — with or without a network.