TL;DR
Xberg (xberg-io/xberg) is an open-source document extraction engine with a Rust core. You hand it a PDF, an Office file, a scanned image, an email, an audio file, a URL or a source tree, and it returns clean text or Markdown, tables, metadata and, if you ask, chunks and embeddings. It is the renamed and rebuilt Kreuzberg: version 1.0.0 (July 28, 2026) is the direct successor to Kreuzberg v4.9.
Facts as of October 25, 2026:
- 9,445 GitHub stars, 599 forks.
- 11 open issues (issues only, not pull requests).
- License: MIT.
- Latest release: v1.3.10, published October 13, 2026. On PyPI the newest
xbergis still 1.3.9; npm and crates.io have 1.3.10. - Downloads:
xbergon PyPI had 41,939 in the last week (pypistats). The oldkreuzbergpackage still had 49,551 in the same window, so most of the user base has not moved yet.
Not run by us: our hands-on lab (a throwaway GitHub Actions container) could not start today because GitHub refused the job over a billing limit on the account. Everything below comes from the README, the docs, the release notes, the package registries and the project’s own benchmark page. We did not install Xberg or run any of its commands.
Our verdict: Xberg is the most complete open-source extraction library for teams that do not want a Python-only stack: one Rust engine, fifteen language bindings, a CLI, a REST server and an MCP server, all MIT. Its own benchmarks put the default pipeline at the fast, light end of the field with text quality level with Unstructured, and its changelog shows careful, fast work on PDF reading order. The catches are breadth (the feature list is far bigger than any one team can test), a fresh rename that splits docs and downloads between two names, and a quality benchmark that still scores a small set of documents.
What Xberg is
The README calls it a “polyglot document intelligence” engine. In practice it does five jobs that RAG and agent pipelines usually assemble from several libraries:
- Read the file. Format detection and extraction for PDFs, Word, Excel, PowerPoint, OpenDocument, Apple iWork, HTML, email, e-books, images, archives and more. Archives are walked recursively with zip-bomb, compression-ratio and nesting-depth limits.
- OCR when needed. Tesseract by default, plus a native PaddleOCR backend and a pure-Rust Candle stack for vision-language OCR models (TrOCR, GLM-OCR, GOT-OCR, DeepSeek-OCR, PaddleOCR-VL), per the 1.0 release notes.
- Rebuild layout. Optional ML layout detection (PP-DocLayout-V3, RT-DETR) and table structure models (TATR, SLANet) reconstruct reading order and table cells for Markdown output.
- Prepare for retrieval. Chunking (including syntax-aware chunking of code in 371 languages via tree-sitter), local ONNX embeddings or hosted ones, sparse (SPLADE) and late-interaction (ColBERT) retrieval, and cross-encoder reranking.
- Enrich. Named-entity recognition, keyword extraction, summarization, translation, redaction, language detection and schema-driven structured extraction through a local or hosted LLM.
Output comes as plain text, Markdown, Djot, HTML, a JSON tree or Docling DocTags. It runs as a library, a 14-command CLI, a REST API, an MCP server, a Docker image or a Helm chart, on CPU by default.
From Kreuzberg to Xberg
If you search for this tool you will find two names, so the history matters.
Kreuzberg started as a Python library and was rewritten around a Rust core in its v4 line. The team’s public posts compared it directly with Docling: in March 2026 the v4.5.0 announcement on Reddit reported a structure F1 of 42.1% against Docling’s 41.7%, text F1 of 88.9% against 86.7%, and 1,032 ms per document against 2,894 ms. Those are the project’s own figures.
On July 28, 2026 it shipped as xberg 1.0.0. The release notes call it “the direct successor to Kreuzberg v4.9” and list what changed beyond the name:
- pdfium is gone. A pure-Rust backend,
pdf_oxide, is now the only PDF engine. - OCR became a family of classical and vision-language backends instead of one engine.
- New capabilities: Whisper-based audio and video transcription, GLiNER2 entity recognition, structured LLM extraction, sparse and late-interaction retrieval.
- Four new bindings (Dart/Flutter, Swift, Kotlin/Android, Zig) for fifteen in total.
- Removed: the R binding, the EasyOCR backend and the bundled pdfium fork.
Kreuzberg v4 lives on as a long-term-support line at kreuzberg-dev/kreuzberg-lts, so existing installs keep working under the old name.
Migration is mostly renaming: packages go from kreuzberg to xberg in every ecosystem, environment variables take the XBERG_ prefix, and config files are discovered as xberg.toml, .yaml or .json. There are breaking API changes too: extracted URIs became ExtractedUri, and document metadata moved from an untyped additional bag to typed fields plus a custom map. The migration guide has the full identifier mapping.
Installing it
Every ecosystem gets a native package. The common ones:
# Python (3.10+)
pip install xberg
# Node.js / TypeScript
npm install @xberg-io/xberg
# Rust
cargo add xberg
# CLI
brew install xberg-io/tap/xberg
# Docker
docker pull ghcr.io/xberg-io/xberg:latest
The Python README says there are “no optional extras”: the wheel bundles OCR (including PaddleOCR), layout detection, embeddings and chunking for your platform. That is convenient, but check the platforms first. For 1.3.9, PyPI lists six wheels: macOS (Apple Silicon and Intel) and Linux (glibc and musl, x86_64 and ARM). There is no Windows wheel and no source distribution there, so Windows users of the Python package should check before planning on it; the CLI is available on Windows through Scoop.
Using it
The Python quick start from the README is short:
import asyncio
from xberg import ExtractInput, extract
async def main() -> None:
output = await extract(ExtractInput(kind="uri", uri="document.pdf"))
document = output.results[0]
print(document.content)
print(f"Results: {output.summary.results}")
asyncio.run(main())
The API is async, and extract returns an envelope (results, errors, a summary) because one input, such as an archive, can expand into many documents. Each ExtractedDocument carries content, metadata, tables and, if configured, chunks and images.
The default content format is plain text. For RAG you usually want Markdown, which you set on the config; OCR is configured the same way:
from xberg import ExtractInput, ExtractionConfig, OcrConfig, extract
config = ExtractionConfig(
output_format="markdown",
ocr=OcrConfig(backend="tesseract", language="eng"),
)
output = await extract(ExtractInput(kind="uri", uri="scanned.pdf"), config)
for table in output.results[0].tables:
print(table.markdown)
The CLI mirrors this:
xberg extract document.pdf --content-format markdown
xberg extract scanned.pdf --ocr true --ocr-language fra
xberg batch documents/*.pdf --format json
--format sets the wire format of the response (text, JSON or TOON); --content-format sets the format of the extracted text. They are easy to mix up.
As a server and as an MCP tool
xberg serve --host 0.0.0.0 --port 8000 starts a REST server with one POST endpoint for every format, returning JSON or Markdown. xberg mcp --transport stdio starts an MCP server with 9 tools (extract, batch extract, MIME detection, cache controls, format listing and more), 3 prompts and 4 resources. Wiring it into Claude Desktop or Cursor is one entry:
{
"mcpServers": {
"xberg": { "command": "xberg", "args": ["mcp"] }
}
}
The repo also ships a plugin bundle for Claude Code, Codex, Cursor, Gemini CLI and others, and the docs list integrations for LangChain, LlamaIndex, CrewAI, n8n and Open WebUI.
What the project’s benchmarks say
The project publishes an interactive benchmark at xberg.io/benchmarks. For native PDFs in plain-text mode (OCR off, p50 values), the project reports:
| Framework | Throughput | Cold start | Text F1 | Peak memory | Install size |
|---|---|---|---|---|---|
| Xberg | 1.03 MB/s | 64 ms | 0.982 | 39 MB | 80 MB |
| LiteParse | 0.99 MB/s | 76 ms | 0.971 | 17 MB | 35 MB |
| Xberg Layout | 0.02 MB/s | 4.3 s | 0.982 | 379 MB | 279 MB |
| Apache Tika | 0.03 MB/s | 1.6 s | 0.971 | 158 MB | 272 MB |
| Unstructured | 0.01 MB/s | 23.4 s | 0.984 | 1.02 GB | 1.36 GB |
| Docling | 0.00 MB/s | 27.2 s | 0.922 | 1.57 GB | 2.97 GB |
Three things are worth reading out of it:
- The page is honest about where Xberg loses. LiteParse wins latency (31 ms against 32 ms per document), peak memory and install size; Unstructured edges text F1. The install-size note says outright that the comparison is not like-for-like, because Xberg is measured as a binary while Tika and Unstructured carry their system dependencies.
- Fast mode and layout mode are different products. The default path is the fast one. Turning on ML layout detection (“Xberg Layout”) costs about 50 times the throughput and roughly ten times the memory, in exchange for structure that the plain-text view does not score. If you need reading order and tables on complex layouts, budget for the second row, not the first.
- The quality sample is small. In the native-PDF view, each framework’s text F1 is marked “8 scored”. Speed and reliability cover more files, but a fidelity number on eight documents is a hint, not a verdict. Run it on your own documents before you trust it.
What the changelog tells you
Release notes are a better signal than a benchmark for a library you will depend on, and Xberg’s are unusually specific. Version 1.3.10 (October 13) fixed a PDF case where a margin-note column beside a justified main column made lines alternate between the columns, and another where text running across a table’s inner gutter was split between page columns. It also dropped the unmaintained unsafe-libyaml dependency to clear RUSTSEC-2024-0449. Version 1.3.9 added a strict_parse option: by default, a YAML, JSON, TOML or XML file that fails to parse (a Helm template, say) is now returned as plain text with a warning instead of failing the whole extraction.
That is the texture of a team fixing real documents that users send in. The flip side is pace: the repository has published 98 releases (counting benchmark-run tags), four 1.3.x versions in the week of October 9–13 alone, and the main branch already says 1.4.0, with an open issue preparing that release “after security, runtime and artifact gates”. Pin versions.
What people say
Community discussion is mostly under the old name. In a February 2026 r/Python thread on the team’s benchmark against Tika, Docling, Unstructured, PDFPlumber, MinerU and PyMuPDF4LLM, one user wrote that they “ended up using kreuzberg instead because it’s so much faster, easier, and easier to install”. The rename was announced on r/Rag and r/LocalLLaMA; “Xberg” is the common nickname of Berlin’s Kreuzberg district.
Who it is for
- Polyglot teams. If your ingestion runs in Go, Java, C#, Elixir or TypeScript, Xberg is one of very few extraction engines with native bindings rather than a Python sidecar.
- Serverless and edge workloads. A 64 ms cold start and an 80 MB footprint (the project’s figures) matter when workers scale from zero. There is also a WASM build for the browser.
- Self-hosters replacing a paid parser. It covers much of what people pay LlamaParse or Reducto for, locally and under MIT. Our PDF parsing for RAG comparison and Reducto alternatives guide cover the hosted side.
It is a weaker fit if you need the best possible reading of hard scanned layouts without tuning: the default path is the fast text one, and the heavy models are opt-in with a real cost.
Honest limitations
- Breadth beyond what you can verify. Extraction, OCR, layout, transcription, embeddings, reranking, NER, translation, redaction, structured extraction, crawling — across fifteen bindings. The core extraction path dates back to the repository’s start in January 2025; the newer modules arrived with 1.0 in July. Test the parts you need.
- The numbers do not agree with each other. The GitHub description says 106 formats across 140 extensions; the README says 107 across 141; the xberg.io homepage says 101 across 115; the benchmark page mentions 115 supported formats. None of this changes whether your PDF works, but it is a sign that the marketing copy lags the code.
- A split ecosystem. Tutorials, Stack Overflow answers and Reddit threads mostly say Kreuzberg, and the 1.0 API changed in places. Expect to translate older examples.
- Python packaging gaps. On October 25, PyPI was one patch behind (1.3.9 against 1.3.10), with no Windows wheel or source distribution.
- A company behind it. xberg.io now offers a managed platform through an invitation-only design-partner program. The libraries are MIT and self-hostable, but watch which features land in the open core and which in the hosted service.
FAQ
Is Xberg the same as Kreuzberg?
Yes. Xberg 1.0.0, released July 28, 2026, is the direct successor to Kreuzberg v4.9, with the same Rust core under a new name. Kreuzberg v4 continues as a long-term-support line at kreuzberg-dev/kreuzberg-lts, so existing installs keep working.
Is Xberg free for commercial use?
Yes. The libraries, CLI, REST server and MCP server are MIT-licensed, which allows commercial use, modification and redistribution with the copyright notice kept. A separate managed platform exists through an invitation-only design-partner program.
Does Xberg need a GPU?
No. The README says it runs on CPU by default. The optional layout and table models and the vision-language OCR backends are heavier; the project’s own benchmark shows the layout pipeline using about 379 MB of memory per document against 39 MB for the default path.
How does Xberg compare with Docling and Unstructured?
On the project’s native-PDF benchmark, Xberg’s default path reports 1.03 MB/s throughput and a 64 ms cold start, against 27.2 s for Docling and 23.4 s for Unstructured, with text F1 of 0.982 against 0.922 and 0.984. Those are the project’s numbers on a small scored sample; test on your own documents.
Can I use Xberg with Claude Code or Cursor?
Yes. Run xberg mcp as an MCP server (9 tools, including extract and batch extract) or install the plugin bundle from the repository, which targets Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI and others.
How do I migrate from Kreuzberg to Xberg?
Rename the package (kreuzberg to xberg), switch environment variables to the XBERG_ prefix and rename config files to xberg.*. Then update code that used Uri (now ExtractedUri) or the untyped additional metadata bag (now typed fields plus custom). The R binding and EasyOCR backend were removed.
Verdict
Xberg is a serious, actively maintained engine and the strongest open-source option if you want one extraction library across many languages, with a CLI, REST and MCP on top. Start with the fast path and Markdown output, turn on layout detection only for documents that need it, pin your version, and measure quality on your own files rather than on the eight-document sample. Teams already on Kreuzberg v4 can stay on the LTS line until the 1.4.0 release settles.
Sources
- xberg-io/xberg on GitHub — README, stars, issues, license
- Xberg v1.0.0 release notes (Kreuzberg successor, migration)
- Xberg v1.3.10 release notes
- Xberg v1.3.9 release notes (strict_parse)
- Xberg Python package README
- Xberg documentation
- CLI usage guide
- MCP integration guide
- Migration guide from Kreuzberg v4
- Xberg benchmarks
- xberg on PyPI
- Kreuzberg LTS repository
- r/rust: Kreuzberg v4.5.0 announcement with Docling comparison
- r/Python: Benchmarks of Kreuzberg, Tika, Docling, Unstructured, PDFPlumber, MinerU and PyMuPDF4LLM
- r/Rag: Kreuzberg is being renamed