Convert CSV file to JSON https://www.npmjs.com/package/convert-csv-to-json
This project is not dependent on others packages or libraries, and supports both synchronous and Promise-based asynchronous APIs.
Follow me, and consider starring the project to show your :heart: and support.
Converts csv files to JSON files with Node.js. Supports both synchronous operations and Promise-based asynchronous operations, allowing integration with modern async/await patterns.
Give an input file like:
| first_name | last_name | gender | age | zip | registered | |
|---|---|---|---|---|---|---|
| Constantin | Langsdon | clangsdon0@hc360.com | Male | 96 | 123 | true |
| Norah | Raison | nraison1@wired.com | Female | 32 | false |
e.g. :
first_name;last_name;email;gender;age;zip;registered
Constantin;Langsdon;clangsdon0@hc360.com;Male;96;123;true
Norah;Raison;nraison1@wired.com;Female;32;;false
will generate:
[
{
"first_name": "Constantin",
"last_name": "Langsdon",
"email": "clangsdon0@hc360.com",
"gender": "Male",
"age": "96",
"zip": "123",
"registered": "true"
},
{
"first_name": "Norah",
"last_name": "Raison",
"email": "nraison1@wired.com",
"gender": "Female",
"age": "32",
"zip": "",
"registered": "false"
}
]
This package is compatible with and
.
NPM (see Installing Npm).
Go to NPM package convert-csv-to-json.
Install package in your package.json
$ npm install convert-csv-to-json --save
Install package on your machine
$ npm install -g convert-csv-to-json
let csvToJson = require('convert-csv-to-json');
let fileInputName = 'myInputFile.csv';
let fileOutputName = 'myOutputFile.json';
csvToJson.generateJsonFileFromCsv(fileInputName,fileOutputName);
let csvToJson = require('convert-csv-to-json');
let json = csvToJson.getJsonFromCsv("myInputFile.csv");
for(let i=0; i<json.length;i++){
console.log(json[i]);
}
firstName;lastName;email;gender;age;birth;sons
Constantin;Langsdon;clangsdon0@hc360.com;Male;96;10.02.1965;*diego,marek,dries*
Given the above CSV example, to generate a JSON Object with properties that contains sub Array, like the property sons
with the values diego,marek,dries you have to call the function parseSubArray(delimiter, separator) .
To generate the JSON Object with sub array from the above CSV example:
csvToJson.parseSubArray('*',',')
.getJsonFromCsv('myInputFile.csv');
The result will be:
[
{
"firstName": "Constantin",
"lastName": "Langsdon",
"email": "clangsdon0@hc360.com",
"gender": "Male",
"age": "96",
"birth": "10.02.1965",
"sons": ["diego","marek","dries"]
}
]
A field delimiter is needed to split the parsed values. As default the field delimiter is the semicolon (;), this means that during the parsing when a semicolon (;) is matched a new JSON entry is created.
In case your CSV file has defined another field delimiter you have to call the function fieldDelimiter(myDelimiter) and pass it as parameter the field delimiter.
E.g. if your field delimiter is the comma , then:
csvToJson.fieldDelimiter(',')
.getJsonFromCsv(fileInputName);
The content of the field header is cut off at the beginning and end of the string. E.g. “ Last Name “ -> “Last Name”.
Use the method trimHeaderFieldWhiteSpace(true) to remove the whitespaces in an header field (E.g. “ Last Name “ -> “LastName”):
csvToJson.trimHeaderFieldWhiteSpace(true)
.getJsonFromCsv(fileInputName);
To be able to parse correctly fields wrapped in quote, like the last_name in the first row in the following example:
| first_name | last_name | |
|---|---|---|
| Constantin | “Langsdon,Nandson,Gangson” | clangsdon0@hc360.com |
you need to activate the support quoted fields feature:
csvToJson.supportQuotedField(true)
.getJsonFromCsv(fileInputName);
The result will be:
[
{
"firstName": "Constantin",
"lastName": "Langsdon,Nandson,Gangson",
"email": "clangsdon0@hc360.com"
}
]
If the header is not on the first line you can define the header index like:
csvToJson.indexHeader(3)
.getJsonFromCsv(fileInputName);
Empty rows are ignored and not parsed.
The formatValueByType() function intelligently converts string values to their appropriate types while preserving data integrity. To enable automatic type conversion:
csvToJson.formatValueByType()
.getJsonFromCsv(fileInputName);
This conversion follows these rules:
For example:
{
"normalInteger": 42, // Converted to number
"decimal": 3.14, // Converted to number
"leadingZeros": "0012345", // Kept as string to preserve leading zeros
"largeNumber": "9007199254740992" // Kept as string to preserve precision
}
Case-insensitive “true” or “false” strings are converted to boolean values:
{
"registered": true, // From "true" or "TRUE" or "True"
"active": false // From "false" or "FALSE" or "False"
}
Input CSV:
first_name;last_name;email;gender;age;id;zip;registered
Constantin;Langsdon;clangsdon0@hc360.com;Male;96;00123;123;true
Norah;Raison;nraison1@wired.com;Female;32;987;00456;FALSE
Output JSON:
[
{
"first_name": "Constantin",
"last_name": "Langsdon",
"email": "clangsdon0@hc360.com",
"gender": "Male",
"age": 96,
"id": "00123", // Preserved leading zeros
"zip": 123, // Converted to number
"registered": true // Converted to boolean
},
{
"first_name": "Norah",
"last_name": "Raison",
"email": "nraison1@wired.com",
"gender": "Female",
"age": 32,
"id": "987",
"zip": "00456", // Preserved leading zeros
"registered": false // Case-insensitive boolean conversion
}
]
You can read and decode files with the following encoding:
csvToJson.utf8Encoding()
.getJsonFromCsv(fileInputName);
csvToJson.ucs2Encoding()
.getJsonFromCsv(fileInputName);
csvToJson.utf16leEncoding()
.getJsonFromCsv(fileInputName);
csvToJson.latin1Encoding()
.getJsonFromCsv(fileInputName);
csvToJson.asciiEncoding()
.getJsonFromCsv(fileInputName);
csvToJson.base64Encoding()
.getJsonFromCsv(fileInputName);
csvToJson.hexEncoding()
.getJsonFromCsv(fileInputName);
If you have CSV content as a string (for example, from an API response or test data), you can parse it directly without writing to a file:
// Parse CSV string to array of objects
let csvString = 'firstName;lastName\nJohn;Doe\nJane;Smith';
let jsonArray = csvToJson.csvStringToJson(csvString);
// Output: [{"firstName":"John","lastName":"Doe"},{"firstName":"Jane","lastName":"Smith"}]
// Parse CSV string to JSON string (validated)
let jsonString = csvToJson.csvStringToJsonStringified(csvString);
// Output: "[\n {\n \"firstName\": \"John\",\n \"lastName\": \"Doe\"\n },\n {\n \"firstName\": \"Jane\",\n \"lastName\": \"Smith\"\n }\n]"
Both methods support all configuration options through the chaining pattern:
let jsonArray = csvToJson
.fieldDelimiter(',')
.formatValueByType()
.csvStringToJson(csvString);
This library provides a Promise-based async API that’s perfect for modern Node.js applications. For a detailed migration guide from sync to async API, see MIGRATION.md.
// Using Promises csvToJson.getJsonFromCsvAsync(‘input.csv’) .then(json => console.log(json)) .catch(err => console.error(‘Error:’, err));
// Using async/await async function convertCsv() { try { const json = await csvToJson.getJsonFromCsvAsync(‘input.csv’); console.log(json); } catch (err) { console.error(‘Error:’, err); } }
2. Generate JSON file from CSV:
```js
// Using async/await with chain configuration
async function convertAndSave() {
await csvToJson
.fieldDelimiter(',')
.formatValueByType()
.generateJsonFileFromCsvAsync('input.csv', 'output.json');
}
Process CSV data from memory or network sources:
// Example: Processing CSV from an API
async function processCsvFromApi() {
const response = await fetch('https://api.example.com/data.csv');
const csvText = await response.text();
const json = await csvToJson
.formatValueByType()
.getJsonFromCsvAsync(csvText, { raw: true });
return json;
}
For large files, use streaming to manage memory efficiently:
const { createReadStream } = require('fs');
const { createInterface } = require('readline');
async function* processLargeFile(filePath) {
const fileStream = createReadStream(filePath);
const rl = createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
yield await csvToJson.getJsonFromCsvAsync(line, { raw: true });
}
}
// Usage
async function processData() {
for await (const record of processLargeFile('large.csv')) {
await saveToDatabase(record);
}
}
Implement robust error handling with retries:
async function processWithRetry(filePath, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const json = await csvToJson
.formatValueByType()
.getJsonFromCsvAsync(filePath);
return json;
} catch (err) {
if (i === maxRetries - 1) throw err;
// Exponential backoff
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, i) * 1000)
);
}
}
}
Process multiple files efficiently:
async function batchProcess(files, batchSize = 3) {
const results = new Map();
for (let i = 0; i < files.length; i += batchSize) {
const batch = files.slice(i, i + batchSize);
const processed = await Promise.all(
batch.map(async file => {
const json = await csvToJson.getJsonFromCsvAsync(file);
return [file, json];
})
);
processed.forEach(([file, json]) => results.set(file, json));
}
return results;
}
// Usage
const files = ['data1.csv', 'data2.csv', 'data3.csv', 'data4.csv'];
const results = await batchProcess(files, 2);
The exposed API is implemented with the Method Chaining Pattern, which means that multiple methods can be chained. This pattern works with both synchronous and asynchronous methods:
const csvToJson = require('convert-csv-to-json');
// Chain configuration methods with sync operation
const json = csvToJson
.fieldDelimiter(',')
.formatValueByType()
.parseSubArray("*", ',')
.supportQuotedField(true)
.getJsonFromCsv('myInputFile.csv');
// Chain with file generation
csvToJson
.fieldDelimiter(';')
.utf8Encoding()
.formatValueByType()
.generateJsonFileFromCsv('input.csv', 'output.json');
// Chain with string parsing
const jsonArray = csvToJson
.fieldDelimiter(',')
.trimHeaderFieldWhiteSpace(true)
.csvStringToJson('name,age\nJohn,30\nJane,25');
const csvToJson = require('convert-csv-to-json');
// Using async/await
async function processCSV() {
// Chain configuration methods with async operation
const json = await csvToJson
.fieldDelimiter(',')
.formatValueByType()
.parseSubArray("*", ',')
.supportQuotedField(true)
.getJsonFromCsvAsync('myInputFile.csv');
// Chain with async file generation
await csvToJson
.fieldDelimiter(';')
.utf8Encoding()
.formatValueByType()
.generateJsonFileFromCsvAsync('input.csv', 'output.json');
}
// Using Promises
csvToJson
.fieldDelimiter(',')
.formatValueByType()
.getJsonFromCsvAsync('input.csv')
.then(json => console.log(json))
.catch(err => console.error('Error:', err));
All configuration methods can be chained in any order before calling the final operation method (like getJsonFromCsv, getJsonFromCsvAsync, etc.). The configuration will be applied in the order it is chained.
Here are some common use cases and how to implement them:
const https = require('https');
async function processRemoteCsv(url) {
const csvData = await new Promise((resolve, reject) => {
https.get(url, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => resolve(data));
res.on('error', reject);
});
});
return csvToJson.getJsonFromCsvAsync(csvData, { raw: true });
}
async function batchProcess(files) {
const results = new Map();
// Process in chunks of 3 files at a time
for (let i = 0; i < files.length; i += 3) {
const chunk = files.slice(i, i + 3);
const processed = await Promise.all(
chunk.map(async file => {
const json = await csvToJson.getJsonFromCsvAsync(file);
return [file, json];
})
);
processed.forEach(([file, json]) => results.set(file, json));
}
return results;
}
async function transformData(csvFile) {
// Step 1: Parse CSV
const json = await csvToJson
.formatValueByType()
.getJsonFromCsvAsync(csvFile);
// Step 2: Transform data
const transformed = json.map(record => ({
id: record.id,
fullName: `${record.firstName} ${record.lastName}`,
age: Number(record.age),
isAdult: Number(record.age) >= 18,
email: record.email.toLowerCase()
}));
// Step 3: Filter invalid records
return transformed.filter(record =>
record.id &&
record.fullName.length > 0 &&
!isNaN(record.age)
);
}
async function processWithLogging(file) {
const logger = {
info: (msg) => console.log(`[INFO] ${msg}`),
error: (msg, err) => console.error(`[ERROR] ${msg}`, err)
};
try {
logger.info(`Starting processing ${file}`);
const startTime = Date.now();
const json = await csvToJson.getJsonFromCsvAsync(file);
const duration = Date.now() - startTime;
logger.info(`Processed ${file} in ${duration}ms`);
return json;
} catch (err) {
logger.error(`Failed to process ${file}`, err);
throw err;
}
}
Here are solutions to common issues you might encounter:
If you’re processing large CSV files and encountering memory issues:
// Instead of loading the entire file
const json = await csvToJson.getJsonFromCsvAsync('large.csv'); // ❌
// Use streaming with async iteration
for await (const record of processLargeCsv('large.csv')) { // ✅
// Process one record at a time
await processRecord(record);
}
csvToJson
.supportQuotedField(true) // Enable quoted field support
.getJsonFromCsvAsync(file);
csvToJson
.fieldDelimiter(';') // Change delimiter
.getJsonFromCsvAsync(file);
csvToJson
.encoding('utf8') // Specify encoding
.getJsonFromCsvAsync(file);
// Use parallel processing with limits async function processWithLimit(files, limit = 3) { const results = []; for (let i = 0; i < files.length; i += limit) { const chunk = files.slice(i, i + limit); const chunkResults = await Promise.all( chunk.map(file => csvToJson.getJsonFromCsvAsync(file)) ); results.push(…chunkResults); } return results; } // ✅
2. **Memory Usage**:
```js
// Clear references when done
async function processWithCleanup(file) {
let json;
try {
json = await csvToJson.getJsonFromCsvAsync(file);
return await processData(json);
} finally {
json = null; // Clear reference
}
}
If you’re using TypeScript and encounter type issues:
// Define custom types for your CSV structure
interface MyCsvRecord {
id: number;
name: string;
age?: number;
}
// Use type assertion
const json = await csvToJson.getJsonFromCsvAsync<MyCsvRecord>('data.csv');
npm install
npm test
npm run test-debug
This repository uses the GitHub Action iuccio/npm-semantic-publish-action@latest to publish the npm packeges. Pushing on the master branch, depending on the git message, an new version will always be released. If the commit message contains the keyword:
CSVtoJSON is licensed under the MIT License.
Just if you want to support this repository: