node package manager
Love JavaScript? Your insights can make it even better. Take the 2017 JavaScript Ecosystem Survey »



Build Status Code Climate Test Coverage Dependency Status Download Status

Use the FeathersJS service interface to read and write data in the file system.


npm install feathers-fs --save


The feathers-js module lets you use the FeathersJS service interface methods to read and write JSON-able data in the file system. It creates .json files, by default, but is extendable to be able to read or write any text-based file format that is serializable to/from JSON or a JavaScript object literal. Here's a basic example:

const ffs = require('feathers-fs');
const jsonService = app.use('/json', ffs({root: 'src/services'});
const messageData = { test: true };
  path: 'messages/messages.json',
  data: messageData


service(options) -> FeathersService

Sets up the plugin with the provided options.

  • options {Object} - must contain a root param.
    • root {String} required - the root path for all files that will be read or written.
    • type {String} - the file type/extension that this service will handle. default: json. When creating a file, if a file extension is not provided, this will be appended.
    • cache {Boolean} - whether the require module cache should be used. default: false. By default, the require cache for the individual file will be cleared both before and after reading the file.

Service API

Two of the service methods are implemented:

create(data) -> Promise

Creates a file using the provided data.

  • data {Object} - must contain path and data attributes.
    • path {String} required - the full path, including file name. If an extension is not provided, the extension provided as options.type will automatically be appended.
    • data {Object|Array} required - The data to be written to the file. The create method returns a promise that resolves to the data that was written to file.

get(path, params) -> Promise

Reads a file from the provided path.

  • path {String} required - the full path, relative to the options.root of the file to be read.
  • params.cache {Boolean} - Whether or not this specific file lookup should use the require cache. Defaults to options.cache The get method returns a promise that resolves to the data that was read from the file.

Handling Other File Types

The service can be extended to handle file types other than .json. When you create an instance of the service class, all attributes passed in the options will be available at this.options. Generally, both of the following methods will need to be overridden:

readFromFile(path) -> promise

The readFromFile method is used to read the file at path and format it as an object literal.

  • path {String} - the full file path of the file to be read, including the options.root. It must return a promise that resolves to an object literal.

toFileString(data) -> promise

The toFileString method is used to convert the provided data into a string to be written to disk.

  • data {Object} - the object literal containing the data that will be formatted. It must return a promise that resolves to a string.

Example of Extending the Service for CSV

Here's a stubbed-out example of what extending a CSV service would look like.

const BaseService = require('feathers-fs').Service;
const fs = require('fs');
class CsvService extends BaseService {
  // Converts the CSV file to an object literal.
  readFromFile (path) {
    return new Promise((resolve, reject) => {
      // Use the path to read the file contents.
      fs.readFile(path, (error, data) => {
        if (err) {
          return reject(error)
        // Use a node package to convert the data to an object literal.
        let formattingOptions = {
          fields: this.options.fields
        let formatted = someCsvToJsonFunction(data, formattingOptions);
  // Converts an object literal to a string ready for storing to the file system.
  toFileString (data) {
    return new Promise((resolve, reject) => {
      // Use a node package to convert the data to a string.
      try {
        let formatted = someJsonToCsvFunction(data);
        return resolve(formatted);
      } catch (error) {
        return reject(error);
const serviceOptions = {
  root: 'src/services',
  type: 'csv',
  // Some CSV plugins require an array of fields.
  // The fields are available inside the override methods as shown above.
  fields: ['first', 'second', 'third']
const csvService = app.use('/json', new CsvService(serviceOptions);
// Notice how the field names match the ones in the `fields` array.
const tableData = {
  first: 'test1',
  second: 'test2',
  third: 'test3'
// Create the csv file.
  path: 'files/table-data.csv',
  data: tableData

Complete Example

Here's an example of a Feathers server that uses feathers-fs.

const feathers = require('feathers');
const rest = require('feathers-rest');
const hooks = require('feathers-hooks');
const bodyParser = require('body-parser');
const errorHandler = require('feathers-errors/handler');
const feathersFs = require('feathers-fs');
// Initialize the application
const app = feathers()
  // Needed for parsing bodies (login)
  .use(bodyParser.urlencoded({ extended: true }))
  // Initialize your feathers plugin
  .use('/json', feathersFs({
    root: 'src',
    type: 'json' // the default value.
const dataToStore = [
    to: 'marshall',
    from: 'marshall',
    body: 'Stop talking to that rubber ducky!'
  }, {
    to: 'marshall',
    from: 'marshall',
    body: `...unless you're rubber duck debugging.`
// Store the data at `/src/services/messages/messages.seed.json`
  path: '/services/messages/messages.seed.json', // path will be appended to the `root` path.
  data: dataToStore
// Retrieve the data at the provided path.
  .then(data => {
    assert.deepEqual(data, dataToStore) // --> true
console.log('Feathers app started on');


Copyright (c) 2016

Licensed under the MIT license.