# Obsidian Text Extractor is a shared OCR engine other plugins can borrow

> Obsidian Text Extractor is a companion plugin that pulls text out of images, PDFs and Office documents inside an Obsidian vault, and its real purpose is to be a dependency: it exposes a small API so other plugins, most obviously Omnisearch, can call OCR without each of them bundling and running their own. The project is now explicitly unmaintained.

**scambier/obsidian-text-extractor** — A (companion) plugin to facilitate the extraction of text from images (OCR) and PDFs.

- Repository: https://github.com/scambier/obsidian-text-extractor
- Stars: 650 · Forks: 50
- Language: TypeScript
- License: GPL-3.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/scambier-obsidian-text-extractor

## It is a companion plugin, and that framing is the design

Text Extractor is described as a companion plugin, and the README is explicit that it is mainly useful when used in conjunction with other plugins, such as Omnisearch, while also being usable on its own to quickly extract texts from images and PDFs.

The reason section explains the design in two sentences. Text extraction is a useful feature, but it is not easy to implement, and it consumes a lot of resources. The author's stated hope is to provide a unified way to extract texts from images and PDFs and make it available to other plugins, so that other plugins can use it without having to worry about the implementation details, and without needlessly consuming resources.

That is the whole point of the project. It is not trying to be the best note-taking search plugin. It is trying to be the piece that runs OCR once, on demand, and hands the result to whoever asks.

The supported file list is short and covers the formats you would expect. Images are `.png`, `.jpg`, `.jpeg`, `.webp`, `.gif` and `.bmp`. PDFs are `.pdf`. And office documents are `.docx` and `.xlsx`.

There is a context menu screenshot in the README, so the standalone use is a right-click action on a file, with the extracted text going into the clipboard or a note depending on the version.

The project is TypeScript, GPL-3.0 licensed, with the last push on 2026-09-07 and releases 0.7.0 from 2025-12-26, 0.6.1 from 2025-07-24 and 0.6.0 from 2025-05-11.

## The limitations section is unusually blunt

The README has a limitations section that reads like a list of known problems, and it is more useful to a potential user than a feature list would be.

The plugin uses Tesseract.js and pdf-extract to extract text from images and PDFs, and the documentation says plainly that those libraries are not perfect and may not work on some files.

Then two items marked in red. PDF files often fail to get their text extracted, with issue 7 and discussion 21 linked. And text extraction does not work on mobile, with a pointer to the section that explains it.

The second one has a specific cause that explains the whole caching design. Text Extractor needs an Internet connection to work, because all the processing is done locally but the language files needed by the underlying OCR library, Tesseract, are downloaded on demand.

So the failure on mobile is not a mobile-specific bug. It is the consequence of a design where the heavy lifting is local but the model files are fetched. On a phone that means either no extraction at all or a slow first run, and neither is acceptable for a search index, so the plugin does not attempt it.

The PDF problem is the one to be most careful with, because the failure mode is silent. If a PDF's text cannot be extracted, the plugin returns an empty result rather than an error, and anything downstream, such as a search index, simply does not contain that document's content. A document you cannot search is easy to miss, especially if you assume the search worked.

The honest summary is that this works well on images and not reliably on PDFs, and a user who knows that can plan around it.

## The cache is what makes mobile and sync work

The cache and sync section is short and it is the mechanism that solves the mobile limitation without pretending it does not exist.

The plugin caches the extracted texts as local small `.json` files inside the plugin directory. Those files can be synced between your devices. Since text extraction does not work on mobile, the plugin uses the synced cached texts if available, and if not, an empty string is returned.

That is a workable design and the reasoning behind it is a nice piece of engineering judgement. The cache is not an optimisation feature, it is the only way the plugin can offer any value on a phone, and the choice to write the cache as plain JSON files inside the plugin directory is what makes it syncable with whatever sync mechanism the vault already uses.

The alternative, storing the cache in Obsidian's own plugin data directory, would be invisible to a vault sync that excludes plugin configuration. Putting it in the plugin directory means a user who already syncs the `.obsidian` folder gets the cache for free.

The downside is the same decision seen from the other side. The cache is files in your vault, so it takes space and it is committed to whatever you commit, and for a large vault with thousands of images the JSON files accumulate.

The API design reinforces the on-demand model. The plugin only extracts text on demand, when you call `extractText()` on a file, to avoid unnecessary resource consumption, and subsequent calls return the cached text. So a user who never searches an image never pays for OCR on it, which matters when the OCR is the expensive part.

## The API is four functions and a cast

The dependency interface is small enough to paste into your own plugin, and the README gives it verbatim.

```ts
// Add this type somewhere in your code
export type TextExtractorApi = {
  extractText: (file: TFile) => Promise<string>
  canFileBeExtracted: (filePath: string) => boolean
  isInCache: (file: TFile) => Promise<boolean>
}

// Then, you can just use this function to get the API
export function getTextExtractor(): TextExtractorApi | undefined {
  return (app as any).plugins?.plugins?.['text-extractor']?.api
}

// And use it like this
const text = await getTextExtractor()?.extractText(file)
```

Three operations and a lookup. `extractText` does the work and returns the text as a promise. `canFileBeExtracted` takes a path and tells you whether the file is one of the supported types, so you can filter a list before you call it. And `isInCache` tells you whether the text is already available, which is the check that lets a search index skip files it has already handled.

The API is reached through the plugin registry with a cast to any, which is the usual Obsidian pattern for talking to another plugin, and the function returns undefined if the plugin is not installed, so every call site has to handle that.

There is a stability caveat attached. The author says the API functions likely will not change, but that this is still a beta, and that they are dogfooding the plugin with Omnisearch.

For a plugin author, the practical value is that you can index the text of an image attachment without shipping Tesseract in your own plugin and without running OCR on every file the moment the vault loads.

## The project is unmaintained, and the author says so first

The most important thing in this README is a warning placed above everything else, and it is worth respecting rather than glossing over.

The heading says unmaintained, and the message is that the author unfortunately cannot dedicate any more time to Text Extractor. Pull requests are welcome, and you are free to fork and improve on this project.

That changes how you should read the rest of the documentation. The limitations are not a to-do list with an owner attached, the PDF extraction problem is not going to be fixed upstream, and the mobile gap is a permanent gap rather than a pending bug.

So the realistic options are three. Use the plugin as it is, within its limits, if your vault is mostly images and your desktop usage covers the OCR need. Fork it, if the PDF problem matters to you, since the author has explicitly invited that and the code is small. Or avoid it, if you need a maintained dependency for a plugin you ship.

The alternative for an end user is a different plugin that bundles its own extraction, at the cost of the shared cache and the on-demand behaviour.

The installation options are the standard ones. It is in the Obsidian community plugins repository, so it can be installed from the community plugin browser. You can also install it manually by downloading the latest release, or use the BRAT plugin manager, which is the usual route for prerelease builds.

The repository layout supports the two-part structure the README describes. There is a lib/ directory holding the text extraction library and a plugin/ directory holding the plugin itself, each with its own package.json and node_modules. The library uses Rollup, described as easier to set up with Wasm and web workers, and the plugin uses esbuild. There is also a manifest.json, a versions.json, a version-bump.mjs script and a CHANGELOG.md.

## Conclusion

Adopt Obsidian Text Extractor if you are writing an Obsidian plugin that needs OCR, because it gives you a cached extraction API rather than a Tesseract integration to maintain. Skip it if you are an end user who only wants to search their notes, since the plugin is built for plugin authors and its own text extraction has real limitations on PDFs and on mobile. Verify first which file types you actually need, since PDFs often fail to extract and the plugin supports images, PDFs and Office documents, that your vault is synced if you want the cached text to work on mobile, and that you are comfortable with a project the author has marked unmaintained, since the fix for that is forking rather than waiting.

## FAQ

### What does the Obsidian Text Extractor plugin do and which files does it support?

It extracts text from images, PDFs and Office documents inside an Obsidian vault. Supported images are .png, .jpg, .jpeg, .webp, .gif and .bmp, PDFs are .pdf, and office documents are .docx and .xlsx. The extraction itself uses Tesseract.js for images and pdf-extract for PDFs.

### How do other Obsidian plugins use Text Extractor?

Through a small exposed API. You add the `TextExtractorApi` type with its three functions, `extractText`, `canFileBeExtracted` and `isInCache`, then fetch the plugin API from the plugin registry with a cast, and call `extractText` on a file. Extraction happens on demand, and later calls return the cached text.

### Is Text Extractor still maintained?

No. The README carries an unmaintained warning at the top and the author states they cannot dedicate any more time to it. Pull requests are welcome and you are free to fork and improve on the project, so a fix for the PDF extraction problem would have to come from a fork rather than an upstream release.

## Sources

- [Issues](https://github.com/scambier/obsidian-text-extractor/issues)
- [License: GPL-3.0](https://github.com/scambier/obsidian-text-extractor/blob/master/LICENSE)
- [README](https://github.com/scambier/obsidian-text-extractor/blob/master/README.md)
- [Releases](https://github.com/scambier/obsidian-text-extractor/releases)
- [scambier/obsidian-text-extractor on GitHub](https://github.com/scambier/obsidian-text-extractor)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/scambier-obsidian-text-extractor
