How to Convert JSON to CSV in JavaScript

You can use the json2csv library to quickly convert JSON to CSV in JavaScript. It is a robust utility that converts JSON to CSV with column titles and proper line endings, and is available as an NPM package.

import { parse } from 'json2csv';

const obj = [
  { firstName: 'Russell', lastName: 'Castillo', age: 23 },
  { firstName: 'Christy', lastName: 'Harper', age: 35 },
  { firstName: 'Eleanor', lastName: 'Mark', age: 26 },
];

const csv = parse(obj);

console.log(csv);

This code will have the following output:

"firstName","lastName","age"
"Russell","Castillo",23
"Christy","Harper",35
"Eleanor","Mark",26

What are JSON and CSV?

Let’s quickly go through these terms in case you’re not familiar with them.

JSON (JavaScript Object Notation) is a text format used to store and transport data based on JavaScript object syntax, and is commonly used to build RESTful APIs.

CSV (Comma-Separated Values) is a method of storing tabular data as text using comma-separated values (hence the name). Each record is stored as a new line, and each field in the record is separated with a character that’s usually a , (comma).

Install json2csv

Before using json2csv, we’ll need to install it in our project. We can do with the NPM or Yarn CLI.

npm i json2csv

# Yarn
yarn add json2csv

After installation, we’ll be able to import it into a JavaScript module, like this:

import { parse } from 'json2csv';

// CommonJS module
const { parse } = require('json2csv');

The parse() function

The parse() function is a convenience method provided by json2csv, and it has two parameters. The first is the JSON string to convert to CSV, and the second is an object.

const csv = parse(obj, { delimiter: ' ', header: false });

[Update] json2csv is now legacy

The json2csv library has now been split into smaller libraries that are now published to NPM independently. json2csv is still available on NPM, but the newer way to use its functionality is through the @json2csv/plainjs module.

So instead of this:

import { parse } from 'json2csv';

// ...

const csv = parse(obj, { delimiter: '|' });

You’ll install @json2csv/plainjs and write this:

import { Parser } from '@json2csv/plainjs';

// ...

const parser = new Parser({ delimiter: '|' });

const csv = parser.parse(obj);


Customize conversion of JSON to CSV

The object specifies various options that customize the conversion.

One such option is delimeter, which indicates the character used to separate the columns in the CSV string. A comma is used if delimeter is not set.

For example, this:

import { parse } from 'json2csv';

const obj = [
  { firstName: 'Russell', lastName: 'Castillo', age: 23 },
  { firstName: 'Christy', lastName: 'Harper', age: 35 },
  { firstName: 'Eleanor', lastName: 'Mark', age: 26 },
];

const csv = parse(obj, { delimiter: '|' });

console.log(csv);

produces the following CSV string:

"firstName"|"lastName"|"age"
"Russell"|"Castillo"|23
"Christy"|"Harper"|35
"Eleanor"|"Mark"|26

We also have header, which determines whether or not the CSV string will contain a title row. It’s true by default.

const csv = parse(obj, { delimiter: '|', header: false });

CSV output:

"Russell"|"Castillo"|23
"Christy"|"Harper"|35
"Eleanor"|"Mark"|26

There’s also the quote option, which sets the quote used around column names. It’s " (double quote) by default, we can remove quotes by passing an ('') empty string to quote:

const csv = parse(obj, { quote: '' });
firstName,lastName,age
Russell,Castillo,23
Christy,Harper,35
Eleanor,Mark,26

Native conversion of JSON to CSV in JavaScript

Here’s how we can easily convert JSON to CSV in JavaScript:

function jsonToCsv(items) {
  const header = Object.keys(items[0]);

  const headerString = header.join(',');

  // handle null or undefined values here
  const replacer = (key, value) => value ?? '';

  const rowItems = items.map((row) =>
    header
      .map((fieldName) => JSON.stringify(row[fieldName], replacer))
      .join(',')
  );

  // join header and body, and break into separate lines
  const csv = [headerString, ...rowItems].join('\r\n');

  return csv;
}

const obj = [
  { color: 'red', maxSpeed: 120, age: 2 },
  { color: 'blue', maxSpeed: 100, age: 3 },
  { color: 'green', maxSpeed: 130, age: 2 },
];

const csv = jsonToCsv(obj);

console.log(csv);

This will be the CSV output:

color,maxSpeed,age
"red",120,2
"blue",100,3
"green",130,2

How it works

We created a reusable jsonToCsv() function to let us convert multiple JSON strings to CSV. It takes an array that contains objects. Each object will take up one row in the CSV output.

The first we do in this function is to get all the keys that will be used for the CSV header. We expect all objects in the array to have the same keys, so we use the Object.keys() method to extract the keys from the first object item into an array.

const obj = [
  { color: 'red', maxSpeed: 120, age: 2 },
  { color: 'blue', maxSpeed: 100, age: 3 },
  { color: 'green', maxSpeed: 130, age: 2 },
];

// { color: 'red', maxSpeed: 120, age: 2 }
console.log(obj[0]);

// [ 'color', 'maxSpeed', 'age' ]
console.log(Object.keys(obj[0]));

After getting the keys, we call the join() method on the array to concatenate all the elements into a CSV header string.

const header = ['color', 'maxSpeed', 'age'];

const headerString = arr.join(',');

console.log(headerString); // color,maxSpeed,age

Next, we create a function that will be passed as a callback to the replacer parameter of the JSON.stringify() function. This function will handle undefined or null property values of the objects in the JSON array.

const obj = { prop1: 'Earth', prop2: undefined };

// replace undefined property values with empty string ('')
const replacer = (key, value) => value ?? '';

const str = JSON.stringify(obj, replacer);

// {"prop1":"Earth","prop2":""}
console.log(str);

We then use the Array map() method to get the property values from each object. map() takes a callback function that is called on each array element to return a transformation.

This callback uses the header array to get all the keys of each object. With another call to map(), it goes through each key, gets the corresponding value for that key in the object, and converts it to a string using JSON.stringify().

This inner call to map() eventually results in an array of all the stringified property values of the current object in the array.

const header = ['color', 'maxSpeed', 'age'];

const row = { color: 'red', maxSpeed: 120, age: 2 };

const replacer = (key, value) => value ?? '';

const rowItem = header.map((fieldName) =>
  JSON.stringify(row[fieldName], replacer)
);

// array of stringified property values
console.log(rowItem); // [ '"red"', '120', '2' ]

After the object has been transformed into a property value array, join() is then used to convert the array to a CSV row.

['"red"', '120', '2'].join(',') // -> "red",120,2

So this transformation happens for every object in the JSON array to generate a list of CSV rows, stored in the rowItems variable in our original example.

To generate the final CSV output, we combine the headerString and the rowItems into one array, making use of the spread syntax (...).

const headerString = ['color', 'maxSpeed', 'age'];

const rowItems = ['"red",120,2', '"blue",100,3', '"green",130,2'];

[headerString, ...rowItems];
/*
Output ->
[
  [ 'color', 'maxSpeed', 'age' ],
  '"red",120,2',
  '"blue",100,3',
  '"green",130,2'
]
 */

Then we call join() on this array with the '\r\n' string as a separator, to create a string with the CSV header and each CSV row in a separate line.

const headerString = ['color', 'maxSpeed', 'age'];

const rowItems = ['"red",120,2', '"blue",100,3', '"green",130,2'];

console.log([headerString, ...rowItems].join('\r\n'));
/*
color,maxSpeed,age
"red",120,2
"blue",100,3
"green",130,2
 */


11 Amazing New JavaScript Features in ES13

This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.

11 Amazing New JavaScript Features in ES13

Sign up and receive a free copy immediately.

Leave a Comment

Your email address will not be published. Required fields are marked *