af·fer·ent (adj. /ˈæf.ər.ənt/) — Carrying sensory signals inward toward the central nervous system.
afferent is a sensory layout engine for 2D documents. It reconstructs columns, horizontal baselines, line-item pairs, and reading order from raw OCR bounding boxes before downstream models or business logic touch them.
Deterministic 2D geometry handles 90%+ of layout recovery at sub-millisecond speeds. For ambiguous page breaks, afferent integrates with System 1 models like Jev to evaluate semantic continuations through micro-judgments.
- Zero dependencies — pure TypeScript, no native bindings.
- Coordinate agnostic — works with normalized (
0..1) or pixel coordinates. - Domain presets — built-in configurations for price lists, spec sheets, and inventory manifests.
- System 1 native — implements
noul,choice, andscoreprimitives.
npm install afferentimport { processPageLayout, type OcrLine } from "afferent";
const lines: OcrLine[] = [
{ id: 1, text: "Platform License (Annual)", x: 0.08, y: 0.22, width: 0.45, height: 0.02 },
{ id: 2, text: "$12,000", x: 0.82, y: 0.221, width: 0.1, height: 0.02 },
{
id: 3,
text: "Includes unlimited seats and priority support.",
x: 0.08,
y: 0.245,
width: 0.55,
height: 0.02,
},
];
const page = await processPageLayout(lines);
console.log(page.itemBlocks);
// [
// {
// id: 'item_1',
// title: 'Platform License (Annual)',
// description: 'Includes unlimited seats and priority support.',
// value: 12000,
// box: { x: 0.08, y: 0.22, width: 0.84, height: 0.045 },
// lines: [...]
// }
// ]OCR engines return an unordered bag of bounding boxes: [x, y, width, height, text]. Reading them in naive stream order scrambles columns, detaches prices from titles, and cuts descriptions in half at page boundaries.
afferent recovers the layout in four passes:
- Split columns. Horizontal projection histograms detect gutters to separate multi-column text from spanning headers and banners. Text from column A never bleeds into column B.
- Lock baselines. Titles pair with right-aligned values (prices, SKUs, dates) that share the same horizontal baseline, regardless of whitespace width.
- Stitch blocks. Wrapped titles, narrative paragraphs, and sub-bullets merge into unified item blocks with exact mathematical bounding boxes.
- Bridge page breaks. Items split across pages are detected using dangling punctuation, lowercase starts, and layout continuity. Ambiguous boundaries query a System 1 model (such as Jev) to confirm semantic continuation.
For guides, presets, and full API documentation, visit afferent.dev:
- Getting Started
- How It Works
- Domain Presets
- Cross-Page Continuations
- System 1 & Jev Integration
- API Reference
MIT © Cody Bromley