// NACHA - ACH toolkit

Move money
files. Without
counting bytes.

Generate, parse and validate NACHA ACH files in a few lines. Fully typed. Zero dependencies. Returns and NOC handled for you - in JavaScript and Python.

$ npm i achkit $ pip install achkit
// How it works

Moving money is a 94-character minefield. We walk it for you.

The whole story, no finance degree required.

// In plain English

What is this, really?

It writes the file your bank demands

To pay staff or charge customers, you send your bank an ACH file - an ancient, rigid text format where one wrong space or one stray penny makes the bank reject everyone's payment. achkit writes that file perfectly, so you just say "pay Jane $100" and it handles the rest.

NACHA doesn't give you software

NACHA makes the rules banks follow - like the DMV writes road laws but doesn't hand you a car. They publish a giant PDF rulebook and leave the code to you. Before achkit your only options were to build it from scratch or hand a payment giant a cut of every transaction, forever. achkit is the free third option.

Why pay if the library is free?

The free library is a perfect offline spell-checker for the file - but it's blind to the real world. A typo'd routing number looks fine to it, and the payment bounces days later. Pro and Ultra check the Federal Reserve's live database to confirm the bank is real and open before money moves, and alert you when a payment bounces.

// Why ACH exists

Every time you pay by credit card, Visa and Mastercard take a cut. That toll is unavoidable and expensive - so the old, slow, bank-to-bank ACH rails are the only other way to move money without paying a percentage tax on every dollar. The catch: ACH's rules are ancient and brutal. That's why developers reach for a free tool like achkit - to navigate them without ripping their hair out.

// Where achkit fits

The Goldilocks option

You refuse to hand Stripe a slice of every dollar, and you won't pay Modern Treasury thousands a month. You want to build the banking files yourself and keep 100% of your money - with a modern, free tool so your developers never fumble the math, and a cheap check that the bank accounts they type in are actually real.

// The alternatives

What you're really choosing between

OptionHow it moves moneyWhat it costs youThe catch
Stripe / PayPalPush a button, they pull the money~0.8% per payment (capped ~$5)A cut of every transaction, forever
Modern Treasury / DwollaThey build + send the files for youThousands / mo + per-transactionEnterprise tollbooth pricing
Moov (moov-io/ach)Free library you run yourselfFreeGo only - a separate server to use from Python/JS
Old OSS (node-nacha, pynacha…)Free, aging librariesFreeUnmaintained - breaks when NACHA changes rules
achkitFree JS/Python lib builds the file; API checks the bank is realFree lib + $29-99 / moYou keep ~100% of your money
// What that saves you

Say you send 1,000 ACH payments of $200 a month. Stripe's ~0.8% fee is about $1,600/mo. The same file handed straight to your bank costs pennies each - roughly $30/mo. achkit is free for the library and $29-99 for live bank verification. You keep the difference.

Illustrative - your bank's per-file ACH rate and Stripe's pricing vary. The point stands: owning the file beats renting a percentage.

// The problem

ACH files are a fixed-width minefield

01 / today

Hand-roll it

String padding, manual field offsets, and the NACHA spec open in another tab. Fragile and untested.

02 / or

Rent an API

Full payment platforms hide ACH away - but you pay per transaction and hand them your whole money flow for a file-format problem.

03 / achkit

Import a library

A typed builder, a strict parser, and a validator that catches every reconciliation error before the file leaves your box.

// Three calls

Build it, read it, prove it

The same typed model powers generation, parsing and validation across both languages. No config, no runtime deps.

import { AchFile } from 'achkit'

const file = AchFile.create({ originDfi: '091000019', companyId: '1234567890' })

file.batch({ sec: 'PPD', description: 'PAYROLL', effectiveDate: '2026-07-22' })
    .credit({ name: 'Jane Doe', routing: '011401533', account: '0072', amountCents: 124050 })
    .debit({ name: 'ACME LLC',  routing: '091000019', account: '1899', amountCents: 124050 })

const bytes = file.render()  // balanced batch, hash totals + block padding done
from achkit import parse

ach = parse(open('incoming.ach').read())

for batch in ach['batches']:
    for e in batch['entries']:
        print(e['sec'], e['amount_cents'], e['trace_number'])
# every field typed - no positional string slicing in your code
import { validate } from 'achkit'

const { ok, errors } = validate(bytes)

if (!ok) errors.forEach(e => console.error(e.code, e.field, e.message))
// R01 insufficient funds, entry-hash mismatch, bad routing checksum,
// unbalanced batch, block-count drift - caught before your ODFI sees it
// What's inside

The whole ACH lifecycle, typed

01

Generate & parse

Round-trip any NACHA file. Builder pads and balances; parser hands you typed records with no positional slicing.

02

Returns & NOC

Decode R-codes and C-codes, map returns to the original entry, and generate corrected re-submissions.

03

Every SEC code

PPD, CCD, WEB, TEL, CTX and addenda - validated against the current NACHA rules.

04

Reconciliation-safe

Entry hash, batch and file control totals, and blocking factor computed for you - the errors an ODFI rejects on, caught first.

// Pricing

The library is free. Verify on the API

The library runs on your box, free forever - build, parse and validate ACH files locally. The paid API adds what a local library structurally cannot: live bank-routing verification against the FedACH directory, always-current NACHA rules, and return monitoring.

Library
$0 / forever
  • Generate, parse, validate - MIT
  • All SEC codes + returns/NOC
  • npm and PyPI, byte-identical
Install it
Pro
$29 / mo
  • Live routing verification vs the FedACH directory
  • Always-current NACHA rule validation
  • Hosted API + usage analytics
  • 10,000 validations / mo
Ultra
$99 / mo
  • Everything in Pro, unlimited validations
  • Return-file (R-code) monitoring + webhooks
  • Priority support