Skip to content

OCR (tesseract.js) still loads its worker, core WASM, and language data from public CDNs #4

Description

@stupleb

Found while scanning the built v2.8.8 bundle for any remaining CDN URL (PR #3). Everything else — the three WASM libraries and, as of v2.8.8, the text editor's fallback fonts — is bundled locally and rewritten at startup. OCR is the one remaining external fetch. It has been this way since the first release (2.8.4:1), so it is not a v2.8.8 regression; README.md / instructions.md now state the exception.

What actually happens (verified against the v2.8.8 -simple image)

It is a two-layer fetch:

  1. The main bundle (assets/tesseract-runtime-*.js) carries only tesseract.js's built-in default workerPath: https://cdn.jsdelivr.net/npm/tesseract.js@v${n}/dist/worker.min.js. BentoPDF's override layer (VITE_TESSERACT_{WORKER,CORE,LANG}_URL) is build-time only and unset in the prebuilt image, and no local worker.min.js ships — so the worker is fetched from jsdelivr.
  2. The core WASM and language-data defaults are not in the main bundle at all (zero tesseract.js-core / tessdata literals there). They live inside the worker script, which fetches tesseract.js-core from jsdelivr and <lang>.traineddata from tessdata.projectnaptha.com on its own.

The OCR language picker offers 30+ languages.

Fix — same pattern as the WASM libraries and fonts, with two rewrite points

  • Vendor worker.min.js and the tesseract.js-core WASM variants, pinned to the exact tesseract.js version the bundle uses, under /usr/share/nginx/html/tesseract/.
  • Rewrite workerPath in the main bundle via the rewrite-wasm-urls oneshot (content-matched, like the fonts).
  • Patch the corePath / langPath defaults inside our vendored worker at Docker build time (a sed on a file we ship — no oneshot needed for that layer).
  • Add the tesseract.js / core versions to the bump checklist in AGENTS.md / CONTRIBUTING.md.

The open decision: which languages to bundle

Each language needs its own traineddata (eng ≈ a few MB; CJK languages tens of MB each). Bundling all 30+ is roughly 150–400 MB — versus 23 MB for the fonts — and a much larger .s9pk. Options: bundle a curated subset (e.g. eng plus the major European and CJK languages) and either let the rest fall back to the CDN (partial, documented) or hide them from the picker.

Verification

The oneshot proves no CDN literals remain; only a real OCR run with the browser network tab proves the worker loads core + language data locally.

Target: 2.8.8:1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions