No description https://decimen.app/
  • TypeScript 89.6%
  • CSS 5.9%
  • HTML 4.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Bash Alarmist (Evan Crawley) 5301fc2020
Merge pull request #50 from bashalarmistalt/release/v0.5.3
v0.5.3: animation export
2026-08-19 20:45:01 -04:00
.github v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
benchmarks v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
build v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
docs v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
home v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
public v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
receive v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
send v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
shared v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
tests v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
vendor/decimen-codec v0.5.0: wire format v3 (version byte, must-understand/ignorable flags, cross-version verdicts), versioning contract + golden vectors, end-to-end conformance test, auto-show privacy setting, decimen-codec 0.2.0, favicon/robots/sitemap 2026-08-12 15:49:13 -04:00
.env.benchmark v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
.env.demo UI/UX improvements, changed notes to text snippets 2026-08-01 13:25:18 -04:00
.env.diagnostics v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
.gitignore Added sponsorship options 2026-08-07 00:51:32 -04:00
.npmrc v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
.nvmrc v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
CLA-ENTITY.md v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
CLA.md v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
CONTRIBUTING.md v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
index.html v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00
LICENSE v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
NOTICE v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
package-lock.json v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
package.json v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
README.md v0.5.3: animation export (looping APNG, or a numbered PNG sequence in a ZIP for video editors) — any camera pointed at the file playing receives it like the live sender, one shared QR path so export and stream cannot drift, size forecast measured from a real frame 2026-08-19 20:37:06 -04:00
src-env.d.ts v0.4.0: relicensed to AGPL-3.0-or-later, contributor CLA, decimen-codec tracked-decode engine, diagnostics rig, published benchmark records 2026-08-09 01:02:49 -04:00
tsconfig.json v0.3.0: Android capability probing, inline media playback, share dialogs, UX overhaul, added legal name to license 2026-08-03 23:12:28 -04:00
tsconfig.node.json v0.3.0: Android capability probing, inline media playback, share dialogs, UX overhaul, added legal name to license 2026-08-03 23:12:28 -04:00
vite.config.ts v0.5.2: twelve-language localization (es, pt-BR, fr, de, it, ru, hi, zh-Hans, ja, ko, ar) — per-locale page trees with hreflang and localized PWA manifests, Arabic RTL, standalone files translate at open and switch live, per-language unreviewed-translation notes gated on a per-locale reviewed flag, coded protocol errors so failures and verdicts localize, ES2022 target (top-level await), Node pinned via .nvmrc/engines/engine-strict 2026-08-12 18:02:08 -04:00

Decimen Optical Transfer: fountain-coded QR file transfer

Send a file between two devices using nothing but a screen and a camera. One page displays the file as an endless stream of animated QR codes; another device points its camera at it and reconstructs the file. No network path between the devices, no app, no pairing, no permissions beyond the camera. The payload travels as light.

Try it

→ decimen.app

Open it on both devices and go — nothing to install. Works offline after the first visit, and installs as an app on both iOS and Android if you want it on a home screen.

Files up to 64 MB (or a pasted text snippet), filename and media type preserved, gzip only when it helps, SHA-256 verified before anything is offered — and received video plays right in the page. A stream can also be exported as a looping animation (APNG, or a PNG sequence for video editors): any camera pointed at the file playing — in a page, a stream, a video lesson — receives it like the live sender. The interface speaks twelve languages (English, español, português, français, Deutsch, italiano, русский, हिन्दी, 简体中文, 日本語, 한국어, العربية — with right-to-left layout where it belongs); machine-drafted translations say so on the page until a native speaker has reviewed them. Currently measured at 418.5 KB/s sustained screen to camera — records with receipts.

Phone receiving a file over light: 130.5 KB/s goodput, halfway through decoding the sender's animated QR stream

Mid-transfer: a phone pulling a file out of the air at 130 KB/s.

Neither mode is encrypted: whatever is on the sending screen is readable by any camera pointed at it. The property this gives you is no network, not confidentiality — see privacy.

Measured speed

sustained record

One record run per device pair. Sustained is whole-transfer goodput; peak is the best ≥1 s window inside that same run. Every row links to the full diagnostics run report that produced it (how these are measured).

pair sustained peak transfer codes devices when receipt
desktop → phone 418.5 KB/s 601.5 KB/s 1.0 MB in 2.5 s 4 Odyssey G9 49″ → iPhone 17 Pro Max 2026-08-09 (v0.4.0) run
phone → phone 199.2 KB/s 340.8 KB/s 1.0 MB in 5.1 s 2 iPhone 17 Pro Max → iPhone 17 Pro Max 2026-08-09 (v0.4.0) run

Documentation

Using it — quick start · sending · receiving · troubleshooting · install & offline · privacy

How it's built — architecture · protocol · platform quirks · build & release · localization

The short version of the protocol: a screen-to-camera link has no back-channel, so the sender streams fountain-coded frames (Luby transform) — the receiver collects any ~K·1.15 distinct frames in any order and peels the file out. Dropped frames cost time, never correctness.

Run it yourself

npm install
npm run dev               # https dev server with HMR
npm run serve             # build, then serve the production bundle
npm run demo              # demo mode: only the bundled payloads can be sent
npm run diagnostics       # dev server + per-transfer run reports in the terminal
npm run benchmark         # diagnostics + sender locked to the canonical 1 MB payload
npm run benchmark:promote # declare your best captured run a record (updates the table above)
npm test                  # golden wire-format vectors and unit tests
npm run build             # the hosted site → dist/
npm run build:standalone  # both self-contained pages → dist-standalone/
npm run build:all         # everything

Open https://localhost:5173/send/ on the sending device and the printed Network URL on the receiving phone (accept the self-signed certificate once). Walkthrough: quick start.

Similar projects

The concept here was arrived at independently. It turns out several people have had similar ideas, and their takes are all worth a look:

  • mohankumarelec/airgapped-qr-code-transfer: browser-based QR file transfer with compression and sequential chunking. Discovered after publicly demoing this project; convergent evolution in action.
  • divan/txqr (2018): animated QR plus fountain codes in Go, with two excellent write-ups on why fountain coding beats sequential looping.
  • sz3/libcimbar: goes past QR entirely with a custom high-density color code purpose-built for this channel.

Project Creator/Maintainer

Built by Evan Crawley (Bash Alarmist), with node-qrcode and decimen-codec, a custom zxing-cpp build.

License

AGPL-3.0-or-later, as of v0.4.0. Releases up to and including v0.3.0 were MIT-licensed and remain available under those terms.

Portions were contributed under MIT, and the vendored decimen-codec decoder (AGPL-3.0-or-later) incorporates zxing-cpp under Apache-2.0 — see NOTICE.