Symlinks and Npm
Tags: javascript, webdev, productivity, beginners
Published: 2020-12-14 14:23:55

---
title: Symlinks and Npm
published: true
description: What is a symlink? How does it work? Why does it matter?
tags: JavaScript, webdev, productivity, beginners
cover_image: https://images.unsplash.com/photo-1416543974351-c28453497ef4?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1052&q=80
canonical_url: https://laurieontech.com/posts/symlinks/
---

Symlink is a phrase you'll hear a lot in relation to local development. But it applies in a number of situations and it's a helpful JavaScript concept to understand.

## What is a symlink

A symlink is a reference to a file or folder. Think of it like an alias. If I typically want to access `../../../dir/laurie.js`, I can use a symlink so that I only have to reference `laurie`.

In most cases, a symlink is operating as a shortcut. But technically the name could be longer than the path, so alias is more accurate. Then again, if you're making the path longer I'm not entirely sure why!

If that explanation doesn't work for you, [@chrisbiscardi](https://twitter.com/chrisbiscardi) explains them as "symlinks make things look like they're in one place when they're actually in another", which is a good one.

## It works on my machine

You can create a symlink in your local file system. So that you don't have to remember the file path to that random executable.

You can do that by running the `ln` command in your terminal.

```shell
ln -s /path/to/target.js linked-target.js
```

You can do the same thing with directories.

```shell
ln -s /this/is/a/nested/proj/ /proj/
```

Once you set a symbolic link, that information is available at that path in your filesystem.

Note that the link can be `name`, `name.js`, whatever you want. However, in most cases you'll see links set with the extension intact.

## Packages

Symlinks are incredibly powerful ways to provide shortcuts in your filesystem. So the question becomes, can you use them to alter other people's filesystem? The answer is, kinda!

### Npm

So how is this enabled? There are a few different ways. A `postinstall` script, or the `bin` field in your package.json file.

#### post-install

If you've read my [package.json post](https://laurieontech.com/posts/package-json/) you know that there are some reserved script keys. `postinstall` is one of those keys.

It's a lifecycle script and it runs after the package has been installed. Therefore, you could use it to define something like this:

```json
{
  "scripts": {
    "postinstall": "ln -s ../ ./node_modules/my-thing"
  }
}
```

With this symlink, a user can `require(my-thing)` and gain access to the root of the project.

#### bin

Going back to that [package.json post](https://laurieontech.com/posts/package-json/) again there is a section on `bin`. I talk about how it facilitates commands users can run directly with `npx`. And that's true! But it's all because of symlinks, which is the true power of the `bin` field.

The commands defined in `bin` are symlinks to executables. If a user runs the command using `npx`, the executable runs without having to install the package. But what if the user does install the package?

#### Local install

If a user installs your package in a project, the package gets downloaded into their `node_modules`. From then on, the symlink is pointing to a relative path inside `node_modules`. That means that a user can run the executable it points to, or reference it as an import, as long as they're in the original directory.

If they aren't, it won't work. Because `./node_modules` will no longer resolve.

#### Global install

Conversely, some packages are meant to be installed globally in your operating system, using a `-g` flag. When that happens, the symlinks are available globally, as they were in the `ln` local machine example.

This means that you can use the symlink to run that executable no matter where you are in the filesystem. It's globally available rather than being relative.

## And that's it

Symlinks are a powerful tool and learning about them helps us understand a lot about the command line tools and import paths we use.