
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
@cerios/csv-nested-json
Advanced tools
Parse CSV files into nested JSON objects with support for dot notation, arrays, and complex data structures
A powerful TypeScript CSV parser that transforms flat CSV data into nested JSON objects with support for dot notation, automatic array detection, and complex hierarchical structures.
address.city)npm install @cerios/csv-nested-json
import { CsvParser } from '@cerios/csv-nested-json';
// Parse CSV file
const result = CsvParser.parseFileSync('data.csv');
console.log(result);
// Output:
// [
// {
// id: "1",
// name: "John Doe",
// address: {
// street: "123 Main St",
// city: "New York",
// zip: "10001"
// }
// }
// ]
| Method | Description |
|---|---|
CsvParser.parseFileSync() | Parse CSV file synchronously |
CsvParser.parseFile() | Parse CSV file asynchronously |
CsvParser.parseString() | Parse CSV string content |
CsvParser.parseStream() | Parse CSV from readable stream |
CsvStreamParser | True streaming parser for very large files |
JsonToCsv.stringify() | Convert JSON objects to CSV string |
JsonToCsv.writeFileSync() | Write JSON objects to CSV file (sync) |
JsonToCsv.writeFile() | Write JSON objects to CSV file (async) |
import { CsvParser } from '@cerios/csv-nested-json';
const result = CsvParser.parseFileSync('./data.csv');
When to use: Small to medium files (<10MB), synchronous workflows, simple scripts.
import { CsvParser } from '@cerios/csv-nested-json';
const result = await CsvParser.parseFile('./data.csv');
When to use: Medium to large files, async/await workflows, web servers, non-blocking operations.
import { CsvParser } from '@cerios/csv-nested-json';
const csvString = `id,name,age
1,Alice,30
2,Bob,25`;
const result = CsvParser.parseString(csvString);
When to use: API responses, in-memory CSV data, testing, dynamic CSV generation.
import { CsvParser } from '@cerios/csv-nested-json';
import { createReadStream } from 'node:fs';
const stream = createReadStream('./large-file.csv');
const result = await CsvParser.parseStream(stream);
When to use: Very large files (>100MB), memory-constrained environments, real-time processing.
For very large files where you want to process records one at a time without loading everything into memory:
import { CsvStreamParser } from '@cerios/csv-nested-json';
import { createReadStream } from 'node:fs';
const parser = new CsvStreamParser({
autoParseNumbers: true,
autoParseBooleans: true
});
// Using async iteration
const stream = createReadStream('./very-large-file.csv');
for await (const record of stream.pipe(parser)) {
console.log('Parsed record:', record);
// Process each record as it's parsed
}
// Or using events
createReadStream('./very-large-file.csv')
.pipe(new CsvStreamParser())
.on('data', (record) => {
console.log('Record:', record);
})
.on('end', () => {
console.log('Done!');
})
.on('error', (err) => {
console.error('Error:', err);
});
When to use: Files too large to fit in memory, real-time processing, ETL pipelines.
import { JsonToCsv } from '@cerios/csv-nested-json';
const data = [
{
id: '1',
name: 'Alice',
address: { city: 'NYC', zip: '10001' }
},
{
id: '2',
name: 'Bob',
address: { city: 'LA', zip: '90001' }
}
];
// Convert to CSV string
const csvString = JsonToCsv.stringify(data);
console.log(csvString);
// Output:
// id,name,address.city,address.zip
// 1,Alice,NYC,10001
// 2,Bob,LA,90001
// Write directly to file
JsonToCsv.writeFileSync('./output.csv', data);
// Or async
await JsonToCsv.writeFile('./output.csv', data);
Input CSV:
id,name,email
1,John Doe,john@example.com
2,Jane Smith,jane@example.com
Output JSON:
[
{
"id": "1",
"name": "John Doe",
"email": "john@example.com"
},
{
"id": "2",
"name": "Jane Smith",
"email": "jane@example.com"
}
]
Input CSV:
id,name,address.street,address.city,address.zip
1,John Doe,123 Main St,New York,10001
Code:
const result = CsvParser.parseFileSync('./nested-data.csv');
Output JSON:
[
{
"id": "1",
"name": "John Doe",
"address": {
"street": "123 Main St",
"city": "New York",
"zip": "10001"
}
}
]
Rows without a value in the first column are treated as continuation rows and automatically create arrays:
Input CSV:
id,name,phones.type,phones.number
1,Alice,mobile,555-0001
,,home,555-0002
,,work,555-0003
Code:
const result = CsvParser.parseFileSync('./grouped-data.csv');
Output JSON:
[
{
"id": "1",
"name": "Alice",
"phones": [
{ "type": "mobile", "number": "555-0001" },
{ "type": "home", "number": "555-0002" },
{ "type": "work", "number": "555-0003" }
]
}
]
Input CSV:
id,user.name,user.profile.age,user.profile.address.city,user.profile.address.zip
1,Alice,30,New York,10001
Code:
const result = CsvParser.parseString(csvContent);
Output JSON:
[
{
"id": "1",
"user": {
"name": "Alice",
"profile": {
"age": "30",
"address": {
"city": "New York",
"zip": "10001"
}
}
}
}
]
[] SuffixUse the [] suffix in headers to force a field to always be an array, even with a single value:
Input CSV:
id,name,tags[]
1,Alice,javascript
2,Bob,python
Code:
const result = CsvParser.parseString(csvContent);
Output JSON:
[
{ "id": "1", "name": "Alice", "tags": ["javascript"] },
{ "id": "2", "name": "Bob", "tags": ["python"] }
]
const csvContent = `id,name,age,price,active,verified
1,Alice,30,19.99,true,FALSE
2,Bob,25,29.99,false,TRUE`;
const result = CsvParser.parseString(csvContent, {
autoParseNumbers: true,
autoParseBooleans: true
});
// Result:
// [
// { id: 1, name: "Alice", age: 30, price: 19.99, active: true, verified: false },
// { id: 2, name: "Bob", age: 25, price: 29.99, active: false, verified: true }
// ]
Note: Strings with leading zeros (like "007") are preserved as strings to avoid data loss.
const csvContent = `id,name,createdAt,updatedAt
1,Alice,2024-01-15,2024-06-30T10:30:00Z`;
const result = CsvParser.parseString(csvContent, {
autoParseDates: true
});
// Result:
// [
// {
// id: "1",
// name: "Alice",
// createdAt: Date("2024-01-15"),
// updatedAt: Date("2024-06-30T10:30:00Z")
// }
// ]
const csvContent = `id,name,email
1,alice,alice@example.com
2,bob,bob@example.com`;
const result = CsvParser.parseString(csvContent, {
valueTransformer: (value, header) => {
// Uppercase names
if (header === 'name' && typeof value === 'string') {
return value.toUpperCase();
}
return value;
}
});
// Result:
// [
// { id: "1", name: "ALICE", email: "alice@example.com" },
// { id: "2", name: "BOB", email: "bob@example.com" }
// ]
const csvContent = `User ID,First Name,Last Name,Email Address
1,John,Doe,john@example.com`;
const result = CsvParser.parseString(csvContent, {
// Convert headers to camelCase
headerTransformer: (header) => {
return header
.toLowerCase()
.replace(/\s+(.)/g, (_, c) => c.toUpperCase());
}
});
// Result:
// [{ userId: "1", firstName: "John", lastName: "Doe", emailAddress: "john@example.com" }]
const csvContent = `user_id,first_name,last_name
1,John,Doe`;
const result = CsvParser.parseString(csvContent, {
columnMapping: {
'user_id': 'id',
'first_name': 'firstName',
'last_name': 'lastName'
}
});
// Result:
// [{ id: "1", firstName: "John", lastName: "Doe" }]
Filter rows during parsing for better memory efficiency:
const csvContent = `id,name,status
1,Alice,active
2,Bob,deleted
3,Charlie,active
4,Diana,pending`;
const result = CsvParser.parseString(csvContent, {
rowFilter: (record, rowIndex) => {
// Only include active records
return record.status === 'active';
}
});
// Result:
// [
// { id: "1", name: "Alice", status: "active" },
// { id: "3", name: "Charlie", status: "active" }
// ]
const csvContent = `Report generated on 2024-01-15
Source: Production Database
id,name,email
1,Alice,alice@example.com
2,Bob,bob@example.com`;
const result = CsvParser.parseString(csvContent, {
skipRows: 2 // Skip the first 2 metadata rows
});
// Result:
// [
// { id: "1", name: "Alice", email: "alice@example.com" },
// { id: "2", name: "Bob", email: "bob@example.com" }
// ]
const csvContent = `id,name,status,country
1,Alice,,
2,Bob,active,USA`;
const result = CsvParser.parseString(csvContent, {
defaultValues: {
status: 'pending',
country: 'Unknown'
}
});
// Result:
// [
// { id: "1", name: "Alice", status: "pending", country: "Unknown" },
// { id: "2", name: "Bob", status: "active", country: "USA" }
// ]
const csvContent = `id,name,nickname
1,Alice,N/A
2,Bob,null
3,Charlie,Bobby`;
const result = CsvParser.parseString(csvContent, {
nullValues: ['null', 'NULL', 'N/A', 'n/a', ''],
nullRepresentation: 'null' // or 'undefined', 'empty-string', 'omit'
});
// Result with nullRepresentation: 'null':
// [
// { id: "1", name: "Alice", nickname: null },
// { id: "2", name: "Bob", nickname: null },
// { id: "3", name: "Charlie", nickname: "Bobby" }
// ]
// Result with nullRepresentation: 'omit' (default):
// [
// { id: "1", name: "Alice" },
// { id: "2", name: "Bob" },
// { id: "3", name: "Charlie", nickname: "Bobby" }
// ]
The parser automatically strips UTF-8 and UTF-16 BOM by default:
// BOM is automatically handled
const result = CsvParser.parseFileSync('./windows-excel-export.csv');
// Disable BOM stripping if needed
const result2 = CsvParser.parseString(csvContent, {
stripBom: false
});
Input CSV:
id,username,profile.firstName,profile.lastName,addresses.type,addresses.city
1,johndoe,John,Doe,home,New York
,,,,work,Boston
2,janedoe,Jane,Doe,home,Chicago
Code:
const result = CsvParser.parseFileSync('./complex-data.csv');
Output JSON:
[
{
"id": "1",
"username": "johndoe",
"profile": {
"firstName": "John",
"lastName": "Doe"
},
"addresses": [
{ "type": "home", "city": "New York" },
{ "type": "work", "city": "Boston" }
]
},
{
"id": "2",
"username": "janedoe",
"profile": {
"firstName": "Jane",
"lastName": "Doe"
},
"addresses": {
"type": "home",
"city": "Chicago"
}
}
]
Note: The first record has an array of addresses (multiple entries), while the second has a single address object.
Semicolon-separated values:
const csvSemicolon = `id;name;city
1;Alice;NYC
2;Bob;LA`;
const result = CsvParser.parseString(csvSemicolon, {
delimiter: ';'
});
Tab-separated values:
const csvTab = `id\tname\tcity
1\tAlice\tNYC`;
const result = CsvParser.parseString(csvTab, {
delimiter: '\t'
});
Pipe-separated values:
const csvPipe = `id|name|city
1|Alice|NYC`;
const result = CsvParser.parseString(csvPipe, {
delimiter: '|'
});
const csvSingleQuote = `id,name,message
1,Alice,'Hello, World'
2,Bob,'It''s working'`;
const result = CsvParser.parseString(csvSingleQuote, {
quote: "'"
});
// Latin1 encoding
const result = await CsvParser.parseFile('./data-latin1.csv', {
encoding: 'latin1'
});
// UTF-16LE encoding
const result2 = await CsvParser.parseFile('./data-utf16.csv', {
encoding: 'utf16le'
});
// Ignore extra columns silently
const result1 = CsvParser.parseString(csvData, {
validationMode: 'ignore'
});
// Warn about extra columns (default)
const result2 = CsvParser.parseString(csvData, {
validationMode: 'warn'
});
// Throw error on extra columns
try {
const result3 = CsvParser.parseString(csvData, {
validationMode: 'error'
});
} catch (error) {
console.error('Validation error:', error.message);
}
async function parseApiCsv() {
const response = await fetch('https://api.example.com/data.csv');
const csvString = await response.text();
const data = CsvParser.parseString(csvString, {
validationMode: 'ignore'
});
return data;
}
import { createReadStream } from 'node:fs';
async function parseLargeFile(filePath: string) {
const stream = createReadStream(filePath, {
highWaterMark: 64 * 1024 // 64KB chunks
});
const data = await CsvParser.parseStream(stream, {
validationMode: 'warn',
encoding: 'utf-8'
});
return data;
}
European CSV files typically use semicolon delimiters and comma as decimal separator:
const europeanCsv = `id;name;price;location.city;location.country
1;Product A;12,50;Paris;France
2;Product B;8,99;Berlin;Germany`;
const result = CsvParser.parseString(europeanCsv, {
delimiter: ';',
validationMode: 'error'
});
// Result:
// [
// {
// id: "1",
// name: "Product A",
// price: "12,50",
// location: { city: "Paris", country: "France" }
// },
// ...
// ]
const files = ['data1.csv', 'data2.csv', 'data3.csv'];
const results = await Promise.all(
files.map(file => CsvParser.parseFile(file))
);
interface CsvParserOptions {
// Validation
validationMode?: 'ignore' | 'warn' | 'error'; // Default: 'warn'
// Parsing
delimiter?: string; // Default: ','
quote?: string; // Default: '"'
// File I/O
encoding?: BufferEncoding; // Default: 'utf-8'
// Row handling
skipRows?: number; // Default: 0
stripBom?: boolean; // Default: true
rowFilter?: (record, rowIndex) => boolean; // Filter rows during parsing
// Value transformations
autoParseNumbers?: boolean; // Default: false
autoParseBooleans?: boolean; // Default: false
autoParseDates?: boolean; // Default: false
valueTransformer?: (value, header) => any; // Custom value transformer
// Header transformations
headerTransformer?: (header) => string; // Transform header names
columnMapping?: Record<string, string>; // Rename columns
// Array handling
arraySuffixIndicator?: string; // Default: '[]'
emptyArrayBehavior?: 'empty-array' | 'omit'; // Default: 'omit'
// Null handling
nullValues?: string[]; // Values to treat as null
nullRepresentation?: 'null' | 'undefined' | 'empty-string' | 'omit'; // Default: 'omit'
// Default values
defaultValues?: Record<string, string>; // Default values for empty cells
}
validationModeControls how the parser handles rows with more values than headers:
'ignore': Silently ignore extra values'warn' (default): Log a warning to console'error': Throw a CsvValidationErrordelimiterField delimiter character. Common values:
',' (default) - Comma-separated values';' - Semicolon-separated values (common in Europe)'\t' - Tab-separated values'|' - Pipe-separated valuesquoteQuote character for escaping fields containing delimiters or newlines:
'"' (default) - Double quotes"'" - Single quotesencodingFile encoding when reading from files or streams:
'utf-8' (default)'utf-16le''latin1''ascii'skipRowsNumber of rows to skip before the header row. Useful for files with metadata at the top.
stripBomAutomatically remove BOM (Byte Order Mark) from the beginning of content. Default: true
autoParseNumbersAutomatically convert numeric strings to numbers. Strings with leading zeros (like "007") are preserved.
autoParseBooleansAutomatically convert 'true'/'false' strings to booleans (case-insensitive).
autoParseDatesAutomatically convert date strings to JavaScript Date objects using Date.parse().
valueTransformerCustom function to transform values after parsing. Called after auto-parse options.
valueTransformer: (value, header) => {
if (header === 'email') return value.toLowerCase();
return value;
}
headerTransformerTransform header names before processing. Useful for converting to camelCase, lowercase, etc.
headerTransformer: (header) => header.toLowerCase().replace(/\s+/g, '_')
columnMappingMap/rename column headers. Applied after headerTransformer.
columnMapping: { 'user_id': 'id', 'first_name': 'firstName' }
rowFilterFilter rows during parsing. More memory-efficient than filtering after parsing.
rowFilter: (record, rowIndex) => record.status === 'active'
arraySuffixIndicatorSuffix in headers to force array type. Default: '[]'
emptyArrayBehaviorHow to handle forced array fields with no values:
'omit' (default): Don't include the field'empty-array': Include as []nullValuesStrings to interpret as null values. Default: ['null', 'NULL', 'nil', 'NIL']
nullRepresentationHow to represent null values in output:
'omit' (default): Remove the field'null': Use JavaScript null'undefined': Use JavaScript undefined'empty-string': Use empty string ''defaultValuesDefault values for columns when cells are empty.
defaultValues: { status: 'pending', country: 'Unknown' }
const result = await CsvParser.parseFile('./data.csv', {
// Validation
validationMode: 'error',
// Parsing
delimiter: ',',
quote: '"',
encoding: 'utf-8',
// Row handling
skipRows: 2,
stripBom: true,
rowFilter: (record) => record.status !== 'deleted',
// Value transformations
autoParseNumbers: true,
autoParseBooleans: true,
autoParseDates: true,
valueTransformer: (value, header) => {
if (header === 'email') return value.toLowerCase();
return value;
},
// Header transformations
headerTransformer: (h) => h.toLowerCase().replace(/\s+/g, '_'),
columnMapping: { 'user_id': 'id' },
// Array handling
arraySuffixIndicator: '[]',
emptyArrayBehavior: 'empty-array',
// Null handling
nullValues: ['null', 'N/A', '-'],
nullRepresentation: 'null',
// Defaults
defaultValues: { status: 'pending' }
});
parseFileSync<T>(filePath: string, options?: CsvParserOptions): T[]Parses a CSV file synchronously and returns an array of nested JSON objects.
parseFile<T>(filePath: string, options?: CsvParserOptions): Promise<T[]>Parses a CSV file asynchronously.
parseString<T>(csvContent: string, options?: CsvParserOptions): T[]Parses CSV string content.
parseStream<T>(stream: Readable, options?: CsvParserOptions): Promise<T[]>Parses CSV from a readable stream.
A Transform stream that parses CSV data chunk by chunk, emitting records as they become available.
import { CsvStreamParser } from '@cerios/csv-nested-json';
const parser = new CsvStreamParser({
nested: true, // Emit nested objects (default: true)
autoParseNumbers: true,
// ... other CsvParserOptions
});
createReadStream('./large.csv')
.pipe(parser)
.on('data', (record) => console.log(record))
.on('end', () => console.log('Done'));
stringify(data: object[], options?: JsonToCsvOptions): stringConvert array of objects to CSV string.
writeFileSync(filePath: string, data: object[], options?: JsonToCsvOptions): voidWrite objects to CSV file synchronously.
writeFile(filePath: string, data: object[], options?: JsonToCsvOptions): Promise<void>Write objects to CSV file asynchronously.
import { JsonToCsv } from '@cerios/csv-nested-json';
const data = [
{ id: 1, user: { name: 'Alice', age: 30 }, tags: ['js', 'ts'] }
];
const csv = JsonToCsv.stringify(data, {
delimiter: ',',
quote: '"',
arrayMode: 'rows' // 'rows' (continuation rows) or 'json' (stringify arrays)
});
The library provides custom error classes for better error handling:
import {
CsvParseError,
CsvFileNotFoundError,
CsvValidationError,
CsvEncodingError
} from '@cerios/csv-nested-json';
try {
const result = CsvParser.parseFileSync('./data.csv', {
validationMode: 'error'
});
} catch (error) {
if (error instanceof CsvFileNotFoundError) {
console.error(`File not found: ${error.filePath}`);
} else if (error instanceof CsvValidationError) {
console.error(`Validation error at row ${error.row}`);
console.error(`Expected ${error.expectedColumns}, got ${error.actualColumns}`);
} else if (error instanceof CsvEncodingError) {
console.error(`Encoding error: ${error.encoding}`);
} else if (error instanceof CsvParseError) {
console.error(`Parse error at row ${error.row}, column ${error.column}`);
}
}
Records are grouped by the first column (identifier). When the first column is empty, the row is treated as a continuation of the previous group:
id,name,item
1,Alice,Book
,,Pen
,,Notebook
2,Bob,Laptop
Groups:
id=1 and the two continuation rowsid=2Column headers with dots create nested object structures:
user.profile.name,user.profile.age
Alice,30
Creates:
{
"user": {
"profile": {
"name": "Alice",
"age": "30"
}
}
}
When the same key path appears multiple times within a group, an array is automatically created:
id,contact.type,contact.value
1,email,alice@example.com
,,phone,555-1234
Creates:
{
"id": "1",
"contact": [
{ "type": "email", "value": "alice@example.com" },
{ "type": "phone", "value": "555-1234" }
]
}
Empty or null values are omitted from the output:
id,name,optional
1,Alice,
2,Bob,Value
Creates:
[
{ "id": "1", "name": "Alice" },
{ "id": "2", "name": "Bob", "optional": "Value" }
]
| Method | Best For | File Size | Blocking |
|---|---|---|---|
parseFileSync() | Scripts, small files | <10MB | Yes |
parseFile() | Web servers, medium files | 10MB-100MB | No |
parseString() | API responses, testing | Any (in-memory) | Yes |
parseStream() | Large files, memory efficiency | >100MB | No |
CsvStreamParser | Very large files, ETL pipelines | Any size | No |
// โ Manual parsing - tedious and error-prone
const fs = require('fs');
const data = fs.readFileSync('data.csv', 'utf-8');
const lines = data.split('\n');
const headers = lines[0].split(',');
const result = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
const obj = {};
for (let j = 0; j < headers.length; j++) {
const keys = headers[j].split('.');
let current = obj;
// Manually handle nesting...
// ... complex nested object logic
}
result.push(obj);
}
// โ
Simple, type-safe, and powerful
const result = CsvParser.parseFileSync('data.csv');
// โ
Automatic nested object creation
// โ
Automatic array detection
// โ
RFC 4180 compliant parsing
// โ
Flexible configuration options
The library is fully RFC 4180 compliant and supports:
"value, with, commas""He said ""Hello""" โ He said "Hello"id,name,description
1,Alice,"Product with, comma"
2,Bob,"Product with ""quotes"""
3,Charlie,"Multi-line
description here"
All of these are correctly parsed!
Full TypeScript support with comprehensive type definitions:
import {
CsvParser,
CsvStreamParser,
JsonToCsv,
CsvParserOptions,
CsvParseError,
CsvValidationError,
NestedObject
} from '@cerios/csv-nested-json';
// Generic type support
interface Person {
id: number;
name: string;
address: {
city: string;
zip: string;
};
}
const result = CsvParser.parseFileSync<Person>('people.csv', {
autoParseNumbers: true
});
// result is typed as Person[]
console.log(result[0].address.city);
// Options
type ValidationMode = 'ignore' | 'warn' | 'error';
type EmptyArrayBehavior = 'empty-array' | 'omit';
type NullRepresentation = 'null' | 'undefined' | 'empty-string' | 'omit';
type ArrayMode = 'rows' | 'json';
// Function types
type ValueTransformer = (value: unknown, header: string) => unknown;
type HeaderTransformer = (header: string) => string;
type RowFilter = (record: CsvRecord, rowIndex: number) => boolean;
// Data types
type CsvRecord = Record<string, string>;
type NestedObject = { [key: string]: NestedValue };
type NestedValue = string | number | boolean | Date | null | NestedObject | NestedValue[];
// Options interface
interface CsvParserOptions { /* ... */ }
Choose the Right Method:
parseFileSync() for small files in scriptsparseFile() for web servers and async workflowsparseString() for API responses and testingparseStream() for large filesCsvStreamParser for very large files or when you need to process records one at a timeUse Appropriate Validation Mode:
'ignore' when you trust the data source'warn' (default) during development'error' for strict validation in productionEnable Auto-Parsing When Appropriate:
const result = CsvParser.parseFileSync('./data.csv', {
autoParseNumbers: true,
autoParseBooleans: true,
autoParseDates: true
});
Handle Errors Gracefully:
import { CsvParseError, CsvValidationError } from '@cerios/csv-nested-json';
try {
const result = CsvParser.parseFileSync('./data.csv', {
validationMode: 'error'
});
} catch (error) {
if (error instanceof CsvValidationError) {
console.error(`Row ${error.row}: expected ${error.expectedColumns} columns`);
} else {
throw error;
}
}
Use Streaming for Large Files:
// โ
Good for very large files
const parser = new CsvStreamParser({ autoParseNumbers: true });
for await (const record of createReadStream('./huge.csv').pipe(parser)) {
await processRecord(record);
}
// โ May cause memory issues with large files
const result = CsvParser.parseFileSync('./huge.csv');
Use Row Filtering for Memory Efficiency:
// โ
Filter during parsing - uses less memory
const result = CsvParser.parseFileSync('./data.csv', {
rowFilter: (record) => record.status === 'active'
});
// โ Filter after parsing - loads everything into memory first
const all = CsvParser.parseFileSync('./data.csv');
const filtered = all.filter(r => r.status === 'active');
Specify Encoding for Non-UTF8 Files:
const result = await CsvParser.parseFile('./data.csv', {
encoding: 'latin1'
});
Use Consistent Column Headers:
headerTransformer for normalizationContributions are welcome! Please feel free to submit a Pull Request.
MIT ยฉ Ronald Veth - Cerios
FAQs
Parse CSV files into nested JSON objects with support for dot notation, arrays, and complex data structures
The npm package @cerios/csv-nested-json receives a total of 38 weekly downloads. As such, @cerios/csv-nested-json popularity was classified as not popular.
We found that @cerios/csv-nested-json demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.