DEV Community 👩‍💻👨‍💻

Cover image for My terminal is procrastinating 🙄
Omri Lotan
Omri Lotan

Posted on

My terminal is procrastinating 🙄

Reduce terminal instance boot time

I am a performance and observability enthusiast. I am also extremely impatient. This combination of traits drives me to find ways to accelerate any process that takes even a tiny bit longer than absolute necessary.

I made my terminal boot procrastinate for efficiency!

I want my terminal to perform operations only when they are required. I already measure everything that my bashrc runs. So I picked the scripts from my bashrc who take the longest to run, and turned them into on-demand commands.


This one was easy.

thefuck is brilliant in correcting your previous console command, but the setup takes me nearly 700ms on average. Unthinkable!

Instead of setting it up up front when terminal instance boots up - I prefer to set it up when I need it. So I set up this idempotent function:

function fuck {
    eval "$(thefuck --alias)"
    eval "fuck $@"
Enter fullscreen mode Exit fullscreen mode

First time I call fuck in an instance it performs the following operations:

  1. Setup thefuck with fuck alias (overrides this function).
  2. Trigger fuck with all the passed in arguments.

So initial setup time is reduced to 20ms and usage gets the hit of 700ms later, on demand. Second call will not take that hit.


Now, nvm I use more often - but it cost me over a whopping 1.5 seconds. It also is a bit trickier - because it loads up an environment, not just a command.

I chose to add this idem potency to the four major commands I use: node, npm, npx, nvm - but you can easily add more.

Each one of the commands is set up to:

  1. Unset all commands in the list (plus the nvm_load command)
  2. Load up nvm
  3. Call the original command with all arguments
if [ -f ".nvmrc" ]; then
    # Load NVM if needed
    source "$HOME/.nvm/"
    # Set up NVM loaders
    nodecommands=(nvm npm npx node)
    function nvm_load {
        # Unset all node command decorators
        for nodecommand in "${nodecommands[@]}"; do
            eval "unset -f ${nodecommand}"
        unset -f nvm_load
        if [[ -s "$HOME/.nvm/" ]]; then
            echo "Loading NVM"
            source "$HOME/.nvm/"
            echo "Can't find nvm script"
    # All node commands should load NVM first
    for nodecommand in "${nodecommands[@]}"; do
        eval "function ${nodecommand} { nvm_load; ${nodecommand} \$@; }"
Enter fullscreen mode Exit fullscreen mode

The draw back is that globally installed NPM packages won't work until you explicitly call one of these method names. On the other hand - you can add anything to the list if there's a command you use often and want to join the party (yarn etc).

There you go, NVM reduced to 80ms and will only take up your time when needed.

Now that NVM is not included by default, we also need to set it up when entering a directory that contains a .nvmrc file.

cd() {
    : ${dir:=~}

    builtin cd $dir
    if [ -f ".nvmrc" ]; then
        nvm use
Enter fullscreen mode Exit fullscreen mode

What do you think? Anything slowing you down loading up a terminal instance?

Top comments (1)

ealush profile image
Evyatar Alush

Regarding nvm, you might consider taking a look at fnm. They seem to improve speed significantly.

Take a look at this:


Go to your customization settings to nudge your home feed to show content more relevant to your developer experience level. 🛠