Keep Your OS Clean with $HOME/.local 
Tags: linux, bash, macos, node
Published: 2021-02-07 07:30:31

---
title: Keep Your OS Clean with $HOME/.local 
published: true
description: Installing unpackaged software outside of your home directory is problematic. Here is a better approach.
tags: linux, bash, macos, nodejs
cover_image: https://i.imgur.com/LeA42So.png
---

In a \*nix environment (Linux, MacOS, WSL), software without packages can sometimes install to global spaces by default. This is often undesirable, due to running unverified scripts as root, conflicts with other packages, and potentially breaking the software during an OS upgrade. Instead, these custom installs should be placed in your home directory. In my case, `$HOME` is `/home/fritzy` or `/Users/fritzy` on MacOS.

But where _in_ your $HOME? As the title implies, `$HOME/.local`.

This directory is a GNOME convention that other software has adopted as well. Similar to `/usr/local`, it is designated for custom or non-package installed software. The `.` at the beginning of the directory name has the added benefit of hiding the directory, preventing cluttering an often-used space.

## Setting up $HOME/.local

If it doesn't exist, go ahead and create it, along with a `bin` directory as your user. No special permissions are needed.

```bash
mkdir -p $HOME/.local/bin
```

Then, make sure that `$HOME/.local/bin` is in your $PATH, preferably with a higher priority than `/usr/bin`. 

For Linux Bash users do:

```bash
echo PATH=$HOME/local.bin:\$PATH >> $HOME/.bashrc
```

## Custom Installers

Now we can install some software. I wanted to install [Starship](https://starship.rs/), a cross-shell prompt in my WSL2 Ubuntu. The only documented way to install this is to install by directly executing a download -- questionable from a security perspective.

```bash
curl -fsSL https://starship.rs/install.sh | bash
```

Instead, I downloaded and inspected the script. I discovered a few things. By default, it would install to `/usr/bin`, a global space requiring root access. But there was good news; I found a command-line option to set the install directory.

```bash
curl  https://starship.rs/install.sh --output install.sh # download
chmod +x install.sh # make it executable
./install.sh -b $HOME/.local/bin # the -b option is what discovered
rm ./install.sh # don't need this anymore
```

I then followed the instructions for setting up Starship for Bash.

```bash
echo 'eval "$(starship init bash)"' >> $HOME/.bashrc
```

## Custom Compiled Installs (Node.js)

If you build custom software, you'll want to find the "prefix" option, and set it to `$HOME/.local`. When following build instructions, you should ignore anything that tells you to use `sudo` when installing; you won't need it with a prefix in your home directory, and doing so may cause problems later.

Let's clone [Node.js](https://nodejs.org), compile it, and install it to our `.local` prefix.

### Checking Out

```bash
cd ~/build # I use a build directory for custom compiling
git clone git@github.com:nodejs/node.git
cd node
```

### Updating Tags

```bash
git fetch --all --tags # update fetched branches and tags
git tag # lists tags
```

As an aside, if you want to sort tags with semver logic, you can update your git config.

```bash
git config --global tag.sort version:refname
```

### Checkout a Tag As a Branch

```
git checkout tags/v15.8.0 -b build-v15.8.0
```

### Configure and Compile

Now we can compile it.

```bash
./configure --prefix=$HOME/.local
make -j12 # number of hardware thread on my cpu
make install # sets everything up in your prefix directory
```

The first `make` line will take a bit, but hey, you look really busy and smart when you're compiling code.

Now when you run `node -V`, it'll show your newly install Node.js version. You also now have the added benefit of being able to install 'global' npm packages without sudo. You'll notice that you now have `include` `lib` and `share` directories in your `$HOME/.local`, just like you would with a `/usr/local` prefix.

You can get similar benefits of using [nvm](https://github.com/nvm-sh/nvm) without having to compile.

## Keep It Clean

Installing unpackaged software in your `$HOME/.local` directory is more secure, more stable across OS upgrades, and prevents unnecessary `root` usage going forward. It can take a bit of investigation with some software, but is worth having a cleaner install in the end. Ideally, the vast majority of your software simply uses OS supported packages, but now you have a plan for when it doesn't.

For you MacOS users, OS upgrades would regularly break Brew for me, but you can even [install Brew into your home directory](https://andrewjorgensen.com/post/install-homebrew-to-your-home-directory/).

---

__Please comment below, or send me your thoughts [on Twitter @fritzy](https://twitter.com/fritzy).__