Home / Writing / Building a Library with CSV in Eleventy
12 / 03 — 2021
348 words 1.8 min


On this website, and on many others I’ve seen, people like to track their reading lists. I thought it may be helpful to briefly outline the system I have set up with Eleventy to do this fairly seamlessly.

Data input

In my opinion, tracking data for books should be frictionless. I personally find the .csv format to be the best for most text-based data inputs, the JSON formatting Eleventy natively uses feels much slower to me. My input data is stored in the _data folder in Eleventy and looks like the following:

The Creative Habit,Twyla Tharp,★★,Read
Seeing With Fresh Eyes,Edward Tufte,★★★,Read
A Mathematician’s Apology,G.H. Hardy,★★★,Read
Sourdough,Robin Sloan,★★★,Reading
The Last Man Who Knew Everything,David Schwartz,★★★½,Reading

This is a great start but unfortunately Eleventy does not natively read the .csv file format.

CSV transformation

Using Node, we can install the csv-parse module with npm install csv-parse. Once installed, add the following .js script to your _data file:

const parse = require("csv-parse/lib/sync");
const fs = require("fs");

function readCSV() {
const input = fs.readFileSync("./src/site/_data/books.csv");
const records = parse(input, {
columns: true,
skip_empty_lines: true,
console.log(`${records.length} books found.`);
return records;

module.exports = function () {
const data = readCSV();
return data;

Note: Make sure here that your input filename matches that .csv in your _data folder.

This file creates a data format that Eleventy can reference now, using the filename as the reference. Let’s look at using this data to create a template.

Nunjucks template

Now that we have usable data for Eleventy to pull from, we can create templates using nunjucks markup. For example, something like {%- for book in booklist -%} will use the Javascript file you created (in this case, booklist.js) to create an entry for each line in the .csv file. You can use this to template a list like my reading page, which uses the following html:

{%- for book in booklist -%}
<td class="table-post">
<div class="date">

<span class="post-link"></span>
<td class="table-stats">
<span class="stats-number">

{%- endfor -%}


That’s it! I hope this proved useful for anyone looking to create a fairly straightforward but streamlined data entry process.