@std/csv
Overview Jump to heading
Reads and writes comma-separated values (CSV) files.
Parsing CSV
import { parse } from "@std/csv/parse";
import { assertEquals } from "@std/assert";
const string = "a,b,c\nd,e,f";
// Parse as array of arrays (default)
assertEquals(parse(string, { skipFirstRow: false }), [["a", "b", "c"], ["d", "e", "f"]]);
// Parse csv file with headers into array of objects
assertEquals(parse(string, { skipFirstRow: true }), [{ a: "d", b: "e", c: "f" }]);
// Parse with custom column names
assertEquals(parse(string, { columns: ["x", "y", "z"] }), [
{ x: "a", y: "b", z: "c" },
{ x: "d", y: "e", z: "f" }
]);
// Parse tab-separated values
const tsvString = "name\tage\tcity\njohn\t30\tnew york\nmary\t25\tlos angeles";
assertEquals(parse(tsvString, { separator: "\t", skipFirstRow: true }), [
{ name: "john", age: "30", city: "new york" },
{ name: "mary", age: "25", city: "los angeles" }
]);
// Parse a CSV file which has comments
const csvWithComments = "# This is a comment\nname,age,city\n# Another comment\njohn,30,new york\nmary,25,los angeles";
assertEquals(parse(csvWithComments, { comment: "#", skipFirstRow: true }), [
{ name: "john", age: "30", city: "new york" },
{ name: "mary", age: "25", city: "los angeles" }
]);
Parsing CSV from a Stream
import { CsvParseStream } from "@std/csv/parse-stream";
import { assertEquals } from "@std/assert";
// Parse from a stream (useful for large files)
const source = ReadableStream.from([
"name,age,city\n",
"john,30,new york\n",
"mary,25,los angeles\n"
]);
const csvStream = source
.pipeThrough(new CsvParseStream({ skipFirstRow: true }));
const records = await Array.fromAsync(csvStream);
assertEquals(records, [
{ name: "john", age: "30", city: "new york" },
{ name: "mary", age: "25", city: "los angeles" }
]);
// Or process records one by one
// for await (const record of csvStream) {
// console.log(record);
// }
Stringifying Data to CSV
import { stringify } from "@std/csv/stringify";
import { assertEquals } from "@std/assert";
// Convert array of arrays to CSV
const arrayData = [["name", "age", "city"], ["john", "30", "new york"], ["mary", "25", "los angeles"]];
const csvString = stringify(arrayData);
assertEquals(csvString, "name,age,city\r\njohn,30,new york\r\nmary,25,los angeles\r\n");
// Convert array of objects to CSV
const objectData = [
{ name: "john", age: "30", city: "new york" },
{ name: "mary", age: "25", city: "los angeles" }
];
// When using an array of objects, you must specify columns to use
const customColumns = stringify(objectData, { columns: ["city", "name", "age"] });
assertEquals(customColumns, "city,name,age\r\nnew york,john,30\r\nlos angeles,mary,25\r\n");
Streaming Stringify Data to CSV
import { CsvStringifyStream } from "@std/csv/stringify-stream";
import { assertEquals } from "@std/assert";
async function writeCsvToTempFile(): Promise<string> {
const path = await Deno.makeTempFile();
using file = await Deno.open(path, { write: true });
const readable = ReadableStream.from([
{ id: 1, name: "one" },
{ id: 2, name: "two" },
{ id: 3, name: "three" },
]);
await readable
.pipeThrough(new CsvStringifyStream({ columns: ["id", "name"] }))
.pipeThrough(new TextEncoderStream())
.pipeTo(file.writable);
return path;
}
const path = await writeCsvToTempFile();
const content = await Deno.readTextFile(path);
assertEquals(content, "id,name\r\n1,one\r\n2,two\r\n3,three\r\n");
CSV Format Information
There are many kinds of CSV files; this module supports the format described in RFC 4180.
A csv file contains zero or more records of one or more fields per record. Each record is separated by the newline character. The final record may optionally be followed by a newline character.
field1,field2,field3
White space is considered part of a field.
Carriage returns before newline characters are silently removed.
Blank lines are ignored. A line with only whitespace characters (excluding the ending newline character) is not considered a blank line.
Fields which start and stop with the quote character " are called quoted-fields. The beginning and ending quote are not part of the field.
The source:
normal string,"quoted-field"
results in the fields
[`normal string`, `quoted-field`]
Within a quoted-field a quote character followed by a second quote character is considered a single quote.
"the ""word"" is true","a ""quoted-field"""
results in
[`the "word" is true`, `a "quoted-field"`]
Newlines and commas may be included in a quoted-field
"Multi-line
field","comma is ,"
results in
[`Multi-line
field`, `comma is ,`]
Add to your project Jump to heading
deno add jsr:@std/csv
See all symbols in @std/csv on
What is a CSV? Jump to heading
CSV (Comma-Separated Values) is a simple text format for storing tabular data, where each line represents a row and each value within the row is separated by a comma. It’s widely used for data exchange between applications, especially spreadsheets and databases.
When to use @std/csv Jump to heading
This package is great for reading and writing CSV files in your applications. It supports parsing CSV into arrays or objects, stringifying data back to CSV, and streaming for large files.
Tips Jump to heading
- Use
skipFirstRow: true
to treat the first row as headers. - For objects, specify
columns
when stringifying. - Prefer streaming parsers for multi-GB datasets.