<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Руслан Фоменко</title>
    <description>The latest articles on DEV Community by Руслан Фоменко (@linolhamelton).</description>
    <link>https://dev.to/linolhamelton</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3729395%2F874e504b-b1df-41eb-b275-022434251b59.jpeg</url>
      <title>DEV Community: Руслан Фоменко</title>
      <link>https://dev.to/linolhamelton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/linolhamelton"/>
    <language>en</language>
    <item>
      <title>I'm Tired of Using Two CSV Libraries — I Built JTCSV</title>
      <dc:creator>Руслан Фоменко</dc:creator>
      <pubDate>Sat, 24 Jan 2026 02:12:13 +0000</pubDate>
      <link>https://dev.to/linolhamelton/im-tired-of-using-two-csv-libraries-i-built-jtcsv-53do</link>
      <guid>https://dev.to/linolhamelton/im-tired-of-using-two-csv-libraries-i-built-jtcsv-53do</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhgdbkymo0g9bdpn7lul.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhgdbkymo0g9bdpn7lul.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;The Problem That Frustrated Me&lt;br&gt;
A few months ago, I was working on a backend application that needed to:&lt;/p&gt;

&lt;p&gt;Accept CSV files from users (data import)&lt;/p&gt;

&lt;p&gt;Export data to CSV (reports)&lt;/p&gt;

&lt;p&gt;Sounds simple? In reality, I ended up installing three different packages:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
npm install papaparse json2csv csvtojson&lt;br&gt;
And it was hell. Three different APIs, three different ways to handle errors, three different support communities. When I updated one library, another broke. When I optimized CSV parsing, I forgot about the memory leak in JSON export.&lt;/p&gt;

&lt;p&gt;The worst part? Security.&lt;/p&gt;

&lt;p&gt;None of these packages protected against CSV injection attacks by default. I discovered in 2023 that this is a real vulnerability:&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
=1+1&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/sum"&gt;@sum&lt;/a&gt;(1+1)&lt;br&gt;
+1+1&lt;br&gt;
-1+1&lt;br&gt;
These strings in a CSV file can open as formulas in Excel. You think it's impossible? Think again.&lt;/p&gt;

&lt;p&gt;The Solution: JTCSV&lt;br&gt;
I spent a month building one library that solves ALL these problems:&lt;/p&gt;

&lt;p&gt;✅ JSON → CSV and CSV → JSON in one package&lt;br&gt;
✅ CSV injection protection by default (no need to remember settings)&lt;br&gt;
✅ NDJSON and TSV support (in case you need them)&lt;br&gt;
✅ TypeScript-first (full types included)&lt;br&gt;
✅ Streaming for large files (without OOM)&lt;br&gt;
✅ 10 framework plugins (Express, Next.js, Fastify ready to use)&lt;/p&gt;

&lt;p&gt;Quick Example&lt;br&gt;
Before (two packages):&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
// Package 1 for CSV → JSON&lt;br&gt;
import csv from 'csvtojson';&lt;br&gt;
const jsonData = await csv().fromFile('data.csv');&lt;/p&gt;

&lt;p&gt;// Package 2 for JSON → CSV&lt;br&gt;
import json2csv from 'json2csv';&lt;br&gt;
const { Parser } = json2csv;&lt;br&gt;
const parser = new Parser();&lt;br&gt;
const csv = parser.parse(jsonData);&lt;br&gt;
Now (one package):&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
import { csvToJson, jsonToCsv } from 'jtcsv';&lt;/p&gt;

&lt;p&gt;// CSV → JSON&lt;br&gt;
const jsonData = await csvToJson(csvString);&lt;/p&gt;

&lt;p&gt;// JSON → CSV&lt;br&gt;
const csvString = jsonToCsv(jsonData);&lt;br&gt;
Less code. Fewer dependencies. Fewer problems.&lt;/p&gt;

&lt;p&gt;Security: What We Do by Default&lt;br&gt;
javascript&lt;br&gt;
// Without protection (other libraries):&lt;br&gt;
{ formula: "=1+1" }&lt;br&gt;
// → Result: "=1+1" (Excel opens as formula!)&lt;/p&gt;

&lt;p&gt;// With JTCSV:&lt;br&gt;
const safe = jsonToCsv({ formula: "=1+1" });&lt;br&gt;
// → Result: "'=1+1" (prefix protects from Excel)&lt;br&gt;
This is enabled by default. You don't need to remember settings.&lt;/p&gt;

&lt;p&gt;Performance: We Don't Sacrifice Speed for Features&lt;br&gt;
I ran benchmarks (1M records):&lt;/p&gt;

&lt;p&gt;Operation   JTCSV   json2csv    csv-parser&lt;br&gt;
CSV → JSON    5.2s    N/A 5.5s&lt;br&gt;
JSON → CSV    3.9s    4.5s    N/A&lt;br&gt;
Memory peak 14 MB   28 MB   18 MB&lt;br&gt;
We're faster on JSON → CSV and more efficient on memory. Because I spent time optimizing.&lt;/p&gt;

&lt;p&gt;Framework Integration: Ready-Made Pieces&lt;br&gt;
JTCSV has built-in plugins for popular frameworks. Examples:&lt;/p&gt;

&lt;p&gt;Next.js:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
import { nextjsHandler } from 'jtcsv/nextjs';&lt;/p&gt;

&lt;p&gt;export const POST = nextjsHandler({&lt;br&gt;
  onUpload: async (data) =&amp;gt; {&lt;br&gt;
    // data is already converted to JSON&lt;br&gt;
    return { success: true, rows: data.length };&lt;br&gt;
  }&lt;br&gt;
});&lt;br&gt;
Express:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
import { expressMiddleware } from 'jtcsv/express';&lt;/p&gt;

&lt;p&gt;app.post('/import', expressMiddleware({&lt;br&gt;
  maxRecords: 10000,&lt;br&gt;
  detectFormat: true&lt;br&gt;
}), (req, res) =&amp;gt; {&lt;br&gt;
  const data = req.body; // Already JSON!&lt;br&gt;
  res.json({ imported: data.length });&lt;br&gt;
});&lt;br&gt;
No boilerplate. Just use it.&lt;/p&gt;

&lt;p&gt;Why I Open-Sourced It&lt;br&gt;
I work at a company that imports 10M+ CSV records monthly. We were saving hours maintaining this framework. I thought: "This should be available to everyone."&lt;/p&gt;

&lt;p&gt;JTCSV is on GitHub: &lt;a href="https://github.com/Linol-Hamelton/jtcsv" rel="noopener noreferrer"&gt;https://github.com/Linol-Hamelton/jtcsv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ Fully typed (TypeScript)&lt;/p&gt;

&lt;p&gt;📚 Comprehensive documentation&lt;/p&gt;

&lt;p&gt;🧪 16 test files (85%+ coverage)&lt;/p&gt;

&lt;p&gt;🔒 Security policy (SECURITY.md)&lt;/p&gt;

&lt;p&gt;🚀 CLI tool + TUI for terminal&lt;/p&gt;

&lt;p&gt;What's Next?&lt;br&gt;
If you have CSV/JSON workload, try JTCSV:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
npm install jtcsv&lt;br&gt;
Or directly in browser:&lt;/p&gt;

&lt;p&gt;xml&lt;/p&gt;

&lt;p&gt;I'll answer all questions in the comments. If you find bugs — that's comments or GitHub issues too.&lt;/p&gt;

&lt;p&gt;Thanks&lt;br&gt;
Thanks to the Node.js community for inspiration. Thanks to PapaParse, csv-parser, and json2csv for proving this market needs a solution. JTCSV stands on the shoulders of giants.&lt;/p&gt;

&lt;p&gt;Want to try it? → GitHub&lt;br&gt;
Found a bug? → Issues&lt;br&gt;
Questions? → Comments below!&lt;/p&gt;

&lt;p&gt;⭐ If you liked it, give it a star on GitHub!&lt;/p&gt;

</description>
      <category>npm</category>
      <category>json</category>
      <category>csv</category>
      <category>analytics</category>
    </item>
  </channel>
</rss>
