Symlink shenanigans - node.js, npm, express and vagrant

Recently I was working on a new project on a virtual box set up through vagrant. For those of you who haven’t used it, vagrant is an amazing tool that makes it crazy-easy to set up and deploy uniform development environments on virtual servers. However, I ran in to a very frustrating issue when trying to install the node.js framework express through npm.

Node was set up and running fine, and I’d successfully gotten a few modules working by adding them to the dependencis list in package.json and running npm install. I then added express, so my dependencies list now looked like:

 "dependencies": {
    "aws-sdk": "0.9.x",
    "express": "3.x",
    "pg": "x"
  }

I ran npm install, then got hit with an error along the lines of:

error code EROFS
error errno 56

This error means the file system is read only. But I already managed to install two other modules in the same way on the same system! So what gives?

Symlink shenanigans

The issue is caused by the way express attempts to symlink binaries. One of the restrictions when using virtualbox is that symlinks can’t be created within shared folders. (My code was mounted from a shared folder on my local machine) This is discussed in a bit more detail on this github issue.

There are a wide variety of suggested fixes for this floating around on the net. One is to edit the vagrant config file to allow symlinks to be created, explained in more detail here. This one didn’t work for me, so my search went on, and eventually led me to the github issue linked above.

The issue resulted in a patch being added to npm which will install packages without forcing the symlinks. So, when running “npm install” on a virtual machine created through vagrant, run it as:

npm install --no-bin-link

This will install the dependencies listed in the packages.json file, whilst preventing npm from creating symlinks for any binaries the packages may contain.

Share This Article

Related Articles


A/B testing headlines on social media

A/B testing is a great way to determine the most compelling headline for an article, but is made difficult by the way social media networks cache link previews. What's the secret to effectively running A/B headline tests, and optimising engagement rates?

Lazy loading background images to improve load time performance

Lazy loading of images helps to radically speed up initial page load. Rich site designs often call for background images, which can't be lazily loaded in the same way. How can we keep our designs, while optimising for a fast initial load?

Font Subsetting - shrink down font files to speed up page loads

Fonts are one of the largest resources on any page after images, and can have a big impact on CLS when they vary in size from the underlying system font. Font subsetting allows us to radically shrink font file sizes, speed up initial page loads, and improve our page speed scores.

Calculating rolling averages with Laravel Collections

Rolling averages are perfect for smoothing out time-series data, helping you to gain insight from noisy graphs and tables. This new package adds first-class support to Laravel Collections for rolling average calculation.

Minimising Cumulative Layout Shift (CLS) When Loading Responsive Ads

Responsive ads are a great way to maximise publisher revenue from display ads. Not knowing the size of the ad to be served in advance can have a big impact on Cumulative Layout Shift (CLS), and, ultimately, Google rankings. How do we maximise revenue while minimising CLS impact?

More