Introduction
One document chunking engine for RAG — 36 formats, one Rust core, with byte-identical bindings for Python, JavaScript, and Rust.
chunk-engine turns any document into clean, retrieval-ready chunks in a single call. A Rust core does the parsing and segmentation; thin bindings give you the same API — and the same output — from Python, JavaScript, or Rust, across 36 file formats.
from py_chunks import get_chunks, stream_chunks, get_markdown
# Batch — works for every supported format
chunks = get_chunks("document.pdf")
chunks = get_chunks("notes.md", mode="semantic")
chunks = get_chunks("deck.pptx", mode="sliding_window", window_size=3, overlap=1)
for chunk in chunks:
print(chunk["content"], chunk["content_type"], chunk["metadata"])
# Streaming — lazy iteration; genuinely incremental for pdf and xlsx
for chunk in stream_chunks("large.pdf", mode="section"):
handle(chunk)
# Markdown conversion
md = get_markdown("report.docx")What a chunk looks like
Every chunk has exactly three fields: content, a typed content_type, and a
metadata object. Here is a complete one — no elisions — from notes.md in
semantic mode at default parameters:
chunk = get_chunks("notes.md", mode="semantic")[3]
# Every chunk is a dict with exactly three keys:
{
"content": "A naive character splitter cuts mid-sentence and mid-table. The retrieved\npassage then answers half a question, and the model fills in the rest. Keeping\na table whole costs nothing at index time and saves a wrong answer at query\ntime.",
"content_type": "semantic",
"metadata": {
"avg_block_length": 234,
"block_types": ["paragraph"],
"chunk_index": 3,
"document_metadata": {"source_type": "md", "total_input_blocks": 7},
"has_list": False,
"heading_path": ["Chunking Notes", "Why structure matters"],
"keyword_density": 0.6,
"merge_reasons": [],
"paragraph_count": 1,
"primary_merge_reason": "initial",
"section_heading": "Why structure matters",
"section_level": 2,
},
}content goes to your embedding model; content_type tells you what kind of
block it was; metadata carries the provenance you need to filter, rank and
cite. The full catalogue is in Output Schema and
Metadata Reference.
One engine, three languages
pip install py-chunks| Package | Import name | Runtime |
|---|---|---|
| py-chunks (PyPI) | py_chunks | Python 3.9+, via PyO3 |
| js-chunks (npm) | js-chunks | Node · Bun · Deno · browsers, via WASM |
| rs-chunks (crates.io) | chunks_rs | Rust — the reference engine |
Byte-identical output
The SDKs wrap the same engine and are parity-checked to emit exactly the same chunks: 3,222 / 3,222 comparisons byte-identical (100%) across every fixture × every mode, re-verified 2026-08-08. The one known divergence is a scanned PDF that WASM cannot rasterise. See Languages & parity for the numbers, the caveats, and the commands that reproduce them.
Why chunk-engine
- Rust-backed speed. Parsing and chunking run in a compiled core, not a stack of interpreted dependencies.
- One API, every format. The same entry points work for Word, PowerPoint, Excel, PDF, HTML, Markdown, email, eBooks, notebooks, and more.
- Structure-aware chunking. Seven document modes and dedicated spreadsheet modes keep headings, tables, and lists intact.
- Streaming built in. Consume chunks one at a time instead of waiting for a
whole document. Genuinely incremental — bounded memory — for PDF, CSV and
spreadsheets in Rust (spreadsheets only in
rowandsliding_windowmodes), and for PDF and spreadsheets in Python; lazy delivery over a completed parse everywhere else. In JavaScript it is always lazy delivery over a completed parse, never bounded-memory. The honest matrix says which is which, per format and per SDK.
Start here
Installation
Install for Python, JavaScript, or Rust.
Quick Start
Chunk your first document in a few lines.
Playground
Chunk a document in the browser — no install.
Supported formats
All 36 extensions and what each one produces.
Languages & parity
Choose an SDK, and how the three stay identical.
Benchmarks
Extraction coverage vs Docling and Unstructured.
API Reference
Signatures for all three languages.