Symlink Is the Answer

The modern Front End workflow is full of tools and things. Processing source code and assets with Gulp, Grunt or perhaps you’re a rebel and use npm. Sass or Less generates your stylesheets. Your front end dependencies are managed by Bower.

It took me a long time before using Bower. Some dependencies don’t have a minified version bundled. Some dependencies are needed elsewhere, like I like to include normalize.css in a Sass file. I desired full control, and Bower wouldn’t give it.

One day, I came across symlinks and I immediately remembered the problem I was having with Bower. Could this be what I was looking for?

What’s a Symlink?

A symbolic link, or symlink, is a reference to another file or folder. When a symlink is read, the file or folder it references to is read instead. Basically shortcuts to another file or folder.

Soft links are shortcuts to other files. When the original file is deleted, your soft link will stop working. Hard links refer directly to the data (inode) of a file, basically acting as an alias. When the other file is deleted, the hard link will keep working. Symlinks are usually soft links.

Creating symlinks is somewhat dodgy. You will have to enter Terminal and enter:

ln -s path/to/target.file path/to/symlink.file

Windows-users will have to enter either of the following lines in command prompt:

# For files, use the /H prefix
mklink /H path/to/symlink.file path/to/target.file
# For directories, use the /D prefix
mklink /D path/to/symlink path/to/target

In the rest of this article, I will use the former command.

Personally, I found it a good practise to change the current directory to the symlink folder first, so I can set a relative link:

cd my/symlink/folder
ln -s ../../target.file symlink.file

Straightforward Links

Want to put a script elsewhere, without breaking dependencies? Symlink to the rescue!

# Install jQuery
bower install jquery
# Go to symlink folder
cd my-project/src/js/vendors
# Create symlink
ln -s ../../../bower_components/jquery/dist/jquery.js jquery.js

Can’t Import CSS in SCSS. Or Can You?

I’m not a fan of ports, so even though a Sass (SCSS) port of normalize.css is available, I’d rather use the original. With symlink magic, normalize.css can be converted to _normalize.scss.

# Install normalize.css normally (no pun intended)
bower install normalize.css
# Go to folder where I want to put my symlink
cd my-project/src/sass/vendors
# Create symlink - notice the changed filename and extension?
ln -s ../../../bower_components/normalize.css/normalize.css _normalize.scss

Now I can import _normalize.scss like any other SCSS file.

@import 'vendors/normalize';

Symlink, our saviour.

One or Many?

Sometimes, I need more than just file. The bootstrap-sass project has all partial files in assets/stylesheets/bootstrap. I want to access all of them.

# Install dependency
bower install bootstrap-sass
# Go to the symlink folder
cd my-project/src/sass/vendors
# Create symlink to the bootstrap folder
ln -s ../../../bower_components/bootstrap-sass/assets/stylesheets/bootstrap bootstrap

By linking the partials directory, we can access each partial independently, allowing us to selectively choose which partials we want. Super useful to void clutter and optimise things.

@import 'vendors/bootstrap/variables';
@import 'vendors/bootstrap/normalize';
@import 'vendors/bootstrap/grid';

You can link the fonts, images and scripts elsewhere, considering you may need those in your project as well.

Praise the symlinks!


It doesn’t matter if npm and Bower makes a complete mess of node_modules and bower_components. With symlinks, can cherrypick what we need and where we want it, creating an organised, structured, tidy place for our source files. Symlinks are awesome!