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
- Quick Start
- Installation
- Core Concepts
- Everyday Usage
- Choosing Output Formats
- Working With Languages
- Running Jobs in Parallel With Schedulers
- Common Tasks (Recipes)
- Performance Best Practices
- How It Works
- Troubleshooting
- FAQ
- 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.recognizefor each image, and callworker.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
corePathandlangPath— 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
createWorkeris asynchronous — alwaysawaitit. The returned worker is already loaded and initialized with the requested language and OEM; you do not need to callload,loadLanguage, orinitialize(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.recognizereturns 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
textis disabled by default. If you previously relied onhocr,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, anddebugdo 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
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
languagesconstant exports symbolic names for every supported language code (for exampleTesseract.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 withrotateRadians.
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.detectrequires the Tesseract Legacy model, which is not loaded by default. You must set bothlegacyCore: trueandlegacyLang: trueincreateWorkeroptions, ordetectwill 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. SettingcorePathto a single.jsfile 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 (
oem1) to Legacy (oem0) withreinitializeonly works if the worker was created withlegacyCore: trueandlegacyLang: true. Otherwise the required code/data is missing andreinitializethrowsLegacy 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
cacheMethodat 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
corePathto a single.jsfile. Point it at a directory so the best build can be selected. - [ ] Consider "fast" language data for speed-sensitive work by setting
langPathtohttps://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 │
└──────────────────────────────┘
- You call
createWorker. The main-thread API (src/createWorker.js) spawns a separate execution context — aWorkerin the browser or aworker_threadsWorkerin Node.js — so recognition never blocks your UI or event loop. - The worker script loads the engine.
src/worker-script/index.jsasks an environment-specific adapter (browserornode) to load the rightTesseractCoreWebAssembly build. The build is chosen by detecting SIMD / relaxed-SIMD support and whether the Legacy model is needed. - Language data is fetched and cached. On
loadLanguage, the worker checks the cache (browser: IndexedDB viaidb-keyval; Node.js: the filesystem). If the.traineddatais missing, it downloads.traineddata.gzfrom the CDN, gunzips it, writes it into the WebAssembly in-memory filesystem (MEMFS), and stores it in the cache for next time. - Recognition runs.
worker.recognizeloads the image into the engine, optionally auto-rotates it, runsRecognize, and dumps the requested output formats into a JSON result that is posted back to the main thread. - You terminate.
worker.terminatetears 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()anddetect()functions are deprecated. They create, load, and destroy a worker on every call, which is slow. Useworker.recognize/worker.detectinstead.
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
jobIdargument lets you label a job so you can correlate it in logger callbacks. If omitted, an id is generated automatically.
Note
worker.setParameterscannot change theoem— that is fixed at initialization. To change the model on an existing worker, usereinitialize. Parameters flagged "init only" in Tesseract docs likewise cannot be set viasetParametersorrecognize; pass them through theconfigargument ofcreateWorker/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.addJobthrowsYou need to have at least one worker before adding jobsif 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.