Skip to content

jtcsv Ecosystem

jtcsv is a JSON ↔ CSV toolkit shipped as ONE small published package (~18 KB gz) with optional siblings for Excel, codemods, framework adapters, and a terminal UI. This page is the map.

Distinguishing pillars

  • ~18 KB gzipped for jtcsv/csv — about half of papaparse for the same workhorse.
  • CSV-injection guard by default (preventCsvInjection: true covers =, +, -, @ prefixes per OWASP).
  • Tree-shakable subpath imports across 9 entries (jtcsv/csv, /json, /streams, /ndjson, /tsv, /errors, /browser, /plugins, /schema).
  • Three formats in one package — CSV, NDJSON, and TSV first-class (one dependency, not three).
  • TypeScript-native source — .d.ts generated from real types; strict-tsconfig clean on the public surface with a CI ratchet.
  • Zero runtime dependencies in the core; Sigstore-signed npm provenance (npm audit signatures jtcsv verifies).
  • Migration codemod — npx jtcsv-codemod papaparse|csvtojson rewrites imports and call sites. No competitor ships one.
  • Worker threads (Node) opt-in via useWorkers; Web Workers (browser) via the jtcsv-workers subpath.

Published packages

PackageVersionRoleInstall
jtcsv3.2.3Core JSON↔CSV/NDJSON/TSV toolkit. Streaming, browser-safe, zero deps.npm i jtcsv
jtcsv-codemod0.2.0jscodeshift transforms for migrations from papaparse / csvtojson / csv-parser.npx jtcsv-codemod papaparse
jtcsv-excel2.1.0Excel (.xlsx) round-trip via exceljs as a peer dep.npm i jtcsv-excel exceljs jtcsv
jtcsv-react0.1.0React hooks + components for jtcsv (useCsvUpload, useCsvParse, <CsvDropZone>).npm i jtcsv-react jtcsv react
jtcsv-vue0.1.0Vue 3 plugin + composables + v-csv-upload directive.npm i jtcsv-vue jtcsv vue

Note: jtcsv-excel is staged for npm publish in the Phase 4 release window. Until then it lives in the monorepo and can be linked locally via npm workspaces.

All three of jtcsv-excel, jtcsv-react, jtcsv-vue are staged for unscoped publish in Phase 5 — see docs/ECOSYSTEM_RENAMES.md for the rename plan; the imminent jtcsv@3.3.0-beta.0 cut on the next dist-tag is the first opportunity to publish them alongside the core.

Planned packages

Current nameTarget nameStatusWhat it does
@jtcsv/validatorjtcsv-validatorprivate, Phase 5 W13Zod-like schema validation over CSV/JSON pipelines
@jtcsv/tuijtcsv-tuiprivate, Phase 5 W14Terminal UI for interactive CSV inspection (blessed)
@jtcsv/express-middlewarejtcsv-expressprivate, Phase 5 W13Express middleware for CSV/JSON request bodies
@jtcsv/fastifyjtcsv-fastifyprivate, Phase 5 W13Fastify plugin (peer fastify-plugin ^4 || ^5)
@jtcsv/honojtcsv-honoprivate, Phase 5 W14Hono middleware (peer hono ^4)
@jtcsv/nestjsjtcsv-nestjsprivate, Phase 5 W14NestJS module (peer @nestjs/common+core ^9 || ^10 || ^11, rxjs ^7)
@jtcsv/nextjsjtcsv-nextjsprivate, Phase 5 W14Next.js App Router + Pages API routes + React hooks

Note: the @jtcsv npm scope is squatted by an unrelated user; all sibling packages ship unscoped. See Ecosystem renames for the rename plan.

Framework recipes

Copy-paste examples (not published as packages) live under examples/frameworks/ for: Angular, Nuxt, Remix, Svelte, SvelteKit, tRPC, Vue. If one deserves a published wrapper, open an issue.

FrameworkDocSummary
Express/integrations/expressCSV uploads via Busboy + createCsvToJsonStream
Fastify/integrations/fastifyCSV uploads via @fastify/multipart + createCsvToJsonStream
React Hook Form/integrations/react-hook-formImport CSV into a form using parseCsvFile from jtcsv/browser
Next.js App Router/integrations/nextjs-app-routerParse CSV uploads in an App Router POST route via csvToJson
Drizzle ORM/integrations/drizzle-ormImport CSV into Postgres via csvToJson + Drizzle (pg)
GraphQL/integrations/graphqlAccept CSV uploads via Apollo Server + graphql-upload

Command-line binaries

BinaryProvided byPurpose
jtcsvjtcsvConvert / stream / inspect CSV ↔ JSON / NDJSON / TSV from the shell.
jtcsv-codemodjtcsv-codemodRun jscodeshift transforms to rewrite papaparse / csvtojson sources to jtcsv.
jtcsv-tui(planned)Terminal UI for interactive CSV inspection (blessed + blessed-contrib).

Plugin host

jtcsv/plugins is a Node-only subpath providing the plugin manager. Plugins are first-class user code — the host calls registered hooks but does NOT sandbox them; treat plugin paths like require() — never untrusted-string-derived. See Plugin authoring and Plugins overview.

Browser bundle

jtcsv/browser is a self-contained UMD + ESM bundle (~16 KB ESM / ~16 KB UMD — browser ESM bundle, distinct from the ~18 KB gz jtcsv/csv subpath) with a separate Web Worker integration via the jtcsv-workers subpath (see Browser Workers).

Codemods

The jtcsv-codemod package ships jscodeshift transforms that rewrite imports + call sites from the most common alternatives to jtcsv:

bash
# papaparse → jtcsv
npx jtcsv-codemod papaparse 'src/**/*.{js,ts,tsx}'

# csvtojson → jtcsv
npx jtcsv-codemod csvtojson 'src/**/*.{js,ts,tsx}'

Both transforms handle imports, option renames, and call-site rewrites. Lossy conversions (event-emitter style .on('json'), csvtojson's preFileLine, papaparse's step) are surfaced as inline TODO comments instead of being silently dropped.

Security & provenance

Every release ≥3.0 is published with --provenance via GitHub Actions; the Sigstore attestation is verifiable with npm audit signatures jtcsv. Supply-chain controls: zero runtime deps in the core, OpenSSF Scorecard run nightly, all GitHub Actions SHA-pinned, Dependabot weekly. See Threat Model for STRIDE + ADRs.

What's NOT in the ecosystem

  • Excel formulas (xlsx is round-trip only; pivot tables / chart objects are out of scope).
  • HTML table parsing (use jsdom + jtcsv yourself).
  • AWS S3 / GCS adapters (use the cloud SDK stream into createCsvToJsonStream — that's the recipe).
  • Real-time tail / fs.watch wrappers — out of scope; pipe tail -f into the CLI instead.

Contributing

Want to ship an adapter / plugin / codemod? See docs/PLUGIN_AUTHORING.md and open a discussion on GitHub.

Released under the MIT License.