A powerful, lightweight TypeScript library for converting JSON arrays to CSV format
Transform your JSON data into properly formatted CSV with ease! ๐
- ๐ JSON to CSV Conversion - Seamlessly convert arrays of objects to CSV format
- โ๏ธ Customizable Delimiter - Use comma, semicolon, or any custom delimiter
- ๐ฏ Smart Header Generation - Automatically detects and creates headers from object keys
- ๐ก๏ธ CSV Escaping - Properly handles special characters, quotes, and newlines
- โก TypeScript First - Full type safety with comprehensive type definitions
- ๐ Error Handling - Detailed error messages with specific error codes
- ๐ฆ Zero Dependencies - Lightweight with no external dependencies
- ๐จ Data Type Support - Handles strings, numbers, booleans, objects, null, undefined
# Using npm
npm install json-data-to-csv
# Using yarn
yarn add json-data-to-csv
# Using pnpm
pnpm add json-data-to-csv
import { parse } from 'json-data-to-csv';
// Simple conversion
const data = [
{ name: 'Alice', age: 30, role: 'Developer' },
{ name: 'Bob', age: 25, role: 'Designer' },
];
const csv = parse(data);
console.log(csv);
// Output:
// name,age,role
// Alice,30,Developer
// Bob,25,Designer
Convert a simple array of objects to CSV format:
import { parse } from 'json-data-to-csv';
const employees = [
{ name: 'John Doe', age: 30, city: 'New York', salary: 75000 },
{ name: 'Jane Smith', age: 25, city: 'Los Angeles', salary: 80000 },
{ name: 'Mike Johnson', age: 35, city: 'Chicago', salary: 90000 },
];
const csv = parse(employees);
console.log(csv);
Output:
name,age,city,salary
John Doe,30,New York,75000
Jane Smith,25,Los Angeles,80000
Mike Johnson,35,Chicago,90000
Use different delimiters for various regional formats:
import { parse } from 'json-data-to-csv';
const data = [
{ product: 'Laptop', price: 999.99, stock: 50 },
{ product: 'Mouse', price: 29.99, stock: 100 },
];
// European format with semicolon
const csvSemicolon = parse(data, { delimiter: ';' });
console.log(csvSemicolon);
// Tab-separated values
const tsvFormat = parse(data, { delimiter: '\t' });
console.log(tsvFormat);
// Pipe-separated values
const psvFormat = parse(data, { delimiter: '|' });
console.log(psvFormat);
Output (semicolon):
product;price;stock
Laptop;999.99;50
Mouse;29.99;100
Handle various data types seamlessly:
import { parse } from 'json-data-to-csv';
const mixedData = [
{
id: 1,
name: 'John Doe',
active: true,
score: 95.5,
metadata: { role: 'admin', permissions: ['read', 'write'] },
lastLogin: new Date('2025-01-15'),
description: null,
notes: undefined,
tags: ['developer', 'senior'],
},
{
id: 2,
name: 'Jane Smith',
active: false,
score: 87.2,
metadata: { role: 'user' },
lastLogin: new Date('2025-01-10'),
bio: 'Software engineer with 5 years of experience',
},
];
const csv = parse(mixedData);
console.log(csv);
Output:
id,name,active,score,metadata,lastLogin,description,notes,tags,bio
1,John Doe,true,95.5,"{""role"":""admin"",""permissions"":[""read"",""write""]}",2025-01-15T00:00:00.000Z,,,"[""developer"",""senior""]",
2,Jane Smith,false,87.2,"{""role"":""user""}",2025-01-10T00:00:00.000Z,,,,"Software engineer with 5 years of experience"
Handle objects with different property sets:
import { parse } from 'json-data-to-csv';
const dynamicData = [
{ name: 'Alice', age: 30, department: 'Engineering' },
{ name: 'Bob', city: 'Seattle', country: 'USA', zipCode: '98101' },
{ age: 40, email: 'charlie@example.com', phone: '+1-555-0123' },
{
name: 'Diana',
department: 'Marketing',
email: 'diana@example.com',
manager: 'Alice',
},
];
const csv = parse(dynamicData);
console.log(csv);
Output:
name,age,department,city,country,zipCode,email,phone,manager
Alice,30,Engineering,,,,,,
Bob,,,"Seattle",USA,98101,,,
,40,,,,,charlie@example.com,+1-555-0123,
Diana,,Marketing,,,,"diana@example.com",,Alice
Properly escape CSV special characters:
import { parse } from 'json-data-to-csv';
const specialData = [
{
name: 'John "Johnny" Doe',
bio: 'Software engineer,\nspecializing in web development',
quote: 'He said, "Hello, world!"',
note: 'Contains\r\nWindows line endings',
},
{
name: "Jane O'Connor",
bio: 'Data scientist; loves statistics',
quote: 'Data tells a story',
note: 'Simple description',
},
];
const csv = parse(specialData);
console.log(csv);
Output:
name,bio,quote,note
"John ""Johnny"" Doe","Software engineer,
specializing in web development","He said, ""Hello, world!""","Contains
Windows line endings"
Jane O'Connor,"Data scientist; loves statistics",Data tells a story,Simple description
Converts an array of objects to CSV format with intelligent header detection.
function parse(data: JsonData, options?: ParseOptions): string;
Parameter | Type | Required | Description |
---|---|---|---|
data |
JsonData |
โ | Array of objects to convert to CSV |
options |
ParseOptions |
โ | Configuration options for parsing |
Property | Type | Default | Description |
---|---|---|---|
delimiter |
string |
',' |
Character used to separate CSV fields |
Type | Description |
---|---|
string |
CSV formatted string with header row and data rows |
Exception | Description |
---|---|
JsonToCsvError |
When input validation fails or processing errors occur |
// Main data type - array of objects
type JsonData = Record<string, any>[];
// Configuration options
interface ParseOptions {
delimiter?: string;
}
// Custom error class with error codes
class JsonToCsvError extends Error {
constructor(message: string, public code?: string);
name: 'JsonToCsvError';
code?: string;
}
JavaScript Type | CSV Output | Example |
---|---|---|
string |
Direct value | "Hello" โ Hello |
number |
String representation | 42 โ 42 |
boolean |
String representation | true โ true |
null |
Empty field | null โ `` |
undefined |
Empty field | undefined โ `` |
object |
JSON string | {a:1} โ "{""a"":1}" |
array |
JSON string | [1,2] โ "[1,2]" |
Date |
ISO string | new Date() โ 2025-01-15T... |
The library provides comprehensive error handling with specific error codes for easy debugging:
import { parse, JsonToCsvError } from 'json-data-to-csv';
try {
const csv = parse([]);
} catch (error) {
if (error instanceof JsonToCsvError) {
console.error(`โ Error: ${error.message}`);
console.error(`๐ Code: ${error.code}`);
// Handle specific error types
switch (error.code) {
case 'EMPTY_INPUT':
console.log('๐ก Tip: Provide a non-empty array of objects');
break;
case 'INVALID_DELIMITER':
console.log('๐ก Tip: Use a non-empty string as delimiter');
break;
default:
console.log('๐ก Check the documentation for more details');
}
}
}
Error Code | Description | Example Cause |
---|---|---|
INVALID_INPUT |
Input is not an array | parse("string") |
EMPTY_INPUT |
Array is empty | parse([]) |
INVALID_DELIMITER |
Invalid delimiter | parse(data, { delimiter: "" }) |
INVALID_DATA_TYPE |
Non-object in array | parse([null, "string"]) |
NO_PROPERTIES |
Objects have no properties | parse([{}, {}]) |
SERIALIZATION_ERROR |
Failed to serialize object | Circular reference in object |
ROW_PROCESSING_ERROR |
Error processing specific row | Malformed data in row |
UNEXPECTED_ERROR |
Unexpected internal error | System/memory issues |
import { parse, JsonToCsvError } from 'json-data-to-csv';
// Example 1: Empty array
try {
parse([]);
} catch (error) {
console.log(error.message); // "Input data cannot be empty"
console.log(error.code); // "EMPTY_INPUT"
}
// Example 2: Invalid data type
try {
parse(['string', 123, null] as any);
} catch (error) {
console.log(error.message); // "All data items must be objects"
console.log(error.code); // "INVALID_DATA_TYPE"
}
// Example 3: Invalid delimiter
try {
parse([{ name: 'John' }], { delimiter: null as any });
} catch (error) {
console.log(error.message); // "Delimiter must be a non-empty string"
console.log(error.code); // "INVALID_DELIMITER"
}
The library follows RFC 4180 standards and properly handles all CSV special characters:
Scenario | Handling | Example |
---|---|---|
Delimiter in field | Wrap in quotes | "Contains, comma" |
Double quotes | Double the quotes | "He said ""Hello""" |
Newlines | Preserve in quotes | "Line 1\nLine 2" |
Carriage returns | Preserve in quotes | "Windows\r\nending" |
import { parse } from 'json-data-to-csv';
// Example with various special characters
const problematicData = [
{
name: 'John "The Coder" Smith',
address: '123 Main St,\nApt 4B\nNew York, NY',
bio: 'Software engineer, loves "clean code" principles',
note: 'Contact via email; phone available Mon-Fri',
tags: 'javascript,typescript,react',
},
];
const csv = parse(problematicData);
console.log(csv);
Output:
name,address,bio,note,tags
"John ""The Coder"" Smith","123 Main St,
Apt 4B
New York, NY","Software engineer, loves ""clean code"" principles","Contact via email; phone available Mon-Fri","javascript,typescript,react"
// Works with international characters and various delimiters
const internationalData = [
{ name: 'Josรฉ Marรญa', city: 'Sรฃo Paulo', note: 'Espaรฑol, Portuguรชs' },
{ name: '็ฐไธญๅคช้', city: 'ๆฑไบฌ', note: 'ๆฅๆฌ่ชใตใใผใ' },
{ name: 'Franรงois', city: 'Paris', note: 'Caractรจres accentuรฉs' },
];
// European format (semicolon delimiter)
const europeanCsv = parse(internationalData, { delimiter: ';' });
console.log(europeanCsv);
import { parse } from 'json-data-to-csv';
// Export user analytics data
const analyticsData = [
{
userId: 'user_001',
name: 'Alice Johnson',
email: 'alice@company.com',
lastLogin: '2025-06-04T10:30:00Z',
pageViews: 245,
sessionDuration: 1800, // seconds
conversions: 3,
revenue: 299.97,
},
// ... more user data
];
const csv = parse(analyticsData);
// Save to file or send as download
console.log('๐ Analytics Export Ready!');
// Export product inventory
const products = [
{
sku: 'LAPTOP-001',
name: 'MacBook Pro 14"',
category: 'Electronics',
price: 1999.99,
stock: 50,
description: 'High-performance laptop for professionals',
specs: { ram: '16GB', storage: '512GB SSD', chip: 'M3 Pro' },
tags: ['laptop', 'apple', 'professional'],
inStock: true,
},
];
const productCsv = parse(products, { delimiter: '|' });
// Export employee data for payroll
const employees = [
{
employeeId: 'EMP001',
fullName: 'John Smith',
department: 'Engineering',
position: 'Senior Developer',
hireDate: '2023-01-15',
salary: 95000,
benefits: { health: true, dental: true, vision: false },
skills: ['JavaScript', 'Python', 'React'],
manager: 'Jane Doe',
},
];
const hrCsv = parse(employees);
// Export financial transactions
const transactions = [
{
transactionId: 'TXN_20250604_001',
date: '2025-06-04',
amount: -89.5,
description: 'Online Purchase - Amazon',
category: 'Shopping',
account: 'Checking ***1234',
merchant: { name: 'Amazon.com', location: 'Online' },
status: 'Completed',
},
];
const financialCsv = parse(transactions, { delimiter: ';' });
- Large datasets: The library handles thousands of records efficiently
- Memory usage: Streaming not required for typical web application datasets
- Complex objects: Nested objects are serialized as JSON strings automatically
// โ
Good: Efficient for typical use cases
const largeDataset = Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `User ${i}`,
email: `user${i}@example.com`,
active: i % 2 === 0,
}));
const csv = parse(largeDataset); // Handles efficiently
// โ
Use consistent property names across objects
const goodData = [
{ id: 1, name: 'John', email: 'john@example.com' },
{ id: 2, name: 'Jane', email: 'jane@example.com' },
];
// โ ๏ธ Inconsistent properties create sparse CSV
const sparseData = [
{ id: 1, name: 'John' },
{ email: 'jane@example.com', phone: '555-0123' },
];
// โ
Handle errors appropriately
try {
const csv = parse(userData);
return csv;
} catch (error) {
if (error instanceof JsonToCsvError) {
logger.error(`CSV conversion failed: ${error.message}`, {
code: error.code,
});
return null;
}
throw error;
}
# Install dependencies
npm install
# Build TypeScript to JavaScript
npm run build
# Build in watch mode for development
npm run dev
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm test -- --coverage
json-data-to-csv/
โโโ ๐ src/
โ โโโ ๐ index.ts # Main library code
โ โโโ ๐ __tests__/
โ โโโ ๐ index.test.ts # Comprehensive test suite
โโโ ๐ dist/ # Compiled output
โ โโโ ๐ index.js # ES modules output
โ โโโ ๐ index.d.ts # TypeScript definitions
โโโ ๐ package.json # Package configuration
โโโ ๐ tsconfig.json # TypeScript configuration
โโโ ๐ jest.config.js # Test configuration
โโโ ๐ README.md # Documentation
# Clone and setup
git clone <repository-url>
cd jsontocsv
npm install
# Run tests while developing
npm run test:watch
# Test your changes
node test.js
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License - feel free to use this library in your projects! ๐
We welcome contributions! Here's how you can help improve this library:
- Check existing issues first to avoid duplicates
- Create a detailed issue with:
- Clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Sample data that causes the issue
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature
- Make your changes with tests
- Test thoroughly:
npm test npm run build
- Commit your changes:
git commit -m 'Add some amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request with:
- Clear description of changes
- Link to any related issues
- Screenshots/examples if applicable
- Write tests for new features
- Follow TypeScript best practices
- Update documentation for API changes
- Maintain backward compatibility when possible
- Keep dependencies minimal (currently zero dependencies!)
- Streaming support for very large datasets
- Custom formatters for specific data types
- Schema validation options
- Performance benchmarks and optimizations
- Browser compatibility testing
- Additional output formats (TSV, PSV, etc.)
Version | Date | Changes |
---|---|---|
1.0.0 | 2025-06-04 | ๐ Initial release with core functionality |
โ JSON to CSV conversion | ||
โ Customizable delimiters | ||
โ Comprehensive error handling | ||
โ Full TypeScript support | ||
โ Zero dependencies |
Made with โค๏ธ by Ashish Patel
๐ฆ npm โข ๐ GitHub โข ๐ Issues โข ๐ Changelog
โญ Star this repo if you find it helpful!