chunk-engine

Introduction

One document chunking engine for RAG — 36 formats, one Rust core, with byte-identical bindings for Python, JavaScript, and Rust.

View raw

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
PackageImport nameRuntime
py-chunks (PyPI)py_chunksPython 3.9+, via PyO3
js-chunks (npm)js-chunksNode · Bun · Deno · browsers, via WASM
rs-chunks (crates.io)chunks_rsRust — 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 row and sliding_window modes), 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

On this page