Releases: epheterson/Zimi
Release list
Zimi 1.8.1
Zimi 1.8.1
A polish-and-hardening release on top of the Community Edition. The big one is access control — a Zimi server can now be open to everyone, limited to a chosen set of ZIMs, or sign-in-required — and the whole private-mode path is tightened so private really means private. On top of that: the offline "did you mean?" grows into the coverage 1.8.0 promised, downloads get a nightly window and bandwidth caps, and light mode gets a proper contrast pass.
Choose who sees what
- Three access modes for anonymous visitors. Set your server to Open (the whole library, the default), Limited (only the ZIMs you pick), or Private (sign-in required to see anything). Named user accounts and their per-ZIM allowlists still work exactly as before on top of this — Limited/Private just decide what someone who isn't signed in gets. Set it in Manage → Users, or with
ZIMI_PUBLIC_ACCESS. - Private really means private. The private-mode gate is default-deny: every read and data endpoint is blocked for an anonymous visitor unless it's on a tiny login allowlist, so nothing leaks by omission. A corrupt policy file fails closed, not open.
- Your own account, on the server. Signed-in users can now save their bookmarks, history and preferences to their own server account and restore them on another device — each user can only ever touch their own data.
Backup, rebuilt
- Two clearly-separated cards — "My data" (this browser's bookmarks, history and preferences) and "Server backup" (the library, collections, layout and every user's server-side data). Each has its own Export and Import.
- Imports merge by default with a preview-then-apply step and an overwrite escape hatch, and they're scope-checked so you can't drop a My-data file on the Server card (or the reverse) by mistake.
"Did you mean?", delivered
- 1.8.0 shipped offline spelling correction and flagged that its coverage was a work-in-progress. 1.8.1 is the widening: it now finds words spread thin across your titles (mitochondria, photosynthesis), catches longer two-typo misspellings (
fotosynthesis→photosynthesis), and fixes a common typo even when the misspelling itself appears in your library (einstien→einstein) — all still built entirely from your own ZIMs, with no network, ever. - The corrected vocabulary is now cached to disk, so it isn't rebuilt on every start.
Downloads on your terms
- Nightly window — schedule downloads to run only inside a time window (say, overnight); anything you start outside it waits, with a start-now override when you don't want to wait.
- Bandwidth caps — a download speed limit that's shared across all your transfers (so ten downloads still sum to your cap, not ten times it) and an upload limit, plus bulk Pause / Resume / Delete-all over the queue.
- BitTorrent — max concurrent downloads and max peer connections are now adjustable knobs.
Read better
- App theme — an Auto / Dark / Light switch for the whole interface, with an option to auto-darken raw article pages when the app is dark, and a Reader View Auto theme that turns sepia in light mode.
- Light mode contrast pass — toggles, badges, disabled fields and icons all pass WCAG AA now, tiles are redesigned, and the Safari tab-switch flash is gone.
- Define clamps to the screen and dismisses on scroll like a native menu, and no longer collides with the iOS text-selection callout.
- PDF collections (
zimgit-*ZIMs) render as a searchable document list — title, author, size, description — instead of a raw page. - Video ZIMs remember where you left off, size correctly on phones, and get a random-video card.
Fixes
- #38 — in-page
#fragmentlinks (single-page docs like devdocs) now scroll instantly instead of hanging for 15 seconds behind a loading spinner. - Health report now catches a ZIM that opens fine but is a broken scrape — every article an empty shell, or its media all 0-byte — and flags it, instead of reporting it healthy.
- Snippets on iFixit device pages show the device's own description instead of the one repeated boilerplate blurb baked into every page.
- Raw articles no longer overflow sideways on narrow screens; the Move to… menu stays put and stays on-screen.
Under the hood
- BitTorrent installs by default now.
pip install zimipulls libtorrent automatically wherever a prebuilt wheel exists — CPython 3.9–3.13 across Linux (glibc and Alpine/musl, including ARM NAS), macOS and Windows — closing the 1.8.0 gap where a bare pip install left you on HTTP-only. No wheel for your interpreter (e.g. Python 3.14, which has none yet)? Zimi quietly falls back to HTTP and tells you the one-line fix;pip install zimi[bt]forces it. - Security hardening across the private-mode path: the service worker no longer caches identity or library endpoints (fixing a "sign in twice" bug and a stale-library leak), and a new HttpOnly admin session cookie means a private-mode admin sees the full library and can open articles again — revoked on logout and on any password change.
Also in the box
- The almanac gains a real bright-star field, a Regional / Worldwide holidays toggle, a wider set of cities with click-anywhere map selection, and more of its stars, planets and people linking straight into your installed encyclopedias.
Install
brew tap epheterson/zimi && brew install --cask zimi # macOS
sudo snap install zimi # Linux
docker run --network host -v ./zims:/zims -v ./zimi-config:/config epheterson/zimi
pip install zimiWindows: download the installer from the release page.
Full detail in CHANGELOG.md.
Zimi 1.8.0 — Community Edition
You asked. Zimi listened.
This is the release the people using Zimi shaped: every open issue on the tracker answered, the ZIM ecosystem's longest-standing requests built, a native Windows app, and a real API for agents.
You filed it. We fixed it.
- New ZIMs are easy to spot — a New badge on anything freshly installed, plus Recently added and Recently updated filter pills on your home library (30-day window). The badge clears when you open the ZIM. → #34
- Organize your library your way — right-click any ZIM (or use the ⋯ gear on its Manage row) to move it into another category, including brand-new ones you name, and drag your home sections into any order from the Reorder panel in Manage. → #37
- Settings stop locking you out on your own network — Tailscale and other CGNAT clients (100.64.0.0/10) now count as your private network, so Manage doesn't force a password prompt over the tailnet. → #36
- "Not found" errors, gone — in-page
#fragmentlinks in single-page docs (devdocs) resolve instead of 404ing, and leftover.zim.torrentfiles no longer masquerade as broken ZIMs (they're moved aside at startup). → #38 - Country holidays get their own colour on the calendar, distinct from worldwide observances, and place correctly on every calendar system. → #33
The ecosystem asked, too
- "Did you mean?" — offline spelling correction on weak searches, built entirely from your own library's vocabulary. No network, ever. (The long-standing offline spell-check ask, libzim#731.) Coverage grows with your title indexes — a work-in-progress we're widening in 1.8.1.
- Read aloud — a speak/stop control in the reader uses your browser's offline speech engine. (kiwix-js#166.)
Read the way you want
- Reader View — a Safari-Reader-style clean reading column: ZIM chrome (navboxes, infoboxes, edit links) stripped, wide tables wrapped, dark by default, with Dark / Light / Sepia themes, serif or sans, an A−/A+ text size, and an AUTO mode that opens articles straight into it. Reach it from the reader's ⋯ menu.
- Word lookup — double-tap or select any word inside an article and a small Define popover appears; tap it for the first definition, pulled from your own installed Wiktionary. It follows your language, works in the normal reader and Reader View, and stays out of the way when no Wiktionary is installed.
- Tap-to-zoom images — a scaled-down image opens full size in a lightbox.
- Print, Save as PDF, and Share — a new row in the Reader palette.
One server, your whole household
- Named user accounts on top of the existing password admin — sign in and out, manage everyone from an admin Users pane (Manage → ⋯ → Users). Roles are admin / user / limited, with an optional management username and last-login tracking. Single-password installs need zero migration.
For agents and developers
GET /chunks— deterministic, embedding-free article chunking for RAG clients, with stable content-addressed chunk IDs (the same ZIM and parameters produce identical IDs on every server; a ZIM update rolls them).GET /openapi.json— a real OpenAPI 3.1 description of the read API, withinfo.versiontracking the running server.- MCP
get_chunks, did-you-mean passed through MCP search, plus a documented API stability policy indocs/api-stability.md.
Downloads that don't lose your progress
- Resumable downloads — quit mid-download and it picks up where it left off.
- Delta updates — updating a ZIM that has a torrent reuses the unchanged pieces of the old file instead of re-fetching gigabytes; the download shows how much it saved.
- Download-this-ZIM buttons on the source header and every Manage row (where the raw file can actually be pulled), a switch-to-direct escape hatch for a stuck torrent, and seeding goals with a progress bar that survives restarts.
A native Windows app
A one-dir Zimi-windows-x64.zip (Edge WebView2) that self-updates via WinSparkle, signed with the same appcast key as the macOS Sparkle path, with a per-user installer that needs no admin rights.
Also in the box
- Library health report — Manage → library runs a per-ZIM ✓/⚠ check (main page, entry count, index status, size against the catalog, age).
- Save your bookmarks to a ZIM — export them to a standalone
.zimany reader can open. - Instant Catalog (stale-while-revalidate), faster update checks (concurrent OPDS fetches), compact tile view, language pills and badges so six same-named Wikipedias are finally tellable apart, and real article counts on every card.
Under the hood
- One BitTorrent engine — the aria2 sidecar is gone, replaced by in-process libtorrent: real per-torrent stats, fast-resume, no stray processes or RPC ports. Bare
pip install zimifalls back to HTTP as always. - Security hardening — a P0 libzim segfault race fixed,
/dl/no longer exposed to the public internet, the multi-user surface locked down, and a cross-user search-cache leak closed. - Ten languages, audited — every user-visible string translated, English leaks closed, orphan keys removed.
Install
brew tap epheterson/zimi && brew install --cask zimi # macOS
sudo snap install zimi # Linux
docker run --network host -v ./zims:/zims -v ./zimi-config:/config epheterson/zimi
pip install zimiWindows: download the installer from the release page.
Full detail in CHANGELOG.md.
v1.7.4
The 1.7 line — "Reach + Pro." Getting knowledge around: peer-to-peer and LAN ZIM sharing, BitTorrent with mirror nodes that carry a whole catalogue through an internet blackout, accessibility, and UX that holds up at 1000+ ZIMs — while the almanac quietly grew up. This release caps that arc.
Closes the two live issues the post-1.7.3 audit surfaced, and grows the almanac up: an accurate Chinese calendar, a real high-res moon, and a solar system you can travel out to.
🔒 Security
/dl/no longer serves whole ZIMs to the public internet on host-networked deploys behind a containerized reverse proxy. Honors Cloudflare's un-forgeableCF-Connecting-IP, trusts a forwarded client only from a private proxy hop (optionalZIMI_TRUSTED_PROXIESallowlist), and refuses forwarded values claiming loopback.
🌘 Almanac
- Accurate Chinese calendar — real astronomical new moons + solar-term leap months; verified against the HK Observatory (New Year dates + leap months 2014–2033). Browsable calendar system with the 闰 leap marker and correct zodiac.
- Holidays on every calendar — worldwide/regional/astronomical events (international days, Easter cycle, solstices, meteor showers, Hindu/Sikh) project onto Hebrew/Islamic/Chinese/… grids by absolute date instead of vanishing off Gregorian.
- Real high-res moon — reprojected from NASA's seamless lunar albedo map (genuine crater detail, subtle true colour); the animated sky moon shares the hero's shading, earthshine dark side and all.
- Travel the solar system — Voyager 1/2, Pioneer 10/11 and New Horizons plotted at their real bearings past Neptune, creeping outward as the clock runs, framed by labelled asteroid, Kuiper and heliopause markers.
- Easier location — the world map cycles through overlapping cities on repeated clicks; search reaches 354 cities.
🐛 Fixed
- A libzim segfault under normal use — a background thread read a shared archive with no lock; it now uses its own handle. Added a real-ZIM concurrency stress test.
- Search could silently drop a ZIM under concurrent load (archive published before its lock).
- LAN discovery advertised the wrong BitTorrent port when a custom port was set.
- Malformed HTTP Range headers no longer 500 the download endpoint.
- Clean "Zimi" almanac breadcrumb; in-place location refresh (no scroll jump/flash).
✨ Added
- New / Updated ZIM badges — clear the moment you open the ZIM, week backstop.
- Country holidays get their own colour on the calendar.
660 tests green. Full detail in CHANGELOG.md.
🤖 Generated with Claude Code
v1.7.3
The 1.7 series has been about reach: BitTorrent-first downloads, LAN library sharing, mirror mode, and surviving without the internet. 1.7.3 closes the loop by making all of it dependable — downloads that can't wedge or blank the page, seeding that genuinely works and tells the truth, and settings that mean what they say. Both open field reports are fixed. And the almanac easter egg grew into a real instrument, if you know where to look.
Highlights
- The downloads page stays put. With a download running, the UI's own status polling could trip the rate limiter and blank the panel (#30). Fixed at the root — it holds up behind reverse proxies and with a password set.
- Downloads can't hang forever. A torrent with peers but no data now falls back to HTTP instead of sitting at "0% · 0.0 MB/s".
- Seeding actually works now — and survives restarts. Ratio caps were silently killing every capped seed the first time a peer took a piece (an aria2 semantics trap; only uncapped mirror seeds ever survived). Zimi now enforces your cap itself — against lifetime upload, across restarts, booked every 30 seconds — and keeps its own ledger of intended seeds, restoring any that go missing at startup. Stopping a seed on purpose sticks.
- Settings govern live torrents. Changing your seed ratio, toggling seeding, or flipping Mirror applies to running seeds immediately — not just the next download. The BT status light no longer shows green over a dead engine, and deleting a ZIM stops seeding it.
- Central Europe gets its own clock (#28 follow-up). Germany, Poland, Austria and friends no longer resolve to London time.
- The almanac grew up. Pick any day and the whole page follows — moon, sun times, sky, history. A star chart you can scrub through time and drag across the Earth, the Sun's yearly figure-eight, moon phases on the calendar, and an international On This Day feed. Under the hood, a full accuracy pass: the hero moon now faces the Sun, eclipses stopped inventing visibility regions, and anything the math can't truly support is no longer claimed.
Full details in CHANGELOG.md.
Zimi v1.7.2
Both open field reports fixed within a day (#30, #28), and the distribution story finished: desktop apps that torrent out of the box, mirror nodes that can carry the whole catalog through an internet blackout, and an almanac that tells the truth about every date it shows. Rounded out with a sharing panel that's rock-solid and honest, and BitTorrent that actually seeds what it says it will.
Highlights
- Desktop apps torrent out of the box. The Mac and Linux apps now ship their own BitTorrent engine, signed and notarized with the app. Every install shares the load with the Kiwix mirrors, automatically.
- Your router opens the door. Like every real BT client: automatic UPnP port-forwarding, a port open/closed indicator, and a retry button, right in the BitTorrent settings. DHT is on, so magnet links and trackerless swarms just work.
- Mirror mode is real now. Flip one switch and Zimi seeds your whole library, uncapped, and archives the torrent for every catalog item — a single mirror node can bootstrap ZIM distribution for an entire offline network. Turning it off stops the mirror seeds (ordinary ratio-capped seeding continues) and never deletes the backup.
- Built for the day the internet isn't there. Every install keeps an offline copy of the catalog and a magnet link per installed ZIM. The catalog browses, searches, and installs from LAN peers with zero connectivity.
- Honest seeding. Seeds survive restarts, and the seeding panel shows snagged ones in red with the reason instead of hiding them.
- The calendar is yours, wherever you are. Click your location on the almanac map: national holidays follow (17 countries + a worldwide set), season names match your hemisphere, and equinoxes are computed to the minute. A new "About this data" section states the precision of every date on the page, in all 10 languages.
- The world clock is alive: 28 cities, one per UTC offset, each card tinted by its local daylight with solid sun/moon marks, the selected city glowing, and a digital card beside the analog clock — split-flap seconds, date, and timezone (PST/CET) included.
- The BitTorrent port is editable in place — change it and the engine respawns on the new port with UPnP re-mapped, live. Peer names apply instantly too (no more restart notes), and Mirror shows its progress while it seeds your library and backs up the catalog.
- Panels stopped blanking themselves (#30): the manage UI no longer trips Zimi's own rate limiter, and a rate-limited response keeps last-known content instead of clearing the page.
- Downloads are stubborn now: they survive server restarts, refuse to start when the disk can't fit them, and flip their catalog card to Installed the moment they land.
- Standing maintenance: catalog, port mapping, seeds, and magnets refresh themselves every 12 hours — no visit required.
- One control for sharing speed: set a max up/down rate right in the BitTorrent card (0 = unlimited); it governs downloads, personal seeds, and mirror alike. The Server → Sharing panel is now rock-solid — no layout jump, instant toggles, and status lights that never lie.
Added
- Global up/down bandwidth caps for BitTorrent, set in MB/s in the Sharing panel (0 = unlimited). Applied to the whole aria2 engine — downloads, seeds, and mirror — so one pair of numbers governs all sharing speed. Live-adjustable without a restart.
- Desktop apps torrent out of the box: the DMG and AppImage now ship their own aria2 sidecar (hash-verified static build on Linux, relocated Homebrew build on macOS, codesigned and notarized with the app). The BT-first default finally applies to every install, not just Docker.
- Port health in BitTorrent settings, like a real BT client: an open/closed/unknown indicator for the listen port, automatic UPnP port-forwarding (on by default, stdlib implementation, fails soft), and a retry button that re-maps and re-tests on demand.
- True mirror mode: turning Mirror on now seeds your whole installed library — aria2 hash-checks each existing file and seeds it in place, uncapped, using saved .torrent files (works offline) or the catalog's torrent URLs. Seeds whose file an update replaced are retired automatically. Mirrors also archive the .torrent for every catalog item (~40-80 MB for the full catalog), making a mirror node a complete offline index: any ZIM can be fetched, verified, and re-seeded with no internet at all.
- Post-world resilience: the last good Kiwix catalog persists to disk and stays browsable when the internet is gone (with a quiet "showing catalog from " note), and every BT download keeps its infohash, magnet link, and .torrent file so ZIMs can be re-seeded into offline swarms later.
- Honest seeding: completed BT downloads re-seed from the library file itself (the old in-place seed died silently on restart), and the seeding panel shows snagged seeds — errored or file-missing — in red instead of hiding them. Mirrors especially.
- Nearby warns when it can't work: Docker bridge mode advertises an unreachable container address; the Nearby card now says so and the ZIMI_NEARBY ip= field (or host networking) fixes it.
- The almanac states its precision like an encyclopedia: a new "About this data" section covers algorithms, calendar accuracy, and coverage in all 10 languages. Equinoxes and solstices are now computed (Meeus, verified to within ~1 minute of USNO reference times) instead of pinned to fixed dates, with hemisphere-aware season names — October is spring in Sydney.
- Every install keeps the post-world basics: the offline catalog copy plus a magnet link for each installed ZIM (infohash extracted from the catalog's torrents); mirrors additionally keep the .torrent files for the whole catalog. Turning Mirror off stops the seeds but never deletes the archive.
- Standing maintenance every 12 hours, no visit required: the offline catalog refreshes before it goes stale, the UPnP port mapping renews at half-lease (it silently expired after 24h otherwise), and magnet manifest / mirror seeds / torrent archive stay current.
- DHT is on by default (opt out with the ZIMI_BT dht= field): trackerless peer discovery makes magnet links usable and keeps swarms findable if the Kiwix trackers ever disappear. The routing table persists across restarts.
- Thumbnails prefetch gently in the background after a catalog fetch, so browsing doesn't trickle images in one at a time.
Fixed
- Downloads and settings panels no longer blank themselves (#30): Zimi's own rate limiter was counting the manage UI's polling against the anonymous budget. Clients with a valid manage credential — or any private-network client on a passwordless instance — now get 10x headroom (
ZIMI_RATE_LIMIT_TRUSTED), snippet fetches ride the roomier content bucket, and a 429 keeps the last-known panel content instead of rendering an empty state. The Server pane also no longer embeds the live seeding list, which used to grow and shrink under you — seeds live in the Downloads tab. - BitTorrent actually seeds now. A completed BT download re-added its library-path seed before removing the staging torrent — same info-hash, so aria2 rejected the add as a duplicate and no seed was ever created (the staging torrent then snagged "file missing"). Now it removes then adds. Downloads that finish over HTTP (or fall back from BT when a torrent has no live seeders) seed too, instead of silently not sharing.
- No more double entries in Downloads. An in-flight BT download used to surface as both a download card and a "seed" card under All; the seeding view now excludes still-downloading torrents, and a completed download that's now seeding shows only its seed card.
- Fresh builds show up immediately. The service worker keys its cache on a content hash of the app bundle, so any deploy — even within the same version — installs a new worker that clears the stale cache. Previously same-version deploys served old JavaScript from cache.
- The random button doesn't no-op. An unlucky ZIM pick could return nothing and leave the dice looking dead; it now retries across a few sources (and the client retries) so the first roll always opens something.
- The almanac speaks world, not American (#28): Gregorian holidays are an international base plus one region pack (17 countries + EU catch-all) picked from the browser locale/timezone — a British calendar shows Guy Fawkes Night and bank holidays, not Thanksgiving. Clock changes follow the region's real rule. The timezone picker grows from 16 to 28 cities covering every UTC offset in common use, including Central Europe ("Italy uses UK time" is fixed) and the half-offset zones, translated in all 10 languages.
- Your location drives the calendar: click anywhere on the almanac map and the holidays follow — Italy gets Ferragosto, all offline. A quiet caption says whose days are showing, and each national day carries a country tooltip.
- The world clock is alive: each city card is tinted by its local hour (day, dawn, dusk, night) with a small glyph — the grid reads as a band of daylight matching the map's terminator.
- Picture of the Day no longer shows yesterday's picture (the Discover cache keyed on the UTC date while content used the local date).
- Closing the reader now restores the underlying view's URL — a reload no longer reopens the article you just closed.
- Downloads survive restarts: pending and queued items persist and resubmit at startup through their validated entry points, resuming partial files. Downloads refuse to start when they would fill the disk (expected size + 2 GB floor, or the disk-pressure threshold).
- Passwordless instances accept management commands from the local network only; public clients must set a password first. Instances with a password are unchanged.
- RTL article/ZIM titles (Arabic, Hebrew, Farsi) no longer reshuffle neighboring punctuation in LTR chrome.
- C...
Zimi v1.7.1
The "Reach + Pro" release. Addresses issue #15 (the warlordattack feedback set
covering UX at 1000+ ZIM scale) and issue #16 (Wikipedia maxi auto-updating to
mini), and delivers the Reach track: P2P distribution + accessibility.
Highlights
- Your downloads now share the load. Every Zimi that can torrent
automatically helps distribute ZIMs instead of leaning on the Kiwix
mirrors. On by default, seeding capped at a polite 2x, controlled by
real switches in Server Settings. - Share your library with nearby machines, no internet needed. Flip
on Nearby and Zimi instances find each other on your network. When a
nearby machine already has a ZIM you're browsing, a green pill lights
up on the catalog card. - Corruption-proof installs. Every downloaded file, whether torrent,
HTTP, or LAN peer, must pass structural validation before it touches
your library. A broken transfer can never replace a good ZIM. - Accessible. If you browse by keyboard, listen by screen reader, or
need high contrast, accessibility is built-in. 100/100 Lighthouse
score across the app. - The catalog and downloads got a real overhaul. Batch-select many
ZIMs and grab them at once, watch real per-file progress with pause
and resume, see what you're seeding back, and let the catalog hide
things you already have. - Smarter, safer updates. A full "maxi" Wikipedia will never
silently downgrade to "mini" again (#16), auto-update follows Kiwix's
new mirror URLs (#20), and the updates panel shows exactly what's
waiting. - Built for big libraries. A live activity bar shows background
work, hot-cache pins your most-used ZIMs for instant search, and
startup is dramatically lighter (#15).
New in 1.7.1
- Updates work again for older clients (#26):
http://catalog URLs
are upgraded tohttps://instead of rejected, every rejected
download now logs its reason, and mirror-list lookups no longer stall
the server ("Request timed out" spam is gone). - Screen-reader text no longer shows under the almanac sky (#25),
even against stale cached stylesheets or translations. - Version stamps (service worker, Snap package,
/health) all derive
from one source now, so a stale constant can never disable the PWA or
mislabel a package again. - Queued downloads show the sweeping "preparing" bar instead of a
stalled-looking 0% bar, and a finished download flips its catalog card
to Installed immediately. - Saving a sharing setting on a read-only config directory returns a
clear error instead of failing silently.
Full details (engineering notes, fixes, QA history): CHANGELOG.md · v1.7.0...v1.7.1
Zimi v1.7.0
The "Reach + Pro" release. Addresses issue #15 (the warlordattack feedback set
covering UX at 1000+ ZIM scale) and issue #16 (Wikipedia maxi auto-updating to
mini), and delivers the Reach track: P2P distribution + accessibility.
Highlights
- Your downloads now share the load. Every Zimi that can torrent
automatically helps distribute ZIMs instead of leaning on the Kiwix
mirrors. On by default, seeding capped at a polite 2x, controlled by
real switches in Server Settings. - Share your library with nearby machines, no internet needed. Flip
on Nearby and Zimi instances find each other on your network. When a
nearby machine already has a ZIM you're browsing, a green pill lights
up on the catalog card. - Corruption-proof installs. Every downloaded file, whether torrent,
HTTP, or LAN peer, must pass structural validation before it touches
your library. A broken transfer can never replace a good ZIM. - Accessible. If you browse by keyboard, listen by screen reader, or
need high contrast, accessibility is built-in. 100/100 Lighthouse
score across the app. - The catalog and downloads got a real overhaul. Batch-select many
ZIMs and grab them at once, watch real per-file progress with pause
and resume, see what you're seeding back, and let the catalog hide
things you already have. - Smarter, safer updates. A full "maxi" Wikipedia will never
silently downgrade to "mini" again (#16), auto-update follows Kiwix's
new mirror URLs (#20), and the updates panel shows exactly what's
waiting. - Built for big libraries. A live activity bar shows background
work, hot-cache pins your most-used ZIMs for instant search, and
startup is dramatically lighter (#15).
Full details (engineering notes, fixes, QA history): CHANGELOG.md · v1.6.5...v1.7.0
Zimi v1.6.5
A "hold-you-over" patch release — most-impactful bug fixes pulled
out of the in-progress v1.7.0 Reach release so they reach users
sooner. v1.6.4 originally carried these fixes but its desktop
release pipeline failed (CI bug — also fixed below); v1.6.5
publishes the same content with proper macOS / Linux binaries.
Fixed
/docs/docs/doubling on zimit-scraped ZIMs (#17, thanks @ma-javaqueen) — ZIMs scraped byzimitship with wombat.js, which rewrites<a href>ATTRIBUTES to look like the original archived URL and installs its own click handler that re-resolves them — doubling the path on every nested navigation. Iframe click chaperon now uses Kiwix's_no_rewrite=truetrick +capture: trueso we run before wombat. Right-click contextmenu got the same fix. Verified end-to-end onersatztv_2026-04.zim.- Wikipedia maxi auto-updating to mini (#16) —
_check_updatesnow filters candidates to the same flavor as the installed file. New_detect_flavor()helper for maxi/nopic/mini. Six tests including the exact bug scenario. - Bitwarden / 1Password ignoring the manage password input (#15-1a) — removed
data-1p-ignore, restored standardcurrent-passwordautocomplete contract. - "Remember me" not persisting across tab close (#15-1b) — was using sessionStorage; now localStorage when checked, sessionStorage when unchecked.
- Catalog item-installed matching (#15-8a) — also tries the prefix derived from the OPDS
download_urlto recover Kiwix-truncated names (canadian_prep_*vscanadian_prepper_*). - Missing
_updateDownloadsTabBadgefunction definition — internal call existed but body was missing on certain code paths. READY <port>not emitted byzimi serve— the macOS / Linux desktop release smoke test grep'd stdout forREADY <port>to capture the bound port (needed when--port 0lets the OS choose). Server now emitsREADY <port>immediately afterThreadingHTTPServerbinds, withflush=Trueso stdout buffers don't hide it.
Added
- Search results carry a
categoryfield (#15-4) — each result is tagged general / images / video so SearXNG (and any future router) can route hits to the right tab. - Top-search analytics (#15-9) —
/manage/usagereportstop_searcheswith a 5000-key bounded counter.
Changed
- Auto-version rewriter now also processes inline
/static/X?v=Nrefs insideapp.js. Disk write is fail-soft — logs a warning on read-only filesystems and falls back to hardcoded tokens. pyproject.tomlexcludestests/test_article_languages.pyfrom defaultpytestruns (data-dependent suite; run explicitly when investigating ZIM-data drift).
Tooling
tests/test_serve_smoke.py— five-test suite that subprocessespython -m zimi serve --port 0and verifies the contract end-to-end (READY emit, /health, /list, /search, /). Catches the desktop-release CI bite at PR time instead of after merge.tests/test_iframe_link_chaperon.py— regression guard for the wombat fix invariants.- 11 new tests across the suite (288 total).
Upgrade
docker pull epheterson/zimi:1.6.5
docker compose down && docker compose up -dOr pip install --upgrade zimi for Python installs. macOS / Linux desktop binaries are below.
🤖 Generated with Claude Code
Zimi v1.6.3
Fixed
- MCP server now warms search indexes on startup (search was returning empty results)
Changed
- Extracted
warm_indexes()fromserve()so MCP and HTTP servers share the same startup path
Upgrade
docker pull epheterson/zimi:latest
docker compose down && docker compose up -dOr pip install --upgrade zimi for Python installs.
Zimi v1.6.2
Fix: manage panel auth lockout (#12)
Fixed
- Fresh Docker installs locked behind password prompt with no password to enter
- Removed
Sec-Fetch-Siteheader dependency from all auth decisions - Token generation and password removal errors now show user-facing messages
Changed
- Auth accepts password or API token as Bearer on all requests (no header sniffing)
- API token requires a password to be set first
- Password cannot be removed while an API token is active
Upgrade
docker pull epheterson/zimi:latest and restart your container.
Or pip install --upgrade zimi for Python installs.