Compatibility

September 11, 2026 ยท View on GitHub

Protocol versions

Current protocol is 1.0; N-1 is 1.0 (single-version rollout; see release/compatibility.toml).

Every connection starts with the version handshake: application version, protocol version range, schema fingerprint, runtime kind, and capabilities. Peers select a mutually supported protocol version before exchanging job data. Handoff data carries app version, protocol version, schema fingerprint, required capabilities, and expiration; receivers treat every field as untrusted input, validate it, and require user confirmation before effects. No version overlap stops safely with protocol.incompatible and an update recovery action. N-2 and future versions fail with guided update or manual flows. Store and updater lag never activates unsupported features; website offers follow published capabilities. Release automation verifies generated bindings, schema fingerprints, compatibility fixtures, and this matrix (see Releases).

Browsers and operating systems

AppSupported platformVerified by
WebsiteCurrent browsers with WebAssembly, workers, and canvasReal-Chromium end-to-end runs (cargo xtask test web --e2e) plus supported browser and OS smoke tests in the release gates
Extension (Chromium)Chrome 121 or later, plus Edge, Brave, and other Chromium-based browsers (minimum_chrome_version 121, required for wasm-unsafe-eval)Headless Chromium end-to-end in cargo xtask test extension
Extension (Firefox)Firefox 128.0 or later (strict_min_version 128.0, event-page background)Headless Firefox end-to-end in cargo xtask test extension via Selenium and geckodriver
Desktop appWindows, macOS, and Linux through the Tauri shell (WebView2 on Windows, WebKit on macOS, webkit2gtk on Linux)cargo xtask test desktop; the Linux .deb builds on a Linux host while Windows and macOS bundles build only on their matching hosts
CLINative binary (Linux cli-linux-x86_64 target; the same native runtime as the desktop app)cargo xtask test native plus scenario parity

Desktop installers ship unsigned (no paid Apple or Azure signing); only the Linux .deb is buildable while Windows and macOS targets stay unavailable (see Releases). Automatic in-app updates are disabled: there is no update host or key, so users check GitHub Releases manually. The user-facing install note lives in the Desktop app guide.

Canvas and save limits

SurfaceBudgetPast the budget
Browser tab (website, extension)Browser memory and save limits; the browser promises no fixed sizeThe job stops with a typed error that names the desktop app as the next step
Desktop appIn-memory canvas: 4 bytes per pixel, subject to the memory currently available to the processTyped output.canvas-limit before allocation; nothing is written; a smaller level fits the available memory
CLIIn-memory canvas subject to the memory currently available to the processSame output.canvas-limit behavior as the desktop app

Encoder side caps apply on top of the available-memory check: JPEG addresses at most 65535 pixels per side and WebP at most 16383 pixels per side, so larger canvases save as PNG, TIFF, ZIF, or an iiif-dir tile tree. The native baseline reports encoders [png, jpeg, tiff, zif, webp], destination modes [file, iiif-dir], storage modes [cache], and bulk_supported true.

Ordinary display without readable bytes

For unprocessed ordinary tiles, browser apps may render through plain <img> elements and draw into a canvas even when the source taints it. The picture stays visible (with browser right-click save where available), but the canvas is not origin-clean: the runtime never runs pixel reads, hashing, processing, toBlob, or toDataURL on it and never promises a clean programmatic save. The website labels this limitation before rendering and points at a readable route (the extension or the desktop app) when the job needs processing or a clean save.

Format support by app

Discovery is one shared core (crates/dezoomify-core): every app recognizes the same formats in the same precedence order and selects automatically. Apps differ in reach (authentication), saving (tainted display or clean bytes), and bulk behavior, as detailed below the table. See Supported formats for what to paste per format.

FormatWebsiteExtensionDesktop appCLI
ZoomifyYesYesYesYes
Deep Zoom (Seadragon)YesYesYesYes
Second CanvasYesYesYesYes
IIIFYesYesYesYes
Arts and CultureYesYesYesYes
IIPImageYesYesYesYes
TopViewer (Memorix)YesYesYesYes
krpanoYesYesYesYes
FSI ViewerYesYesYesYes
LizardTech ImageServerYesYesYesYes
Visual Library Server (VLS)YesYesYesYes
XLimageYesYesYesYes
HungaricanaYesYesYesYes
ArcGIS MapServerYesYesYesYes
WMTSYesYesYesYes
pnavYesYesYesYes
Generic tile patternYesYesYesYes
Custom tiles (tiles.yaml)Yes, over http(s) tile URLsYes, over http(s) tile URLsYes, plus local filesYes, plus local files
Bulk text (URL list)Single-queue, one at a timeDeferred entries, one at a timeMulti-job queue, one at a time--bulk loop, one bounded run per entry

Authentication

  • The website never signs in anywhere: direct browser fetch and browser-to-proxy requests omit cookies, Authorization, and browser credentials. Only eligible public, non-credential metadata requests fall back to the metadata CORS proxy (never tiles); signed or token-bearing URLs are ineligible. Members-only collections need the extension.
  • The extension works inside the user browser session, but only for origins covered by granted host permissions (activeTab on the scanned tab, or explicitly granted hosts). Cookies pass to native only after explicit consent that names the destination origins, scope, recipient, and job; they stay in memory only and consent never carries over to later jobs.
  • The desktop app and CLI accept user-supplied headers such as Referer for sites that only serve their own viewer pages, and read local paths and file:// URIs. The resume cache stores tile response bytes only, never headers, cookies, or credentials.

Tainted canvas

Browser apps show tainted tiles but cannot produce clean saves from them (see Ordinary display without readable bytes above). The extension assembles on an origin-clean canvas under its own fetch grant, so its saves are clean. Native apps decode bytes directly and have no canvas taint.

Bulk

Queues run sequential single-job runs in the integration layer over the single-job engine, never in the engine: bulk_supported is true on the website (single-queue: an address submitted while a job runs waits its turn) and native (multi-job queue with progress per job, cancel one or all, and retry of failed jobs) baselines. Each job still saves one output, and a failed entry never stops the rest. The CLI --bulk loop runs one bounded single-job run per list entry (a failed entry never stops the rest; a per-image summary plus totals print at the end and the exit is 1 when any entry fails). Bulk text discovery yields deferred entries that resolve one at a time.

Reporting a problem

One template covers every app. Copy the diagnostics block from the error details in the app (it already redacts secrets) and open an issue at https://github.com/lovasoa/dezoomify/issues with:

  • the page or manifest address, with tokens removed;
  • the exact error message plus error code, phase, transport, resource kind, and blocked reason;
  • the redacted source origin and the capability snapshot from the diagnostics copy;
  • app and protocol versions, browser name and version;
  • what was tried already (retry later, extension, desktop app);
  • a screenshot where it helps.

Never include passwords, cookies, session contents, Authorization headers, signed query values, full URLs with sensitive queries, local path details, or response content. Before reporting, check the troubleshooting guide: a site that limits request rates needs a later retry or a personal connection through the extension or desktop app; a busy site needs a few minutes; a picture that shows but cannot save needs the extension; an approval step when sending a signed-in image to another app is expected. Support is free and done by volunteers; a precise report gets answered faster. Owners triage per Incident response.

Live canary

The deterministic suites never contact public source sites. Public compatibility checks run only through the explicit cargo xtask test live target: cargo xtask test live --dry-run --fixtures validates the target list with no network, while cargo xtask test live --public [--limit <n>] [--site <name>] runs the real CLI against real sites with bounded sequential requests.

.github/workflows/live-compat.yml schedules a weekly canary (--public --limit 2, every Monday plus manual dispatch). The canary is advisory: it never blocks pull requests or releases. A failing target is fixed or removed from crates/xtask/src/live.rs with the reason in the commit message; failures are never tolerated silently and never replace deterministic coverage (see Testing).