Skip to content

didrod205/nanocsv

nanocsv

A tiny, correct CSV parser & stringifier in ~1 KB. Zero dependencies. Handles the quoting edge cases naive split-on-comma code gets wrong.

npm version bundle size CI types license

"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"'

Why nanocsv?

  • 🪶 Zero dependencies, ~1 KB gzipped. No papaparse-sized download for a simple job.
  • Actually correct. Quoted fields, escaped quotes (""), embedded commas and newlines, \n and \r\n.
  • 🔁 Round-trips. parse and stringify are 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: true changes the return type to objects.

Install

npm install nanocsv
# or: pnpm add nanocsv  /  yarn add nanocsv  /  bun add nanocsv

Ships ESM and CommonJS:

import { parse, stringify } from "nanocsv";        // ESM / TypeScript
const { parse, stringify } = require("nanocsv");   // CommonJS

Usage

Parsing

// 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

Stringifying

// 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: ";" });

API

parse(input, options?)

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).

stringify(rows, options?)

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.

Comparison

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's nanocsv.

Contributing

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 test

💖 Sponsor

nanocsv 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! 🙏

License

MIT © nanocsv contributors

About

Tiny zero-dependency CSV parser & stringifier — handles quotes, escaped quotes, embedded commas/newlines & CRLF. ~1KB.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors