AZB-12 AN-09 · vocabio.notazizelse.xyz

← AN-09 Vocabio

Technical document · AN-09

README

vocabio.notazizelse.xyz · README.md on GitHub

A vocabulary trainer built from your Anki export of The College Panda's 400 SAT Words You Must Know. It reads the words aloud, gives each one a tightened definition and an example sentence, and picks up your scheduling exactly where Anki left off.

Ships as three things from one codebase:

  • a website — static files, works offline
  • an iPhone app — the same site, installed to the Home Screen from Safari
  • a Windows app — an installer and a portable .exe

Progress syncs between all three.


What came out of the .apkg

progress_13092026.apkg held 400 notes, 400 cards and 1,424 reviews dating from 2026-08-02. All of it is used:

Signal Where it goes
ivl (interval) main input to the mastery score, and the starting interval
factor (ease) carried over so hard words stay hard
reps / lapses mastery score and the "Shaky" flag (3+ lapses)
revlog again-rate accuracy component of the mastery score
due converted to a real date; overdue cards are queued first
card type new / learning / review / relearning all resume correctly

Your starting position: 42% average mastery, 241 of 400 words started, 83 due, and these buckets —

mastered 100   strong 41   learning 80   shaky 20   unseen 159

The six weakest words it found: coerce, postulate, transgress, construe, obstinacy, insolent.

The definitions

All 400 definitions were rewritten to be short but still accurate, and each word got an example sentence that uses it in context. Average definition length went from 40.7 to 23.4 characters (42% shorter; the longest dropped from 147 to 52). 54 entries got slightly longer where the original was too terse to be accurate — mired was just "stuck in mud". Multi-sense words keep both senses where the distinction matters (contend → "to assert; to struggle with"), and the entries Anki stored as to stress / delegate (verb) / consummate (adj.) now carry a clean headword plus a part-of-speech label.

The word is bolded inside its own example, including inflected forms — all 400 verified, no false matches.

Each word also carries 2–3 common synonyms, shown alongside the definition in Review, Browse and the Listen player, and searchable from Browse.


The two study modes

Active learning — the Anki loop. The word appears, you recall the meaning, reveal, then grade yourself Again / Hard / Good / Easy. Each button shows the interval it would give you. Keyboard: space reveals, 1–4 grade, S replays the audio. Cards you mark Again come back later in the same session.

Passive learning — hands-free. It reads word → meaning → example, then moves on by itself. Order it by weakest first, due now, unseen, A–Z or shuffle, and set the speed and the gap between lines. Leave it running while you do something else.

Speech uses the voice already on your device, so there is no API key, no account, and no network call.


Run the website

Any static host works — the app is plain HTML/CSS/JS with no build step and no external requests.

Locally:

npx http-server app -p 5178 -c-1

To put it on your phone, deploy the app/ folder (not the repo root).

Netlify Drop — quickest, no account needed to start:

  1. Run npm run zip:web (or use the prebuilt dist/vocabio-web.zip).
  2. Drop that zip on https://app.netlify.com/drop.
  3. Netlify gives you an HTTPS URL straight away. Claim the site to keep it.

index.html sits at the root of the zip, which is what Netlify expects — zipping the app folder itself would nest everything one level too deep and serve a 404.

Netlify CLI — better for repeat deploys. Log in once, then deploy any time:

npm install -g netlify-cli
netlify login          # opens a browser; authorise there
npm run deploy         # netlify deploy --prod --dir app

Cloudflare Pages / Vercel — point the project at app as the output directory. GitHub Pages — push the repo and serve /app from your branch.

Whichever you pick, the URL must be HTTPS: Safari will not install a Home Screen app, register the offline worker, or grant a wake lock over plain HTTP.

For the iPhone, see the next section.

Install on iPhone

The iPhone version is this same site, added to the Home Screen. iOS 18 runs it full screen with its own icon, offline, with no Safari chrome — and Apple has no way to sideload anything else without a Mac, Xcode and a paid developer account, so this is the route that actually works.

  1. Deploy app/ somewhere with HTTPS (see above — Netlify Drop is quickest). HTTPS is required; offline caching and speech will not work over plain HTTP.
  2. Open the URL in Safari on the iPhone. Chrome or Firefox on iOS cannot install it.
  3. Tap the Share button, then Add to Home Screen, then Add.
  4. Launch it from the Home Screen icon.

What was done for iOS specifically:

  • Speech is primed on your first tap, because iOS refuses to speak otherwise.
  • The Chrome keep-alive trick is disabled on iOS, where it stops speech instead.
  • Every utterance carries a watchdog, so a dropped onend event cannot freeze the passive player mid-session.
  • A screen wake lock holds during passive sessions, so the phone does not sleep between words.
  • Layout respects the Dynamic Island and home indicator; sliders, switches and buttons are sized for thumbs; inputs are 16px so iOS never zooms on focus.
  • The app asks iOS for persistent storage, so your progress is not evicted after a week of not opening it.

Two things worth knowing: speech follows the silent switch, so flip the ring switch on if you hear nothing; and iOS suspends web apps in the background, so passive sessions play while the app is on screen rather than behind a locked phone.

Sync across devices

Each device keeps its own copy and syncs through a tiny server you control. Every card carries the time it was last graded, and merging happens per word — so if you review on the phone and the PC before either syncs, both sets of work survive. A blob-level "newest file wins" would silently throw one away.

1. Put the server somewhere

Cloudflare Workers (free, no card, nothing to maintain):

npm install -g wrangler
cd server
wrangler kv namespace create VOCABIO      # paste the id into wrangler.toml
wrangler deploy

You get a URL like https://vocabio-sync.<you>.workers.dev.

Or run it yourself — your PC, your LAN, or any free Node host:

node server/server.js

2. Point the apps at it

In Settings → Sync across devices on any one device: paste the server address, press New code, then Sync now. On every other device enter the same address and the same code.

After that it syncs on open, after each study session, and when you close the app. Sync now forces it.

The sync code is the only credential — anyone who has it can read and change your progress, so treat it like a password. Nothing else is stored: no account, no email. If you would rather not run a server at all, Settings → Progress → Export / Import still moves a file by hand.

Run the Windows app

Already built, in dist/:

  • Vocabio-Setup-1.0.0.exe — normal installer, lets you pick the folder, makes Start-menu and desktop shortcuts. This is the one to hand to another PC.
  • Vocabio-Portable-1.0.0.exe — single file, no install, runs from a USB stick.

Neither is code-signed, so SmartScreen will show More info → Run anyway the first time.

To rebuild:

npm install
npm run dist

During development, npm start opens the app without packaging.


Refreshing from a new Anki export

Export the deck from Anki again, drop the .apkg in the project root, and:

python tools/build_data.py

It rebuilds app/data/deck.js, keeps every curated definition (matched by the original Anki front field), and stamps a new offline-cache version so phones pick up the change. Pass a path to target a specific file.

Edit the wording in data/words.json and re-run the same command.

Starting over

Settings → Progress → Reset returns this device to the state in the .apkg. It only clears the device you press it on; if sync is on, the next sync pulls the other devices' history back. To wipe everything, reset each device and then press New code to start a fresh sync record.


Layout

app/                 the actual application — this folder is what you deploy
  index.html
  styles.css
  js/scheduler.js    SM-2 scheduling, mastery score
  js/store.js        state, persistence, queue building
  js/speech.js       text-to-speech (incl. the iOS workarounds)
  js/sync.js         cross-device sync client
  js/ui.js           views and routing
  data/deck.js       generated: 400 words + your Anki state
  sw.js              offline cache
data/words.json      the curated definitions, examples and synonyms (edit here)
tools/build_data.py  .apkg -> app/data/deck.js
desktop/main.js      Electron shell
server/worker.js     sync server for Cloudflare Workers
server/server.js     the same sync server as plain Node
server/merge.js      the merge rule, shared by both
dist/                built Windows installer and portable exe

The scheduler mirrors Anki's defaults: learning steps 1m/10m, graduating interval 1 day, easy 4 days, ease ±150/−200, lapses halve the interval, and intervals get a small random spread so cards studied together don't clump forever. Grading previews deliberately skip that spread so the four buttons always read in order.