█████▄ ▄███▄ █▓▄██▄ █▓███▄ ▄███▄ ▄█████ ▄███▄ ███▓██ ██ ██ ▓▒ ▀▒▓ ▓▒▀ ▀▒▓ ▓▒▀ ▀▒▓ ▓▒ ▀▒▓ ▓▒▀ ▀▒▓ ▓▒▀ █▒ ▓▒▀ ▀▒▓ ▓▒ ▓▒ ▒▓ ▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ▒░ ▒░ ░▒ ▒░ ▒░ ░▒ ░ ▄ ▀ ░ ░ ░ ░ ░ ░ ░ ░ ░ ██░ ░ ░ ░ ░ ░ ░ ▄ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░▒ ▀▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ▒░ ░▒ ░▒ ░▒ ▒░ ░▒ ░▒ ▒░ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▓▒ ▒▓ ▒▓ ▓▒ ▓█ █▓ ▓█ █▓ ▓█ █▓ ▓█ ▄█▓ ▓█▄ ▄█▓ ▓█▄ █▓ ▓█▄ ▄█▓ ▓█ ▓█ █▓ ██ ██ ██ ██ ██ ██ ██████▀ ▀███▀ ▀█████ ▀███▀ ██ ██ ██
════════════════════════════════════════════════════════════════════════════════
Node 1 · 2400 baud · 40 msgs in 6 areas · sysop randogoth
════════════════════════════════════════════════════════════════════════════════
════════════════════════════════════════════════════════════════════════════════
Msg : smolmail-clients Area : MINIMAL From : randogoth Date : 13 Oct 2026 Subj : Browser, Desktop and Phone smolmail Apps Keys : smolmail, rust, flutter
Msg : smolmail-clients
Area : MINIMAL
From : randogoth
Date : 13 Oct 2026
Subj : Browser, Desktop and Phone smolmail AppsKeys : smolmail, rust, flutter
════════════════════════════════════════════════════════════════════════════════
The last post ended on fumi-core, the Rust library underneath the reference client, and on the claim that everything in this post would be built on it. That turned out to be two thirds true, and the exception is the interesting one.
gsmol runs in a browser. There is no Rust in it at all: the sealing, the signing and the Noise handshake are reimplemented in JavaScript, about a thousand lines across crypto.js, noise.js and proto.js, because a browser tab cannot open a TCP socket and I wanted the client to be just a page. The Python part, bridge.py, is 154 lines and does nothing but relay bytes. It never sees a key and never sees a plaintext. The bridge binds to 127.0.0.1 and has no TLS of its own. That is fine on your own machine and nowhere else. That's a feature, not a limitation.

carrier is the desktop client, Rust on fumi-core, and it has been rewritten once already. It started on Iced, and then moved to GTK4 with Relm4 and libadwaita. It is at v0.2.0 now, with a Flatpak and a Windows installer built by CI, and the Flatpak sandbox keeps its config under ~/.var/app/com.randogoth.carrier, so installing it gives you a fresh identity. Closing a compose window from the sidebar saves it as a draft instead of losing it, custom Key: value headers are checked against the frontmatter rules and cannot override carrier's own fields, and strict first contact makes it pause before writing to a new address that carries no key, offering to fetch and pin the server's key so you can compare it against what the operator published.

kirakira is the phone (plus desktop!), Flutter, at v1.0.0, and it is fumi-core again by a longer route: a Rust wrapper crate exposes a C ABI, that ships in the APK as libsmol_mail_native.so with SQLite bundled, and dart:ffi speaks to it from the Dart side. Addresses move around by QR code, and any smol:// link a camera or browser hands the device lands in a confirm-first import dialog. The on-device tests run under Patrol against a live local bunshin, driving onboarding, registration, fetch cancellation and key rotation on a real device, in an install that sits beside the real app with its data cleared between runs.

Credit where it is due: kirakira began as FlashMail by sarthakkimtani, a Flutter UI template for a disposable-email app built on mail.tm. The protocol underneath it was replaced entirely, the UI it started from is why the thing looked finished long before it was.
The one invariant all three ended up sharing wasn't planned. In each of them the 32-byte seed is the only secret, it is shown exactly once at creation, and no backup file contains it. kirakira reads gsmol's v2 encrypted export, so a backup written in a browser restores on a phone. Three UI stacks agreed about that without being told to, which is a better argument for the protocol being the right size than anything in the spec.
Nine days ago smolmail was just one Python file for a server and one for a client, and what the protocol did was whatever those two files did. It isn't that any more. A browser tab, a GTK window and an Android app now disagree about nearly everything above the wire and about nothing on it.
--- RANDOGOTH BBS * Origin: randogoth.com (1:1/1)
────────────────────────────────────────────────────────────────────────────────
[I]ndex [K]eywords [F]eed Main [M]enu
Command: