@json2csv/node
Node.js Transform stream and promise-based parser for converting JSON and NDJSON into CSV.
Repository Health
Technical Analysis
@json2csv/node is the Node.js integration package for the json2csv project, a fast and highly configurable JSON-to-CSV converter that follows the RFC4180 delimited-text specification. It exposes two complementary APIs: a Transform stream that can be piped directly into Node’s Stream API (file reads, HTTP responses, or any other readable source), and an AsyncParser that wraps the transform in a friendlier promise-based parse().promise() call while still supporting piping to a writable destination.
Under the hood, the package delegates all JSON tokenizing and CSV formatting to @json2csv/plainjs’s StreamParser, which itself is built on @streamparser/json for incremental JSON parsing. This keeps @json2csv/node itself a thin, focused adapter: it buffers and coalesces output chunks per _transform call (rather than pushing once per CSV row), forwards header/line events for observability, and normalizes a wide range of input shapes — strings, typed arrays, arrays, streams, async iterables, and single objects — into a Node Readable before piping it through the core parser.
Because the conversion is stream-based end to end, it scales to arbitrarily large datasets without loading the full JSON payload into memory, and supports both standard JSON arrays and newline-delimited JSON (NDJSON). It ships as part of a monorepo alongside sibling packages for plain JS, WHATWG streams, a CLI, and shared formatters/transforms, so the same core parsing logic powers every runtime target.
What You Get
- A
Transformclass that plugs directly into Node’s Stream API for piping JSON in and CSV out - An
AsyncParserwith a.parse(data).promise()convenience method for one-shot conversions - Automatic normalization of strings, typed arrays, plain arrays, objects, and async iterables into a stream
- Support for both standard JSON arrays and NDJSON without loading the full payload into memory
headerandlineevents for observing the conversion as it happens- Configurable delimiters, EOL characters, default values, custom field selectors, and custom formatters/transforms via the shared json2csv core
Common Use Cases
- Streaming a large database export or API response directly to a CSV file without buffering it in memory
- Converting an HTTP response body (JSON or NDJSON) into a downloadable CSV attachment
- Building ETL or reporting pipelines that need CSV output from streaming JSON sources
- Piping JSON log or event data into CSV for spreadsheet analysis
Under The Hood
Architecture
The package is a thin Node-specific adapter over @json2csv/plainjs’s StreamParser. Transform (packages/node/src/Transform.ts) extends Node’s stream.Transform, instantiating a StreamParser in its constructor and wiring its onHeader/onLine/onData/onError/onEnd callbacks to Node stream events and an internal outputBuffer that coalesces multiple CSV rows produced from a single input chunk into one push() call, avoiding excessive downstream event overhead. AsyncParser (packages/node/src/AsyncParser.ts) wraps Transform behind a single parse() method: it normalizes strings, ArrayBufferViews, arrays (filtering out nulls via a generator), plain objects, and existing Readable/ReadableStream inputs into a Node Readable, then pipes that through a freshly constructed Transform, returning the resulting stream (which itself exposes a .promise() helper). This separation lets the same core streaming/tokenizing logic in @json2csv/plainjs be reused unmodified across the node, whatwg, and cli sibling packages.
Tech Stack
Written in TypeScript targeting Node 20+, built with tsc into dual CJS/ESM outputs (a custom build-cjs.js script post-processes the CommonJS build) and managed as an npm workspace inside the json2csv monorepo alongside @json2csv/plainjs, @json2csv/formatters, @json2csv/transforms, @json2csv/whatwg, and @json2csv/cli. JSON tokenizing is delegated to @streamparser/json, the same author’s incremental JSON parser. Tests run on Vitest with coverage reported to Coveralls; linting and formatting are handled by Biome.
Code Quality
The package has a real, non-trivial Vitest suite (Transform.test.ts, AsyncParser.test.ts, AsyncParserInMemory.test.ts) covering object-mode streaming, NDJSON handling, small-chunk-size edge cases, and error propagation, plus a CommonJS.cjs script that verifies the CJS build’s interop. Error handling is explicit: _transform/_final wrap the underlying parser calls in try/catch and flush any buffered output before forwarding errors to the stream’s done callback rather than swallowing them. Generics (TRaw, T) type the raw input and transformed record shapes throughout. CI (GitHub Actions) runs Biome linting, a full build, and coverage-instrumented tests across Node 22.x/24.x on both Ubuntu and Windows.
API Design
The public surface is deliberately small — two exported classes (Transform, AsyncParser) plus re-exported option types — and accepts a broad range of input shapes (strings, buffers, arrays, streams, async iterables, single objects) through one parse() entry point, minimizing boilerplate for common one-shot conversions while still exposing the full Transform stream for advanced piping. The extensive docsify documentation site (quick-start, per-parser pages, advanced-options, migration guides) keeps onboarding straightforward despite the option surface inherited from the shared core.
Used by 2 apps in this directory
Formbricks
Forms Surveys · Marketing · Analytics
Open-source experience management platform for in-app, website, email, and link surveys — privacy-first and fully self-hostable.
NodeBB
Community
Modern Node.js forum software with real-time WebSockets, multi-database support, and a plugin ecosystem — the community platform built for the open web and the Fediverse.