# Show HN: Panini – a zero-dependency parser for chaotic Indian bank narrations

> Source: <https://github.com/peopleofproduct/Panini>
> Published: 2026-10-17 09:14:13+00:00

**The First Grammatical Open-Finance Orchestration Core for India's Digital Public Infrastructure (DPI).**

Named after Acharya Pāṇini — the ancient architect of formal rule-based grammar — **Panini** is a zero-runtime-dependency TypeScript engine built to parse, structure, and normalize chaotic financial data ecosystems. It is a **fully free and open-source** local sandbox for processing **ReBIT v2.0 Account Aggregator payload schemas** and **OCEN 4.0 lending networks**, shipped with framework-neutral ops extensions for teams self-hosting at scale.

Just as Pāṇini's Aṣṭādhyāyī reduced a language to deterministic rules ~2500 years ago, Panini treats bank narrations as a grammar — not an AI problem. Fully free under Apache-2.0, forever.

The platform isolates the parsing core from the optional ops layer (rate limiting, metering, telemetry) to guarantee absolute privacy data sandboxing — everything is free and runs in memory on your host.

```
                 ┌────────────────────────────────────────────────┐
                 │              Client / Host Server              │
                 │                                                │
   narrations ──►│  @panini/rules-engine ──► @panini/core          │
   AA payloads ─►│     (JSON grammars)         (Normalizer)        │
                 │            │                                    │
                 │            ▼                                    │
                 │     NormalizedTransaction / AAProfile          │
                 │            │                                    │
                 │            ▼                                    │
                 │  @panini/standards-schema  (ReBIT / OCEN)      │
                 └───────────┬────────────────────────────────────┘
                             │  (optional ops layer)
                 ┌───────────▼────────────────────────────────────┐
                 │  EnterpriseProxy + HTTP adapter                 │
                 │  rate-limit • usage meter • opt-in telemetry    │
                 │  (PII-free by construction — no raw narrations) │
                 └────────────────────────────────────────────────┘
```

| Package | Role | 
|---|---|
| `@panini/core` | Deterministic tokenizer + grammar-driven normalizer; optional ops layer (rate limiting, metering, HTTP adapter). | 
| `@panini/rules-engine` | Community-extendable JSON grammars for Indian banks (SBI, HDFC, ICICI, generic) + archetype rule set. | 
| `@panini/standards-schema` | Zero-dependency validators for ReBIT v2.0 AA profiles and OCEN 4.0 loan applications. | 
| `@panini/simulator` | Generative sandbox producing seeded, anomaly-injected ReBIT payloads for client-side testing. | 

- **Zero runtime dependencies.** The parsing core is pure TypeScript — deterministic regex grammars and tokenizers only. No network calls, no ML models, no phone-home telemetry. Safe to embed inside on-prem or sandboxed environments.
- **Rules are data, not code.** Bank-specific grammars live in standalone JSON files loaded at runtime; updating a bank's narration layout never requires touching the TypeScript engine.
- **Strictly typed.** Strict TypeScript throughout — no`any` ,`unknown` at external boundaries,`exactOptionalPropertyTypes` enabled.
- **PII isolation.** The optional telemetry channel is opt-in only and its event type has*structurally no field* for raw narrations, counterparties, references, VPAs, or amounts.

```
npm install
npm run build   # tsc -b (project references)
npm test        # jest — 158 tests across 15 suites
js
import { parseBankNarration } from '@panini/rules-engine';

parseBankNarration('NEFT-N3452618902-SALARY-OCTOBER 2026-TCS LTD');
// {
//   channel: 'NEFT',
//   type: 'CREDIT',
//   ref_no: 'N3452618902',
//   counterparty: 'TCS Ltd',
//   is_salary: true,
//   category: 'Income',
//   ...
// }
```

Or use the raw engine for custom grammars:

``` js
import { Normalizer } from '@panini/core';
import { loadBuiltinRuleSets, loadCategories } from '@panini/rules-engine';

const normalizer = new Normalizer({
  ruleSets: loadBuiltinRuleSets(),
  categories: loadCategories(),
});
normalizer.normalize('UPI-SWIGGY-826384@okaxis-20261015-REV-DEBIT');
js
import { validateAAProfile, isOCENLoanApplication } from '@panini/standards-schema';

const result = validateAAProfile(payload); // { valid, errors[] } — zero deps
npm run simulate -- --count=50 --seed=7 --anomaly-rate=0.2
npm run simulate -- --count=50 -o mocks.json --pretty
```

Streams deterministic ReBIT v2.0 FI profiles — including deliberate anomalies (truncated narrations, corrupt timestamps, dropped fields) for exercising client-side error handling.

``` js
import { createPaniniHttpHandler } from '@panini/core';

app.post('/v1/parse', createPaniniHttpHandler(proxy));
// bearer token → rate-limit bucket → normalize → usage meter → JSON
npm run build          # strict project-reference build
npm test               # full monorepo suite
npm run lint           # eslint flat config
npm run format         # prettier
```

A `pre-commit` gate (`scripts/pre-commit.sh`, installed at `.git/hooks/pre-commit`) runs lint + tests before any commit finalizes.

**Project Panini** is an open-source initiative by **[People of Product™](https://theproduct.city)** — the team behind **[Product City](https://theproduct.city)**, built to empower professionals with leading tech capabilities and to make India's open-finance infrastructure more open for everyone.

Find us:

- 🌐 Website — [theproduct.city](https://theproduct.city)
- 💼 LinkedIn — [People of Product](https://www.linkedin.com/company/people-of-product) ·[Kapil (founder)](https://www.linkedin.com/in/kapil0/)
- 🐦 X — [@PeopleOfProduct](https://x.com/PeopleOfProduct) ·[@product_city](https://x.com/product_city) ·[@Krazzy_Bunny](https://x.com/Krazzy_Bunny)

Contributions welcome — see [CONTRIBUTING.md](https://github.com/peopleofproduct/Panini/blob/main/CONTRIBUTING.md).
