CSV File-based Database
csv-db is a lightweight, file-based database for Node.js, initially designed as a teaching aid for workshops requiring a simple data persistence layer. It stores data in plain CSV files, using newlines for row separation and semicolons for field separation. The current stable version, 0.2.2 (last published over eight years ago), relies on Promises for asynchronous CRUD (Create, Read, Update, Delete) operations, a significant evolution from its initial synchronous implementation. Its primary differentiators are extreme simplicity and direct file storage, making it suitable for minimal persistence needs, proof-of-concept applications, or educational contexts where understanding basic data storage is key. It lacks advanced database features such as indexing, complex querying, or transaction management. Due to its age and lack of updates, its release cadence is effectively nonexistent.
Common errors
-
TypeError: CsvDb is not a constructor
cause Attempting to use `CsvDb` as a function or importing it incorrectly in an ESM context.fixEnsure you are using CommonJS `const CsvDb = require('csv-db');` and instantiating with `new CsvDb(...)`. -
Error: ENOENT: no such file or directory, open 'your-file.csv'
cause The specified CSV file path does not exist or is inaccessible.fixVerify the file path is correct and the Node.js process has read/write permissions for the file and directory. -
UnhandledPromiseRejectionWarning: Unhandled promise rejection.
cause An error occurred during a `csv-db` operation (e.g., file I/O), but the promise's `.catch()` method or second callback argument was not used.fixAlways chain a `.catch(err => console.error(err))` to `csv-db` promise calls or use `try/catch` with `async/await` to handle potential errors. -
Data appears corrupted or incorrectly parsed (e.g., entire row in one field).
cause The CSV file is not formatted with semicolons (`;`) as field separators, or headers do not match.fixEnsure the CSV file uses semicolons as delimiters. If providing column names in the constructor, make sure they match the order and number of fields in the CSV.
Warnings
- breaking The package transitioned from a synchronous API in its earliest versions to an asynchronous, Promise-based API. Code written for the synchronous version will break if run against version 0.2.2.
- gotcha This package has been abandoned for over eight years (last update v0.2.2). It is not actively maintained, may contain unpatched vulnerabilities, and does not support modern JavaScript features like ESM.
- gotcha As a file-based database, `csv-db` offers no inherent concurrency control, locking mechanisms, or ACID properties. Concurrent write operations from multiple processes or even multiple asynchronous operations within the same process can lead to data corruption or loss.
- gotcha The package uses semicolons (`;`) as the default field separator. Using a comma-separated (`,`) CSV file will result in incorrect parsing.
- gotcha The `update` method requires passing an object containing *all* field values for the row, not just the changed ones. Omitting fields will overwrite them with `undefined` or empty strings in the CSV.
Install
-
npm install csv-db -
yarn add csv-db -
pnpm add csv-db
Imports
- CsvDb
import CsvDb from 'csv-db';
const CsvDb = require('csv-db'); - CsvDb instance
const csvDb = CsvDb('input.csv', ['id', 'username']);const csvDb = new CsvDb('input.csv', ['id', 'username']);
Quickstart
const CsvDb = require('csv-db');
const fs = require('fs');
// Create a dummy CSV file for demonstration
const filePath = 'example.csv';
const initialData = '1;admin;secret;\n2;user;password;';
fs.writeFileSync(filePath, initialData);
const csvDb = new CsvDb(filePath, ['id', 'username', 'password']);
csvDb.get().then((data) => {
console.log('All data:', data);
// Expected output: [{ id: '1', username: 'admin', password: 'secret' }, { id: '2', username: 'user', password: 'password' }]
}).catch((err) => {
console.error('Error fetching all data:', err);
});
csvDb.get('1').then((data) => {
console.log('Data for ID 1:', data);
// Expected output: [{ id: '1', username: 'admin', password: 'secret' }]
}).catch((err) => {
console.error('Error fetching data by ID:', err);
});
// Clean up the dummy file
process.on('exit', () => {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
console.log(`Cleaned up ${filePath}`);
}
});