A tiny, correct CSV parser & stringifier in ~1 KB. Zero dependencies. Handles the quoting edge cases naive split-on-comma code gets wrong.
"a,b".split(",") breaks the moment a value contains a comma, a quote, or a
newline. nanocsv parses CSV the right way — a proper RFC 4180 state machine —
in two functions and about a kilobyte.
import { parse, stringify } from "nanocsv";
parse('id,name\n1,"Doe, John"'); // [["id","name"],["1","Doe, John"]]
parse("id,name\n1,Ada", { header: true }); // [{ id: "1", name: "Ada" }]
stringify([{ id: 1, name: "Doe, John" }]); // 'id,name\n1,"Doe, John"'- 🪶 Zero dependencies, ~1 KB gzipped. No
papaparse-sized download for a simple job. - ✅ Actually correct. Quoted fields, escaped quotes (
""), embedded commas and newlines,\nand\r\n. - 🔁 Round-trips.
parseandstringifyare designed to be lossless together. - 🧩 Two functions. Strings in, strings/objects out. No streams to wire up, no config object to memorize.
- 🌍 Runs everywhere. Node 18+, Deno, Bun, Cloudflare Workers and the browser.
- 🛡️ Type-safe. Written in TypeScript;
header: truechanges the return type to objects.
npm install nanocsv
# or: pnpm add nanocsv / yarn add nanocsv / bun add nanocsvShips ESM and CommonJS:
import { parse, stringify } from "nanocsv"; // ESM / TypeScript
const { parse, stringify } = require("nanocsv"); // CommonJS// Matrix of strings (default)
parse("a,b,c\n1,2,3");
// → [["a","b","c"], ["1","2","3"]]
// Objects keyed by the header row
parse("name,age\nAda,36\nBob,40", { header: true });
// → [{ name: "Ada", age: "36" }, { name: "Bob", age: "40" }]
// Quotes, embedded commas and newlines just work
parse('x,"a,b","line1\nline2"');
// → [["x", "a,b", "line1\nline2"]]
// Other formats
parse("a;b;c", { delimiter: ";" }); // semicolons
parse("a\tb\tc", { delimiter: "\t" }); // TSV
parse(" a , b ", { trim: true }); // trim each field
parse("# header\na,b", { comment: "#" }); // skip comment lines// From rows
stringify([["a", "b"], [1, 2]]);
// → "a,b\n1,2"
// From objects (header inferred from keys)
stringify([{ a: 1, b: 2 }, { a: 3, b: 4 }]);
// → "a,b\n1,2\n3,4"
// Fix the column order, or drop the header
stringify(records, { header: ["id", "name", "email"] });
stringify(records, { header: false });
// Only fields that need quoting are quoted
stringify([["plain", "needs,quote", 'has "quote"']]);
// → 'plain,"needs,quote","has ""quote"""'
// Or quote everything, and pick your line ending
stringify(rows, { quoteAll: true, newline: "\r\n", delimiter: ";" });Returns string[][], or Record<string, string>[] when header: true.
| Option | Type | Default | Description |
|---|---|---|---|
delimiter |
string |
"," |
Field separator. |
quote |
string |
'"' |
Quote character. |
header |
boolean |
false |
Use the first row as keys and return objects. |
skipEmptyLines |
boolean |
true |
Drop blank lines. |
trim |
boolean |
false |
Trim whitespace around each field. |
comment |
string |
— | Skip lines starting with this (outside quotes). |
Accepts an array of arrays or an array of plain objects. Returns a string.
| Option | Type | Default | Description |
|---|---|---|---|
delimiter |
string |
"," |
Field separator. |
quote |
string |
'"' |
Quote character. |
newline |
string |
"\n" |
Record separator. |
header |
boolean | string[] |
true* |
Emit/define the header. *Default true for objects only. |
quoteAll |
boolean |
false |
Quote every field instead of only when required. |
Values are coerced with String(); null/undefined become empty fields and
plain objects are JSON-stringified.
nanocsv |
"x".split(",") |
papaparse |
|
|---|---|---|---|
| Quoted fields / commas | ✅ | ❌ | ✅ |
| Escaped quotes & newlines | ✅ | ❌ | ✅ |
| Parse and stringify | ✅ | ❌ | ✅ |
| Zero dependencies | ✅ | ✅ | ✅ |
| ~1 KB gzipped | ✅ | ✅ | ❌ |
Need streaming gigabyte files or worker threads? Reach for
papaparse. Need to correctly parse the CSV you actually have, in a kilobyte? That'snanocsv.
Contributions are very welcome! Please read CONTRIBUTING.md and our Code of Conduct.
git clone https://github.com/didrod205/nanocsv.git
cd nanocsv
npm install
npm testnanocsv is free and MIT-licensed, built and maintained in spare time. If it
saved you from debugging a broken CSV split, please consider supporting it —
every bit helps keep the project healthy.
- ⭐ Star this repo — the simplest, free way to help others discover it.
- 🍋 Sponsor via Lemon Squeezy — one-time or recurring support.
Sponsoring? Open an issue and we'll add your name/logo here. Thank you! 🙏
MIT © nanocsv contributors