Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Tesseract.js User Guide

Generated June 2026 from naptha/tesseract.js at a1ca80d

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Tesseract.js is a pure JavaScript optical character recognition (OCR) library that extracts text from images in almost any language. It runs in the browser and in Node.js with no native binaries to install — recognition is performed by a WebAssembly port of the Tesseract OCR engine that the library downloads and manages for you.

This guide is for developers who want to use Tesseract.js in an application: reading text from images, controlling the recognition output, running jobs in parallel, and troubleshooting common problems. For architecture, build internals, and deployment concerns, see the Admin Guide.

Note

This guide documents Tesseract.js v7.0.0. The npm package is tesseract.js. The library is licensed under Apache-2.0.


Table of Contents

  1. Quick Start
  2. Installation
  3. Core Concepts
  4. Everyday Usage
  5. Choosing Output Formats
  6. Working With Languages
  7. Running Jobs in Parallel With Schedulers
  8. Common Tasks (Recipes)
  9. Performance Best Practices
  10. How It Works
  11. Troubleshooting
  12. FAQ
  13. API Reference

Quick Start

Recognize English text from an image URL in three lines of real work:

Browser (ESM / bundler)

import { createWorker } from 'tesseract.js';

(async () => {
  const worker = await createWorker('eng');
  const ret = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');
  console.log(ret.data.text);
  await worker.terminate();
})();

Browser (script tag / CDN)

<script src="https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js"></script>
<script>
  (async () => {
    const worker = await Tesseract.createWorker('eng');
    const ret = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');
    console.log(ret.data.text);
    await worker.terminate();
  })();
</script>

Node.js

const { createWorker } = require('tesseract.js');

(async () => {
  const worker = await createWorker('eng');
  const { data: { text } } = await worker.recognize('./image.png');
  console.log(text);
  await worker.terminate();
})();

Expected output (for the sample image):

Mild Splendour of the various-vesfed Night!
...

Tip

When recognizing multiple images, create the worker once, call worker.recognize for each image, and call worker.terminate() once at the end. Do not create and destroy a worker per image — see Performance Best Practices.


Installation

Tesseract.js works three ways: a <script> tag (local copy or CDN), a bundler such as webpack via npm, and Node.js via npm or yarn.

CDN (browser, no build step)

<!-- v5 -->
<script src='https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.min.js'></script>

After the script loads, a global Tesseract variable is available and you can create a worker with Tesseract.createWorker.

An ESM build (for import syntax) is available at:

https://cdn.jsdelivr.net/npm/tesseract.js@5/dist/tesseract.esm.min.js

npm / yarn (bundlers and Node.js)

# Latest version
npm install tesseract.js
# or
yarn add tesseract.js
# A specific (older) version
npm install tesseract.js@3.0.3
# or
yarn add tesseract.js@3.0.3

Expected output:

added 1 package, and audited N packages in Xs

Important

Tesseract.js v7 requires Node.js v16 or newer. (Tesseract.js v6 requires Node.js v14 or newer.) Installing on an unsupported Node version can fail outright — see Troubleshooting.

Requirements at a glance

Requirement Detail
Node.js (v7) v16 or newer
Browser Any browser that supports JavaScript and WebAssembly
Network (default) Outbound HTTPS to the jsDelivr CDN for the WASM core and language data
Disk / storage Space to cache .traineddata files (browser: IndexedDB; Node.js: filesystem)

Note

Tesseract.js downloads its WebAssembly core and language data at runtime from a CDN by default. If your environment cannot reach the CDN, host these files yourself and set corePath and langPath — see Self-hosting the core and language data.


Core Concepts

Understanding four terms makes the rest of the API obvious.

Worker : An object that owns one instance of the Tesseract engine, running in a web worker (browser) or a worker thread (Node.js). You send OCR jobs through the worker. Created with createWorker.

Scheduler : A manager that holds a pool of workers and a job queue, dispatching jobs to idle workers so they run in parallel. Created with createScheduler. Use it when you have many images to process. See Workers vs. Schedulers.

OEM (OCR Engine Mode) : Selects which recognition model runs. Tesseract.js defaults to LSTM only (the modern neural model). See OEM.

PSM (Page Segmentation Mode) : Tells the engine how the text is laid out on the page (a single line, a single block, sparse text, etc.). See PSM.

Note

Tesseract.js is a wrapper. It brings the Tesseract engine to JavaScript but does not change how recognition works. The recognition model and most engine parameters come from the upstream Tesseract project. This guide documents the JavaScript API and the options Tesseract.js adds; for deep recognition-tuning questions, the upstream Tesseract documentation is authoritative.


Everyday Usage

Create a worker

const worker = await createWorker('eng');

createWorker(langs, oem, options, config) — all arguments are optional:

Argument Default Meaning
langs 'eng' Language code, +-joined string ('eng+chi_sim'), or array (['eng', 'chi_sim'])
oem 1 (OEM.LSTM_ONLY) OCR engine mode
options {} Worker options (paths, caching, logger, etc.) — see WorkerOptions
config {} "Init-only" Tesseract parameters set before initialization

Important

createWorker is asynchronous — always await it. The returned worker is already loaded and initialized with the requested language and OEM; you do not need to call load, loadLanguage, or initialize (those were removed in v5).

Recognize an image

const { data: { text } } = await worker.recognize(image);
console.log(text);

worker.recognize(image, options, output, jobId) returns a promise to an object with jobId and data properties. The data object contains every output format you requested (by default, just text).

Tip

Recognition quality scales with image resolution. The same image often gives much better results if you upscale it before calling recognize.

Note

worker.recognize returns a result object even when no text is found (the outputs are simply empty). An empty page is treated as a valid result, not an error, so no exception is thrown.

Track progress with a logger

Pass a logger function in the worker options to receive progress updates:

const worker = await createWorker('eng', 1, {
  logger: (m) => console.log(m), // e.g. { status: 'recognizing text', progress: 0.5, ... }
});

A logger message looks like:

{ workerId: 'Worker-0-abc12', jobId: 'Job-0-de34f', status: 'recognizing text', progress: 0.5 }

Always terminate

await worker.terminate();

Terminating frees the worker's memory and underlying thread. For a single one-off recognition you can terminate immediately; when reusing a worker, terminate only after all jobs are done.


Choosing Output Formats

By default, worker.recognize returns only plain text. To get other formats, pass an output object as the third argument with the formats you want set to true.

const { data } = await worker.recognize(image, {}, {
  text: true,
  hocr: true,
  tsv: true,
  blocks: true,
});
console.log(data.hocr); // hOCR (HTML) string

Warning

As of v6, every output format other than text is disabled by default. If you previously relied on hocr, blocks, etc. being present, you must now explicitly enable them: worker.recognize(image, {}, { hocr: true }).

Available output formats

Output key Type returned Description
text string Plain UTF-8 recognized text (default true)
blocks object Structured JSON tree of blocks → paragraphs → lines → words → symbols
layoutBlocks object Layout-only blocks (does not require full recognition)
hocr string hOCR — HTML representation with bounding boxes
tsv string Tab-separated values with positional data
box string Box file (character coordinates)
unlv string UNLV format
osd string Orientation & script detection text
pdf number[] Searchable PDF as a byte array
imageColor string Pre-processed color image (base64 data URL)
imageGrey string Pre-processed greyscale image
imageBinary string Pre-processed binary (black/white) image
debug string Internal debug output

The full recognition result (data) also always includes confidence, psm, oem, and version.

Tip

imageColor, imageGrey, imageBinary, layoutBlocks, and debug do not require running full text recognition. If you request only these, Tesseract.js skips the OCR step, which is faster. See Recipe: extract pre-processed images.

Caution

Tesseract.js can produce searchable PDFs via the pdf output, but it cannot read PDF files as input. See Are PDF files supported?.


Working With Languages

Specify one or more languages when you create the worker. Language data (.traineddata) is downloaded automatically the first time it is needed and then cached.

// Single language
const worker = await createWorker('eng');

// Multiple languages, '+'-joined
const worker = await createWorker('eng+chi_tra');

// Multiple languages as an array
const worker = await createWorker(['eng', 'chi_tra']);

Note

The languages constant exports symbolic names for every supported language code (for example Tesseract.languages.ENG === 'eng', Tesseract.languages.CHI_SIM === 'chi_sim'). You can pass either the code string directly or the constant.

Supported languages

Tesseract.js supports the full set of Tesseract language codes — roughly 90 languages including English (eng), Chinese Simplified (chi_sim) and Traditional (chi_tra), Japanese (jpn), Korean (kor), Arabic (ara), Hindi (hin), Russian (rus), German (deu), French (fra), Spanish (spa), and many more. The osd "language" is used for orientation/script detection only.

For the complete, current list of codes see the upstream Tesseract data files documentation.

Tip

When you need the Latin-script default, 'eng' is the right choice. Combining many heavy languages (for example Chinese with the Legacy model) downloads large data files — see Do Not Disable Language Data Caching.


Running Jobs in Parallel With Schedulers

There are two ways to run recognition: a single worker (simple), or a scheduler that spreads jobs across multiple workers (parallel, much faster for bulk work).

When to use which

Situation Use
One image, or images processed one after another A single reused worker
Many images that can be processed at once A scheduler with a pool of workers

Caution

Do not create a new worker for every image when processing in parallel. Each worker uses a large amount of memory, so spawning an unbounded number of workers can crash your application. Use a scheduler with a fixed pool instead.

Scheduler example

const { createWorker, createScheduler } = require('tesseract.js');

const scheduler = createScheduler();

const workerGen = async () => {
  const worker = await createWorker('eng');
  scheduler.addWorker(worker);
};

const workerN = 4; // pool of 4 workers
(async () => {
  await Promise.all(Array(workerN).fill(0).map(() => workerGen()));

  // Run 10 recognition jobs across the 4 workers
  const results = await Promise.all(
    Array(10).fill(0).map(() => (
      scheduler.addJob('recognize', 'https://tesseract.projectnaptha.com/img/eng_bw.png')
        .then((x) => x.data.text)
    )),
  );

  console.log(results);
  await scheduler.terminate(); // terminates all workers too
})();

Important

All workers added to the same scheduler should be homogeneous — same language and same parameters. The scheduler assigns jobs to workers non-deterministically, so mismatched workers would produce results that depend on which worker happened to take the job.

scheduler.addJob(action, ...payload) accepts 'recognize' or 'detect' as the action, followed by the same arguments you would pass to worker.recognize / worker.detect.


Common Tasks (Recipes)

Recipe: recognize only digits (character whitelist)

const worker = await createWorker('eng');
await worker.setParameters({
  tessedit_char_whitelist: '0123456789',
});
const { data: { text } } = await worker.recognize(image);
await worker.terminate();

Tip

A character whitelist dramatically improves accuracy when you know the content is constrained (invoice totals, license plates, serial numbers).

Recipe: choose a page segmentation mode

const { createWorker, PSM } = require('tesseract.js');

const worker = await createWorker('eng');
await worker.setParameters({
  tessedit_pageseg_mode: PSM.SINGLE_BLOCK,
});
const { data: { text } } = await worker.recognize(image);

Recipe: recognize only part of an image (rectangle)

const worker = await createWorker('eng');
const rectangle = { left: 0, top: 0, width: 500, height: 250 };
const { data: { text } } = await worker.recognize(image, { rectangle });

To read several regions, call recognize once per rectangle (optionally via a scheduler to do them in parallel):

const rectangles = [
  { left: 0,   top: 0, width: 500, height: 250 },
  { left: 500, top: 0, width: 500, height: 250 },
];
const values = [];
for (let i = 0; i < rectangles.length; i += 1) {
  const { data: { text } } = await worker.recognize(image, { rectangle: rectangles[i] });
  values.push(text);
}

Recipe: auto-rotate skewed scans

const { data: { text, rotateRadians } } = await worker.recognize(
  image,
  { rotateAuto: true },
);
console.log('Rotated by (radians):', rotateRadians);

Note

With rotateAuto: true, Tesseract.js detects the skew angle and re-runs recognition on the corrected image. Very small angles (under ~0.3°) are ignored to save runtime. You can also set a fixed angle with rotateRadians.

Recipe: generate a searchable PDF (Node.js)

const fs = require('fs');
const { createWorker } = require('tesseract.js');

(async () => {
  const worker = await createWorker();
  const { data: { pdf } } = await worker.recognize(
    'image.png',
    { pdfTitle: 'Example PDF' },
    { pdf: true },
  );
  fs.writeFileSync('tesseract-ocr-result.pdf', Buffer.from(pdf));
  await worker.terminate();
})();

Use pdfTextOnly: true in the options to produce a PDF containing only the text layer (no background image).

Recipe: extract pre-processed images

const { data: { imageColor, imageGrey, imageBinary } } = await worker.recognize(
  image,
  { rotateAuto: true },
  { imageColor: true, imageGrey: true, imageBinary: true },
);

Each is returned as a base64 data-URL string. In Node.js, convert and save:

const convertImage = (src) => new Uint8Array(
  atob(src.split(',')[1]).split('').map((c) => c.charCodeAt(0)),
);
fs.writeFileSync('imageBinary.png', convertImage(imageBinary));

Recipe: detect orientation and script (OSD)

const worker = await createWorker('eng', 1, { legacyCore: true, legacyLang: true });
const { data } = await worker.detect(image);
console.log(data);
// { tesseract_script_id, script, script_confidence, orientation_degrees, orientation_confidence }

Warning

worker.detect requires the Tesseract Legacy model, which is not loaded by default. You must set both legacyCore: true and legacyLang: true in createWorker options, or detect will throw `worker.detect` requires Legacy model, which was not loaded.

Recipe: self-host the core and language data

const worker = await createWorker('eng', 1, {
  workerPath: 'https://your-host/tesseract.js@v5.0.0/dist/worker.min.js',
  langPath:   'https://your-host/tessdata/4.0.0',
  corePath:   'https://your-host/tesseract.js-core@v5.0.0',
});

Important

When you set corePath, point it at a directory that contains all four core files (tesseract-core.wasm.js, tesseract-core-simd.wasm.js, tesseract-core-lstm.wasm.js, tesseract-core-simd-lstm.wasm.js). Tesseract.js picks the right one for the user's device. Setting corePath to a single .js file is strongly discouraged — it degrades performance or breaks on some devices.

Recipe: switch language/model on an existing worker

// Worker created with the legacy code/data available:
const worker = await createWorker('eng', 1, { legacyCore: true, legacyLang: true });
await worker.reinitialize('eng', 0); // switch to Tesseract Legacy (oem 0)

Note

Switching from LSTM (oem 1) to Legacy (oem 0) with reinitialize only works if the worker was created with legacyCore: true and legacyLang: true. Otherwise the required code/data is missing and reinitialize throws Legacy model requested but code missing.


Performance Best Practices

Tip

Always benchmark your own images. Some tips below are universal; others (changing language data or model) trade quality for speed.

  • [ ] Reuse workers. Never create/load/destroy a worker per image. Reuse one worker for sequential jobs, or a scheduler pool for parallel jobs.
  • [ ] Set up workers ahead of time. Create the worker before the user picks an image (for example on page load, or when the user signals intent to use OCR), so the first recognition isn't slowed by setup.
  • [ ] Do not disable language-data caching. Leave cacheMethod at its default (write). Caching bugs that prompted some users to disable it were fixed in v4.0.6.
  • [ ] Use the latest version. Old versions are much slower — v2 takes ~10× longer on some images than current.
  • [ ] Never set corePath to a single .js file. Point it at a directory so the best build can be selected.
  • [ ] Consider "fast" language data for speed-sensitive work by setting langPath to https://tessdata.projectnaptha.com/4.0.0_fast (benchmark quality impact first).

Note

To experience first-time-user setup cost during development (no cache), set cacheMethod: 'none'. Remove this before publishing your app — it forces a re-download of language data on every run.

Important

In long-running Node.js servers, periodically recreate workers/schedulers (for example every 500 jobs). WebAssembly memory only grows over time, and workers accumulate words into an internal dictionary that can become bloated with typos across thousands of unrelated documents.


How It Works

You can use Tesseract.js productively without this section, but it explains the moving parts behind the API.

   Your code
      │  createWorker('eng')
      ▼
 ┌─────────────────────────┐        spawns        ┌──────────────────────────────┐
 │  Worker (main thread)    │ ───────────────────▶ │  Worker script               │
 │  src/createWorker.js     │   postMessage(...)   │  (web worker / worker_thread)│
 │  - recognize/detect/...  │ ◀─────────────────── │  src/worker-script/index.js  │
 └─────────────────────────┘   progress/result    │   ├─ loads TesseractCore WASM │
                                                   │   ├─ downloads .traineddata   │
                                                   │   └─ runs OCR                 │
                                                   └──────────────────────────────┘
  1. You call createWorker. The main-thread API (src/createWorker.js) spawns a separate execution context — a Worker in the browser or a worker_threads Worker in Node.js — so recognition never blocks your UI or event loop.
  2. The worker script loads the engine. src/worker-script/index.js asks an environment-specific adapter (browser or node) to load the right TesseractCore WebAssembly build. The build is chosen by detecting SIMD / relaxed-SIMD support and whether the Legacy model is needed.
  3. Language data is fetched and cached. On loadLanguage, the worker checks the cache (browser: IndexedDB via idb-keyval; Node.js: the filesystem). If the .traineddata is missing, it downloads .traineddata.gz from the CDN, gunzips it, writes it into the WebAssembly in-memory filesystem (MEMFS), and stores it in the cache for next time.
  4. Recognition runs. worker.recognize loads the image into the engine, optionally auto-rotates it, runs Recognize, and dumps the requested output formats into a JSON result that is posted back to the main thread.
  5. You terminate. worker.terminate tears down the worker and frees memory.

Note

Communication between your code and the worker is entirely message-based (postMessage). Every method on a worker — recognize, detect, setParameters, etc. — is a job sent into the worker and a promise resolved when the worker replies.


Troubleshooting

Follow the format: error → cause → solution.

Error: Cannot find module

Cause: The main Tesseract.js thread cannot locate the worker code. This commonly happens inside frameworks whose build systems move files in ways that violate Tesseract.js's assumptions about file locations.

Solution: Set workerPath explicitly to point at the local worker script.

const worker = await createWorker('eng', 1, {
  workerPath: './node_modules/tesseract.js/src/worker-script/node/index.js', // Node.js
  // or, in the browser, the path to worker.min.js
});

Prevention: Confirm the official examples run first; if they do but your framework build does not, a workerPath override is almost always the fix.

Error: Error attempting to read image.

Cause: The supplied image is not a supported format and data type combination, or the data is corrupt. Tesseract.js supports the image formats bmp, jpg, png, pbm, webp, and non-animated gif — but the data must also be a supported type (see Supported image inputs). For example, a buffer of raw pixel data (not an encoded image) is not supported.

Solution: Ensure you are passing an encoded image in a supported format and a supported data type. Re-encode raw pixels to PNG/JPEG first.

Prevention: Validate the source before recognition; for canvases use toBlob/convertToBlob rather than raw pixel arrays.

Error: initialization failed

Cause: Initialization of the Tesseract API failed — most often because the cached .traineddata does not support the requested model (for example, requesting the Legacy model with LSTM-only data).

Solution: Tesseract.js automatically deletes the suspect cache entry and retries. If it still fails, ensure the OEM you request matches the data you load — request the Legacy model only with legacyCore: true and legacyLang: true, or simply use the default LSTM model.

Prevention: Don't mix Legacy oem values (0/2) with LSTM-only data.

Error: worker.detect requires Legacy model, which was not loaded.

Cause: worker.detect (OSD) needs the Tesseract Legacy model, which is not loaded by default.

Solution: Create the worker with legacyCore: true and legacyLang: true.

Prevention: Reserve detect for workers explicitly configured with the Legacy model.

Error: Legacy model requested but code missing.

Cause: You called reinitialize requesting a Legacy oem (0 or 2) on a worker created without the Legacy core.

Solution: Create the worker with legacyCore: true (and legacyLang: true) before switching to a Legacy oem.

Error: Network error while fetching <url>. Response code: <status>

Cause: Downloading language data from langPath/the CDN failed (offline, blocked, wrong path, or 404).

Solution: Verify network access to the CDN. If self-hosting, confirm langPath points at a directory and the <lang>.traineddata(.gz) file exists there. Remember: do not include a trailing / on langPath.

Prevention: For air-gapped or restricted environments, self-host the data — see Recipe: self-host the core and language data.

Warning: Invalid resolution 0 dpi. Using 70 instead.

Cause: The image has no DPI metadata.

Solution: Set a DPI explicitly:

await worker.setParameters({ user_defined_dpi: '300' });

New installations (npm install) broken on Node.js v14

Cause: Tesseract.js v7 requires Node.js v16+; v6 requires v14+. Installing a version newer than your Node supports can break the install.

Solution: Upgrade Node.js, or pin Tesseract.js to a version compatible with your Node (for example use v6 on Node 14).

Poor accuracy on angled or rotated text

Cause: Skewed text reduces recognition quality.

Solution: Enable rotateAuto: true (see Recipe: auto-rotate skewed scans) and ensure the image is high resolution. Recognition of severely rotated or distorted text remains a known limitation of the underlying engine.


FAQ

Q: What is the scope of this project? Tesseract.js is the JavaScript/WebAssembly port of the Tesseract OCR engine. It does not modify the underlying recognition engine. Bugs in recognition behavior originate upstream; if you can reproduce a recognition bug in the main CLI Tesseract, report it there.

Q: Which JavaScript frameworks are supported? All frameworks that support JavaScript and WebAssembly. The one common framework known not to work is React Native, because it does not support WebAssembly.

<a name="q-are-pdf-files-supported"></a> Q: Are PDF files supported? No — Tesseract.js cannot take a PDF as input. To OCR a PDF you must render its pages to images first (with a library such as PDF.js or muPDF) and recognize those images. Alternatively, Scribe.js builds on Tesseract.js and adds native PDF support. (Note: Tesseract.js can produce searchable PDFs as output — see Recipe: generate a searchable PDF.)

Q: Is handwritten text supported? No. The Tesseract model assumes printed text. No combination of options meaningfully improves handwriting recognition unless the handwriting closely resembles print.

Q: Why do I get different results than the Tesseract CLI? Usually because of different defaults. Tesseract.js defaults to oem 1 (LSTM only) while the CLI defaults to 2 (LSTM + Legacy fallback); Tesseract.js defaults to psm 6 (single block) while the CLI defaults to 3 (auto). Set oem and psm explicitly in both, confirm identical language data and Tesseract version, and results should match.

Q: What configuration settings should I use? The defaults are optimal for most users. The recognition engine and its many parameters come from upstream Tesseract, so questions like "what settings work best for license plates" are usually answered in the main Tesseract documentation, not here.

Q: How does Tesseract.js download and keep *.traineddata? On first use it checks the cache (browser IndexedDB; Node.js filesystem). If the file is missing it fetches *.traineddata.gz from the CDN, gunzips it, and stores it. Delete the cached file to force a re-download.

Q: How can I train my own *.traineddata? Follow the upstream Tesseract training documentation. Custom traineddata can then be loaded via langPath.

Q: Can I run OCR completely offline? Yes — self-host the WASM core (corePath), worker script (workerPath), and language data (langPath). See Recipe: self-host the core and language data.

Q: Does Tesseract.js work in Web Workers / Cloudflare Workers / browser extensions? It runs in standard browsers and Node.js. Some constrained or non-standard runtimes (certain serverless worker platforms, some browser-extension manifest configurations) may need extra path configuration or may be unsupported; check the project's issue tracker for the current status of your specific runtime.


API Reference

Top-level exports

The package exports: createWorker, createScheduler, recognize, detect, setLogging, OEM, PSM, languages, plus the Tesseract namespace types.

Export Kind Purpose
createWorker(langs?, oem?, options?, config?) function Create and initialize a worker (async)
createScheduler() function Create a scheduler that pools workers
recognize(image, langs?, options?) function ⚠️ Deprecated — one-shot recognize (creates + destroys a worker each call)
detect(image, options?) function ⚠️ Deprecated — one-shot detect
setLogging(logging) function Globally enable/disable verbose logging
OEM enum OCR Engine Mode constants
PSM enum Page Segmentation Mode constants
languages object Map of symbolic names → language codes

Warning

The top-level recognize() and detect() functions are deprecated. They create, load, and destroy a worker on every call, which is slow. Use worker.recognize / worker.detect instead.

Worker methods

Method Returns Purpose
recognize(image, options?, output?, jobId?) Promise<RecognizeResult> Run OCR on an image
detect(image, jobId?) Promise<DetectResult> Orientation & script detection (needs Legacy model)
setParameters(params, jobId?) Promise<ConfigResult> Set Tesseract parameters at runtime
reinitialize(langs?, oem?, config?, jobId?) Promise<ConfigResult> Re-initialize with different language/model
writeText(path, text, jobId?) Promise<ConfigResult> Write a text file into the worker's in-memory FS
readText(path, jobId?) Promise<ConfigResult> Read a file from the in-memory FS
removeFile(path, jobId?) Promise<ConfigResult> Delete a file from the in-memory FS
FS(method, args, jobId?) Promise<ConfigResult> Call any Emscripten FS method
terminate(jobId?) Promise<ConfigResult> Terminate the worker and free memory

Note

The optional jobId argument lets you label a job so you can correlate it in logger callbacks. If omitted, an id is generated automatically.

Note

worker.setParameters cannot change the oem — that is fixed at initialization. To change the model on an existing worker, use reinitialize. Parameters flagged "init only" in Tesseract docs likewise cannot be set via setParameters or recognize; pass them through the config argument of createWorker/reinitialize.

Scheduler methods

Method Returns Purpose
addWorker(worker) string Add a worker to the pool; returns the worker id
addJob(action, ...payload) Promise Queue a 'recognize' or 'detect' job
getQueueLen() number Current job-queue length
getNumWorkers() number Number of workers in the pool
terminate() Promise Terminate all workers and clear the queue

Important

scheduler.addJob throws You need to have at least one worker before adding jobs if the pool is empty. Add workers before queueing jobs.

recognize options (second argument)

Option Type Description
rectangle { left, top, width, height } Restrict recognition to a region
rotateAuto boolean Auto-detect and correct skew before recognizing
rotateRadians number Apply a fixed rotation (radians)
pdfTitle string Title embedded in pdf output
pdfTextOnly boolean Produce a text-only PDF (no background image)

Any other key in this object that is not a Tesseract.js option (and does not start with tessjs_) is passed through to the Tesseract engine as a parameter for that single recognition call.

WorkerOptions

Passed as the third argument to createWorker.

Option Type Default Description
corePath string jsDelivr CDN Directory containing the four tesseract.js-core WASM builds
langPath string jsDelivr CDN Directory for .traineddata downloads (no trailing /)
workerPath string jsDelivr CDN Location of the worker script
dataPath string . Path inside the WASM FS for traineddata (rarely changed)
cachePath string . Cache location (Node.js folder; browser IndexedDB key prefix)
cacheMethod string write Caching behavior — see below
legacyCore boolean false Ensure downloaded code supports the Legacy model
legacyLang boolean false Ensure downloaded language data supports the Legacy model
workerBlobURL boolean true Use a Blob URL for the worker script (browser)
gzip boolean true Whether remote traineddata is gzipped
logger function () => {} Progress callback, e.g. m => console.log(m)
errorHandler function — Worker error callback, e.g. err => console.error(err)

cacheMethod values:

Value Reads cache? Writes cache?
write (default) Yes Yes
readOnly Yes No
refresh No Yes
none No No

PSM

Page Segmentation Mode (import { PSM } from 'tesseract.js'). Tesseract.js defaults to SINGLE_BLOCK.

Constant Value Meaning
OSD_ONLY '0' Orientation and script detection only
AUTO_OSD '1' Automatic page segmentation with OSD
AUTO_ONLY '2' Automatic, no OSD or OCR
AUTO '3' Fully automatic, no OSD (CLI default)
SINGLE_COLUMN '4' A single column of variable-size text
SINGLE_BLOCK_VERT_TEXT '5' A single uniform block of vertical text
SINGLE_BLOCK '6' A single uniform block of text (Tesseract.js default)
SINGLE_LINE '7' A single text line
SINGLE_WORD '8' A single word
CIRCLE_WORD '9' A single word in a circle
SINGLE_CHAR '10' A single character
SPARSE_TEXT '11' Sparse text — find as much text as possible, no order
SPARSE_TEXT_OSD '12' Sparse text with OSD
RAW_LINE '13' Raw line — treat as a single line, bypassing hacks

OEM

OCR Engine Mode (import { OEM } from 'tesseract.js'). Tesseract.js defaults to LSTM_ONLY.

Constant Value Meaning
TESSERACT_ONLY 0 Legacy engine only
LSTM_ONLY 1 Neural (LSTM) engine only — default
TESSERACT_LSTM_COMBINED 2 Legacy + LSTM combined
DEFAULT 3 Whatever is available

Frequently used Tesseract parameters

Set via worker.setParameters({...}) or per call in recognize options.

Parameter Type Default Description
tessedit_pageseg_mode enum (PSM) PSM.SINGLE_BLOCK Page segmentation mode
tessedit_char_whitelist string '' Restrict recognition to these characters
tessedit_char_blacklist string '' Forbid these characters
preserve_interword_spaces string '0' '1' keeps spaces between words
user_defined_dpi string '' Set DPI to fix the "Invalid resolution 0 dpi" warning

This is not exhaustive — because Tesseract.js passes parameters straight to the engine, any parameter supported by the underlying Tesseract version works here too (except "init only" parameters, which must go through config).

Supported image inputs

Image formats: bmp, jpg, png, pbm, webp, gif (non-animated).

Data type Browser Node.js
base64 data-URL string ✅ ✅
Buffer / array buffer ✅ ✅
File / Blob ✅ —
img / canvas / video element, OffscreenCanvas ✅ —
local file path string — ✅
remote URL string ✅ ✅

Caution

The image must be both a supported format and a supported data type. A buffer containing a PNG is supported; a buffer of raw pixel data is not.