The Problem
Enterprises that need to ingest heterogeneous documents (PDFs, Office files, scanned images, source code) must stitch together a patchwork of parsers, OCR engines, and language‑specific extractors. Maintaining that stack is costly, slows onboarding, and introduces inconsistent output formats.
What This Does
Kreuzberg is a polyglot document‑intelligence framework built around a Rust core that normalises extraction across >97 file types and 305 programming languages.
The core lives in crates/kreuzberg-cli/src/main.rs (CLI) and crates/kreuzberg-ffi/src/lib.rs (C‑FFI). Language bindings are generated from the FFI layer and shipped in dedicated crates (kreuzberg-node, kreuzberg-paddle-ocr, etc.). Extraction results are modelled by ExtractionResult structs that include text, metadata, and a codeintelligence field populated via Tree‑sitter parsers (crates/kreuzberg-cli/src/commands/extract.rs). Plugins (OCR back‑ends, post‑processors) are defined under .ai-rulez/domains/plugin-system/, with contracts enforced in crates/kreuzberg-ffi/src/config/.rs.
How To Use It
Setup
Build the Rust core (requires a recent Rust toolchain) cargo build --release # builds all crates, including CLI and FFI
Install the Node binding (requires the compiled .node module) cd crates/kreuzberg-node npm install # reads package.json npm run build # runs cargo build --release via the npm script
Docker users can pull the pre‑built image defined in charts/kreuzberg/templates/deployment.yaml:
docker pull ghcr.io/kreuzberg-dev/kreuzberg:latest docker run --rm -p 8000:8000 ghcr.io/kreuzberg-dev/kreuzberg
Configuration
Runtime configuration is loaded from the hierarchy described in .ai-rulez/config.yaml and crates/kreuzberg-cli/src/commands/config.rs. Typical keys include:
.ai-rulez/config.yaml extraction: maxfilesizemb: 100 ocr: backend: "tesseract" # or "paddle" language: "eng"
The CLI respects KREUZBERGCONFIG environment variable to point at an alternate file.
Running
CLI:
Extract a PDF and emit JSON
cargo run -p kreuzberg-cli -- extract --input sample.pdf --output result.json
Server (REST API):
cargo run -p kreuzberg-cli -- server --bind 0.0.0.0:8080 POST /extract with multipart file in the body
Node:
import { extract } from '@kreuzberg/node'; const result = await extract('sample.docx'); console.log(result.text);
Real‑World Use
A data‑pipeline for contract analysis can invoke the REST server from a Kubernetes pod (see charts/kreuzberg/values.yaml). The pod streams incoming PDFs to POST /extract, receives ExtractionResult with structured code symbols for embedded contract clauses, and forwards the JSON to an indexing service such as ElasticSearch.
apiVersion: v1 kind: Pod metadata: name: contract-ingestor spec: containers: name: ingestor image: my/ingestor:latest env: name: KREUZBERGENDPOINT value: http://kreuzberg:8080
Code Health & Issues
Low – Comprehensive test suite – 13 unit tests (crates/kreuzberg-cli/tests/.rs) and CI workflows (.github/workflows/ci-rust.yaml) run on each PR. Medium – Native dependency complexity – PDFium (crates/kreuzberg-pdfium-render/) and Paddle‑OCR require external binaries; build failures on CI are mitigated by cached actions but may surface on custom platforms. Low – Limited documentation for non‑Rust bindings – README lists all language bindings, but the docs/ directory only contains Rust‑centric guides; users of Go, PHP, or R may need to infer usage from the FFI crate. Low – No explicit secret scanning – No .env or secret files are present, but the repository does not include a secret‑scan step in CI; adding github/codeql or detect-secrets would improve hygiene.
Overall the repository follows standard Rust conventions, includes a lockfile, CI linting, and a Helm chart for production deployment.
The Bottom Line
Kreuzberg delivers a single, high‑performance extraction engine with a well‑defined plugin model and language bindings for the major ecosystems. It is ready for enterprise integration where uniform document processing and code‑intelligence are required, but teams should budget for native‑dependency setup and may need to supplement documentation for non‑Rust languages.