
Xberg Document Extraction
FreeEfficiently extract data from 101 document formats.
Free · Opens the source repo
What Xberg Document Extraction does
Xberg is a robust document intelligence library designed for developers who need to extract text, tables, images, and metadata from a wide range of document formats. With support for 101 formats, including PDFs, Office documents, images, and HTML, Xberg provides a high-performance solution for document processing tasks. The library is built on a Rust core, ensuring efficiency and speed, and offers native bindings for Python, Node.js/TypeScript, and Rust, making it accessible for various development environments.
This skill is particularly useful for developers who are working on applications that require document data extraction. Whether you need to perform OCR on scanned images, batch process multiple files, or configure extraction options such as output format and chunking, Xberg has you covered. It simplifies the integration of document extraction capabilities into your applications, allowing you to focus on building features rather than dealing with the complexities of document parsing.
Xberg also supports custom plugin implementations, enabling developers to extend its functionality further. This includes post-processors, validators, and different OCR backends, which can be tailored to meet specific project requirements. The library's comprehensive documentation and examples make it easy to get started, whether you're using it in Python, Node.js, or Rust.
In summary, Xberg is an essential tool for developers looking to integrate powerful document extraction capabilities into their applications. Its extensive format support and flexibility make it suitable for a variety of use cases, from simple text extraction to complex data processing workflows.
When to use it
Use Xberg when you need to extract data from documents in multiple formats, especially when dealing with batch processing or OCR tasks.
When not to use it
If your project requires extraction from only a limited set of formats or if you do not need the advanced features like OCR or batch processing, simpler tools may suffice.
What you can build with it
Extracting Metadata from PDFs
Use Xberg to extract metadata from PDF files for indexing or cataloging purposes.
Batch Processing Office Documents
Process multiple Office documents simultaneously to extract text and tables for data analysis.
Performing OCR on Scanned Images
Utilize Xberg's OCR capabilities to convert scanned documents into editable text.
How to install Xberg Document Extraction
View source1. Install with the skills CLI
npx skills add xberg-io/xberg/xberg --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by xberg-ioXberg Document Extraction
Xberg is a high-performance document intelligence library with a Rust core and native bindings for Python, Node.js/TypeScript, Ruby, Go, Java, C#, PHP, and Elixir. It extracts text, tables, metadata, and images from 101 file formats across 115 file extensions including PDF, Office documents, images (with OCR), HTML, email, archives, and academic formats.
Use this skill when writing code that:
- Extracts text or metadata from documents
- Performs OCR on scanned documents or images
- Batch-processes multiple files
- Configures extraction options (output format, chunking, OCR, language detection)
- Implements custom plugins (post-processors, validators, OCR backends)
If the
xbergMCP server is registered in this session, prefer its tools over shelling out to the CLI — they expose the same extraction surface with structured arguments and results.
Installation
Python
pip install xberg
Node.js
npm install @xberg-io/xberg
Rust
cargo add xberg
# Cargo.toml
[dependencies]
xberg = { version = "1.0.2", features = ["full"] }
tokio = { version = "1", features = ["full"] }
# feature flags: pdf, ocr, chunking, embeddings, language-detection, keywords, api, mcp
# (or "formats" / "full" aggregates); tokio-runtime is on by default
CLI
brew install xberg-io/tap/xberg
# or run without a persistent install (the CLI proxy package self-installs the binary):
npx @xberg-io/xberg-cli --help
uvx --from xberg-cli xberg --help
# or download a prebuilt binary from the latest GitHub release:
# https://github.com/xberg-io/xberg/releases/latest
# or build from source:
cargo install xberg-cli
Quick Start
The library entry points are extract(input, config) and extract_batch(inputs, config). Both return an ExtractionResult envelope — the extracted document(s) live in result.results, and per-document data (content, tables, metadata, …) is on each result.results[i]. Python and Node are async-only.
Python
import asyncio
from xberg import ExtractInput, extract, ExtractionConfig
async def main() -> None:
result = await extract(ExtractInput(uri="document.pdf"), ExtractionConfig())
doc = result.results[0]
print(doc.content) # extracted text
print(doc.metadata) # document metadata
print(doc.tables) # extracted tables
asyncio.run(main())
Node.js
import { extract } from "@xberg-io/xberg";
const output = await extract({ kind: "uri", uri: "document.pdf" });
const doc = output.results[0];
console.log(doc.content);
console.log(doc.metadata);
console.log(doc.tables);
Rust
use xberg::{extract, ExtractInput, ExtractionConfig};
#[tokio::main]
async fn main() -> xberg::Result<()> {
let output = extract(ExtractInput::from_uri("document.pdf"), &ExtractionConfig::default()).await?;
println!("{}", output.results[0].content);
Ok(())
}
CLI
xberg extract document.pdf
xberg extract document.pdf --format json
xberg extract document.pdf --content-format markdown
Configuration
All languages use the same configuration structure with language-appropriate naming conventions.
Python (snake_case)
from xberg import (
ExtractInput, extract,
ExtractionConfig, OcrConfig, TesseractConfig, PdfConfig, ChunkingConfig, OutputFormat,
)
config = ExtractionConfig(
ocr=OcrConfig(
backend="tesseract",
language=["eng"],
tesseract_config=TesseractConfig(psm=6, enable_table_detection=True),
),
pdf_options=PdfConfig(passwords=["secret123"]),
chunking=ChunkingConfig(max_characters=1000, overlap=200),
output_format=OutputFormat("markdown"),
)
result = await extract(ExtractInput(uri="document.pdf"), config)
Node.js (camelCase)
import { extract, type ExtractionConfig } from "@xberg-io/xberg";
const config: ExtractionConfig = {
ocr: { backend: "tesseract", language: ["eng"] },
pdfOptions: { passwords: ["secret123"] },
chunking: { maxCharacters: 1000, overlap: 200 },
outputFormat: "markdown",
};
const output = await extract({ kind: "uri", uri: "document.pdf" }, config);
Rust (snake_case)
use xberg::{extract, ExtractInput, ExtractionConfig, OcrConfig, ChunkingConfig, OutputFormat};
let config = ExtractionConfig {
ocr: Some(OcrConfig {
backend: "tesseract".into(),
language: vec!["eng".to_string()],
..Default::default()
}),
chunking: Some(ChunkingConfig {
max_characters: 1000,
overlap: 200,
..Default::default()
}),
output_format: OutputFormat::Markdown,
..Default::default()
};
let output = extract(ExtractInput::from_uri("document.pdf"), &config).await?;
Config File (TOML)
output_format = "markdown"
[ocr]
backend = "tesseract"
language = "eng"
[chunking]
max_characters = 1000
overlap = 200
[pdf_options]
passwords = ["secret123"]
# CLI: auto-discovers xberg.toml in current/parent directories
xberg extract doc.pdf
# or explicit:
xberg extract doc.pdf --config xberg.toml
xberg extract doc.pdf --config-json '{"ocr":{"backend":"tesseract","language":"deu"}}'
Batch Processing
extract_batch takes a list of ExtractInputs and returns one envelope whose results array holds a document per input (in input order); per-input failures are reported in result.errors.
Python
from xberg import ExtractInput, extract_batch, ExtractionConfig
inputs = [
ExtractInput(uri="doc1.pdf"),
ExtractInput(uri="doc2.docx"),
ExtractInput(uri="doc3.xlsx"),
]
output = await extract_batch(inputs, ExtractionConfig())
for doc in output.results:
print(f"{len(doc.content)} chars extracted")
Node.js
import { extractBatch } from "@xberg-io/xberg";
const output = await extractBatch([
{ kind: "uri", uri: "doc1.pdf" },
{ kind: "uri", uri: "doc2.docx" },
]);
for (const doc of output.results) {
console.log(`${doc.content.length} chars`);
}
Rust
use xberg::{extract_batch, ExtractInput, ExtractionConfig};
let config = ExtractionConfig::default();
let inputs = vec![ExtractInput::from_uri("doc1.pdf"), ExtractInput::from_uri("doc2.docx")];
let output = extract_batch(inputs, &config).await?;
CLI
xberg batch *.pdf --format json
xberg batch docs/*.docx --content-format markdown
OCR
OCR runs automatically for images and scanned PDFs. Tesseract is the default backend (native binding, no external install required).
Backends
Select with OcrConfig.backend:
- tesseract (default): built-in native binding. All Tesseract languages supported.
- paddleocr (
"paddleocr"/"paddle-ocr"): ONNX-based PaddleOCR. - vlm: Vision-Language-Model OCR (configure via
OcrConfig.vlm_config).
Custom backends can be registered in Python/Node via register_ocr_backend (see Advanced Features).
Language Codes
config = ExtractionConfig(ocr=OcrConfig(language=["eng"])) # English
config = ExtractionConfig(ocr=OcrConfig(language=["eng", "deu"])) # Multiple
# The single-string shorthand ("eng+deu") is only accepted in config files / --config-json,
# not in the OcrConfig constructor (Python takes a list, Node takes an array).
Force OCR
config = ExtractionConfig(force_ocr=True) # OCR even if text is extractable
Result Envelope and Document Fields
extract / extract_batch return an ExtractionResult envelope: results (list of documents), errors (per-input failures), and summary (counts). Per-document fields live on each document in results — bind doc = result.results[0] (Python/Node) or &output.results[0] (Rust) first.
| Field | Python (doc.) | Node.js (doc.) | Rust (document.) | Description |
|---|---|---|---|---|
| Text content | content | content | content | Extracted text (str/String) |
| MIME type | mime_type | mimeType | mime_type | Input document MIME type |
| Metadata | metadata | metadata | metadata | Document metadata (flat mapping) |
| Tables | tables | tables | tables | Extracted tables with cells + markdown |
| Languages | detected_languages | detectedLanguages | detected_languages | Detected languages (if enabled) |
| Chunks | chunks | chunks | chunks | Text chunks (if chunking enabled) |
| Images | images | images | images | Extracted images (if enabled) |
| Elements | elements | elements | elements | Semantic elements (if element_based format) |
| Pages | pages | pages | pages | Per-page content (if page extraction enabled) |
| Keywords | extracted_keywords | extractedKeywords | extracted_keywords | Extracted keywords (if enabled) |
Error Handling
Python
extract / extract_batch raise a plain RuntimeError on failure — the typed XbergError subclasses are not raised by these entry points, so catch RuntimeError. Per-input failures during extract_batch are reported non-fatally in result.errors.
from xberg import ExtractInput, extract, ExtractionConfig
try:
result = await extract(ExtractInput(uri="file.pdf"), ExtractionConfig())
for err in result.errors:
print(f"Per-input error: {err}")
except RuntimeError as e:
print(f"Extraction failed: {e}")
Node.js
The Node binding throws plain Error objects (it does not export typed error subclasses). Catch with instanceof Error, and inspect output.errors for non-fatal per-input failures.
import { extract } from "@xberg-io/xberg";
try {
const output = await extract({ kind: "uri", uri: "file.pdf" });
if (output.errors.length > 0) {
console.error("Per-input errors:", output.errors);
}
} catch (e) {
if (e instanceof Error) {
console.error(`Extraction failed: ${e.message}`);
}
}
Rust
use xberg::{extract, ExtractInput, ExtractionConfig, XbergError};
let config = ExtractionConfig::default();
match extract(ExtractInput::from_uri("file.pdf"), &config).await {
Ok(output) => println!("{}", output.results[0].content),
Err(XbergError::Parsing { message, .. }) => eprintln!("Parse error: {message}"),
Err(XbergError::Ocr { message, .. }) => eprintln!("OCR error: {message}"),
Err(XbergError::UnsupportedFormat(mime)) => eprintln!("Unsupported: {mime}"),
Err(e) => eprintln!("Error: {e}"),
}
Common Pitfalls
- Result is an envelope:
extract/extract_batchreturnExtractionResultwithresults,errors, andsummary. Per-document fields (content,tables,chunks, …) are onresult.results[i], NOT on the top-level return. - Async-only: Python and Node have no sync variants — always
await extract(...). Rustextractis async; use#[tokio::main]or an async context. - Build the input: pass an
ExtractInput, not a bare path. UseExtractInput(uri=...)/ExtractInput::from_uri(...)(Python/Rust) or{ kind: "uri", uri: "..." }(Node); for bytes usekind="bytes"withbytes/mime_type. - Python ChunkingConfig fields: construct with
max_charactersandoverlap(defaults 1000 / 200); these are also the readable attributes. When passing config as a dict/JSON, themax_chars/max_overlapaliases are also accepted. Node usesmaxCharacters/overlap; Rust struct fields aremax_characters/overlap. - Python errors:
extract/extract_batchraise a plainRuntimeErroron failure, not typedXbergErrorsubclasses — catchRuntimeError. Node throws plainError(no typed error subclasses). - Rust extract signature:
extract(input, &config)— the config is a reference. Use&ExtractionConfig::default()for defaults. - CLI --format vs --content-format:
--formatcontrols CLI output (text/json).--content-formatcontrols content format (plain/markdown/djot/html). - Config file field names: Use snake_case in TOML/YAML/JSON config files —
[chunking]fields aremax_charactersandoverlap; other fields use names likeoutput_format,pdf_options.
Supported Formats (Summary)
| Category | Extensions |
|---|---|
.pdf | |
| Word | .docx, .odt |
| Spreadsheets | .xlsx, .xlsm, .xlsb, .xls, .xla, .xlam, .xltm, .ods |
| Presentations | .pptx, .ppt, .ppsx |
| eBooks | .epub, .fb2 |
| Images | .png, .jpg, .jpeg, .gif, .webp, .bmp, .tiff, .tif, .jp2, .jpx, .jpm, .mj2, .jbig2, .jb2, .pnm, .pbm, .pgm, .ppm, .svg |
| Markup | .html, .htm, .xhtml, .xml |
| Data | .json, .yaml, .yml, .toml, .csv, .tsv |
| Text | .txt, .md, .markdown, .djot, .rst, .org, .rtf |
.eml, .msg | |
| Archives | .zip, .tar, .tgz, .gz, .7z |
| Academic | .bib, .biblatex, .ris, .nbib, .enw, .csl, .tex, .latex, .typ, .jats, .ipynb, .docbook, .opml, .pod, .mdoc, .troff |
See references/supported-formats.md for the complete format reference with MIME types.
Additional Resources
Detailed reference files for specific topics:
- Python API Reference — All functions, config classes, plugin protocols, exact signatures
- Node.js API Reference — All functions, TypeScript interfaces, worker pool APIs
- Rust API Reference — All functions with feature gates, structs, Cargo.toml examples
- CLI Reference — All commands, flags, config precedence, exit codes
- Configuration Reference — TOML/YAML/JSON formats, auto-discovery, env vars, full schema
- Supported Formats — All 101 formats (115 file extensions) with file extensions and MIME types
- Advanced Features — Plugins, embeddings, MCP server, API server, security limits
- Other Language Bindings — Go, Ruby, Java, C#, PHP, Elixir, WASM, Docker
Related skills
Task-focused sibling skills go deeper than this overview:
- extracting-with-ocr — OCR backends, language packs, force-OCR, tuning.
- extracting-tables — layout-aware table detection and table models.
- chunking — chunk size/overlap, markdown/yaml/semantic chunkers, the
chunkcommand. - extracting-keywords — YAKE/RAKE keywords, language detection, the
embedcommand. - batch-extraction — the
batchcommand,--file-configs, parallelism, error recovery. - picking-a-format — choosing
--format/--content-formatper consumer.
Full documentation: https://docs.xberg.io GitHub: https://github.com/xberg-io/xberg
Frequently asked questions about Xberg Document Extraction
Similar skills
WinMD API Search
Easily find and explore Windows desktop APIs.
WebMCPify
Transform any web app into an agent-ready platform.
Phoenix Tracing
Instrument LLM applications with OpenInference tracing.
Foundry Hosted Agent CopilotKit
Guidance for developing agentic web apps on Azure.
Power Automate Foundation
Connect AI agents to Power Automate seamlessly.
Power Automate Flow Builder
Efficiently build and deploy Power Automate flows programmatically.
