πŸš€ Fast and simple Node.js version manager, built in Rust

Overview

Fast Node Manager (fnm) Amount of downloads GitHub Actions workflow status

πŸš€ Fast and simple Node.js version manager, built in Rust

Blazing fast!

Features

🌎 Cross-platform support (macOS, Windows, Linux)

✨ Single file, easy installation, instant startup

πŸš€ Built with speed in mind

πŸ€” Works with .node-version and .nvmrc files

Installation

Using a script (macOS/Linux)

For bash, zsh and fish shells, there's an automatic installation script:

curl -fsSL https://fnm.vercel.app/install | bash

Upgrade

On macOS, it is as simple as brew upgrade fnm.

On other operating systems, upgrading fnm is almost the same as installing it. To prevent duplication in your shell config file add --skip-shell to install command.

Parameters

--install-dir

Set a custom directory for fnm to be installed. The default is $HOME/.fnm.

--skip-shell

Skip appending shell specific loader to shell config file, based on the current user shell, defined in $SHELL. e.g. for Bash, $HOME/.bashrc. $HOME/.zshrc for Zsh. For Fish - $HOME/.config/fish/conf.d/fnm.fish

--force-install

macOS installations using the installation script are deprecated in favor of the Homebrew formula, but this forces the script to install using it anyway.

Example:

curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir "./.fnm" --skip-shell

Manually

Using Homebrew (macOS/Linux)

brew install fnm

Then, set up your shell for fnm

Using Scoop (Windows)

scoop install fnm

Then, set up your shell for fnm

Using Chocolatey (Windows)

choco install fnm

Then, set up your shell for fnm

Using Cargo (Linux/macOS/Windows)

cargo install fnm

Then, set up your shell for fnm

Using a release binary (Linux/macOS/Windows)

  • Download the latest release binary for your system
  • Make it available globally on PATH environment variable
  • Configure your shell profile:

Removing

To remove fnm ( 😒 ), just delete the .fnm folder in your home directory. You should also edit your shell configuration to remove any references to fnm (ie. read Shell Setup, and do the opposite).

Completions

fnm ships its completions with the binary:

fnm completions --shell <SHELL>

Where <SHELL> can be one of the supported shells:

  • bash
  • zsh
  • fish
  • powershell

Please follow your shell instructions to install them.

Shell Setup

fnm needs to run some shell commands before you can start using it. This is done by evaluating the output of fnm env. Check out the following guides for the shell you use:

Bash

add the following to your .bashrc profile:

eval "$(fnm env)"

Zsh

add the following to your .zshrc profile:

eval "$(fnm env)"

Fish shell

create ~/.config/fish/conf.d/fnm.fish add this line to it:

fnm env | source

PowerShell

Add the following to the end of your profile file:

fnm env --use-on-cd | Out-String | Invoke-Expression
  • On Windows, the profile is located at ~\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 or $PROFILE
  • For macOS/Linux, the profile is located at ~/.config/powershell/Microsoft.PowerShell_profile.ps1

Windows Command Prompt aka Batch aka WinCMD

fnm is also supported but is not entirely covered. You can set up a startup script and append the following line:

FOR /f "tokens=*" %i IN ('fnm env --use-on-cd') DO CALL %i

⚠️ If you get the error i was unexpected at this time, please make a .cmd file as suggested by the first step in the Usage with Cmder secton add it's path to the AutoRun registry key.

Usage with Cmder

Usage is very similar to the normal WinCMD install, apart for a few tweaks to allow being called from the cmder startup script. The example assumes that the CMDER_ROOT environment variable is set to the root directory of your Cmder installation.
Then you can do something like this:

  • Make a .cmd file to invoke it
:: %CMDER_ROOT%\bin\fnm_init.cmd
@echo off
FOR /f "tokens=*" %%z IN ('fnm env --use-on-cd') DO CALL %%z
  • Add it to the startup script
:: %CMDER_ROOT%\config\user_profile.cmd
call "%CMDER_ROOT%\bin\fnm_init.cmd"

You can replace %CMDER_ROOT% with any other convenient path too.

Usage

See the available commands for an extended usage documentation

Contributing

PRs welcome πŸŽ‰

Developing:

# Install Rust
git clone https://github.com/Schniz/fnm.git
cd fnm/
cargo build

Running Binary:

cargo run -- --help # Will behave like `fnm --help`

Running Tests:

cargo test
Comments
  • fnm current version reset on sleep / lock / stale terminal

    fnm current version reset on sleep / lock / stale terminal

    Since I installed the latest fnm to try the new recursive version strategy I have the following problem:

    When I lock my mac and put it into sleep for some time, my current shell sessions (including vscode) cannot find node & npx anymore. I think the symlink is getting cleaned up or something? When I open up a new terminal fnm is working properly again. But the current shell does not have any current node version. fnm current outputs none.

    My setup is as simple as the following as first line in .zshrc:

    eval "$(fnm env --use-on-cd --version-file-strategy recursive)"
    
    opened by uloco 29
  • Fish completions

    Fish completions

    Are there any plans for adding fish completions? ~~Perhaps this could be achieved with a man page, as it would probably be better than having third-party completions from, for example, an Oh My Fish plugin.~~ Maybe the installation script could add completions to ~/.config/fish/completions, as this could allow for completions similar to plugin-nvm.

    help wanted fish shell 
    opened by thomsj 29
  • `fnm use` doesn't switch node version

    `fnm use` doesn't switch node version

    Hi,

    With a clean install of fnm 1.9.0 and fish shell version 3.0.2, the fnm use command doesn't work as expected.

    steps to reproduce

    $ fnm install v8.10.0
    $ fnm use v8.10.0
    $ fnm alias v8.10.0 default
    

    fnm ls is just fine

    $ fnm ls
    The following versions are installed:
    * v8.10.0 (default)
    

    And Testing node version gives the expected output

    $ node --version
    v8.10.0
    

    Now installing latest LTS 10.15.3 and trying to switch to that version is not working

    fnm install v10.15.3
    fnm use v10.15.3
    

    Again, fnm ls says that everything is fine

    $ fnm ls
    The following versions are installed:
    * v8.10.0 (default)
    * v10.15.3
    

    (with a blue-green highlight on the 10.15.3 version indicating it's the current version)

    However node version is still 8.10.0

    $ node --version
    v8.10.0
    

    Additional information

    I've tried to locate which version is pointing the node symbolic link to:

    $ which node
    /tmp/fnm-shell-2857505/bin/node
    

    And /tmp/fnm-shell-2857505 is linking /tmp/fnm-shell-2857505 -> /home/spiroid/.fnm/aliases/default/ which seems to be the issue here, as i guess it should link /home/spiroid/.fnm/current/ right ?

    Thanks for your help

    bug fish shell 
    opened by spiroid 27
  • Switch to cohttp(lwt) instead of curl

    Switch to cohttp(lwt) instead of curl

    Hello,

    This is my attempts (and still in progress) to replace curl with cohttp as proposed in #18

    Currently, only the makeRequest function to fetch node version has been changed. Furthermore, I still need to figure out how to use it with https(so currently I used httpurls).

    Also, I used the `cohttp_lwt_unix' so I guess it would not work on windows. But I assume that was already the case.

    Here's a list of todos:

    • [x] Make it compatible with https
    • [x] Switch other curl's depending code (download function)

    Please don't hesitate to propose any improvements or even to guide me since I'm new to the Ocaml/ReasonML world :)

    PR: New Feature 
    opened by tatchi 24
  • fnm env produce error: Can't infer shell!

    fnm env produce error: Can't infer shell!

    Recently im facing this error,

    error: Can't infer shell!
    fnm can't infer your shell based on the process tree.
    Maybe it is unsupported? we support the following shells:
    * cmd
    * powershell
    * bash
    * zsh
    * fish
    

    Im using windows 11 , and before im not facing this issue, i did try to reinstall fnm and build from cargo but the error persist.

    is there a way to fix this? Only in windows this is persisting, im using it in all my dev machine, artix linux, mac big sur no problem.

    hope this will be resolve coz the command wont simple generate the correct fnm path for windows now. so the command node and npm are both not found.

    i just use pure node js installation for now until this is resolve thanks for building fnm

    bug help wanted 
    opened by codeitlikemiley 23
  • Respect $XDG_DATA_HOME

    Respect $XDG_DATA_HOME

    ~~WIP~~

    ~~I have to stop for the evening, but there's one problem left that may be easiest to solve with a better view of the higher-level architecture and/or with more experience with Rust.~~

    ~~Because base_dir_with_default is called twice below, the deprecation notice is printed twice.~~

    ~~Do let me know if you have a preferred means of addressing this, else I'll have a crack at it next chance I get.~~


    Once the above is addressed this will close #357.

    PR: New Feature 
    opened by samhh 22
  • Does not work with MacOS Big Sur Beta

    Does not work with MacOS Big Sur Beta

    Don't think the version of MacOS matters. Here's the output of fnm env

    export PATH="/var/folders/gk/vbr0r1914mx22rfyq7wmq9y40000gn/T/fnm_multishell_70411_1603896631979/bin":$PATH export FNM_MULTISHELL_PATH="/var/folders/gk/vbr0r1914mx22rfyq7wmq9y40000gn/T/fnm_multishell_70411_1603896631979" export FNM_DIR="/Users/nav/.fnm/" export FNM_LOGLEVEL="info" export FNM_NODE_DIST_MIRROR="https://nodejs.org/dist"

    and here's an excerpt of my .zshrc eval "$(fnm env --use-on-cd --shell=zsh --multi)"

    opened by navxio 22
  • illegal hardware instruction

    illegal hardware instruction

    I am getting the error [1] 86284 illegal hardware instruction fnm --version

    It happens on any usage of fnm. It used to work when installed via script on a previous version.

    I'm on Mac OS 10.13.6 (High Sierra)

    Installed fnm via your homebrew tap. Also tried reinstalling.

    opened by ivanoats 19
  • fnm not respecting/using shell proxy environment variables

    fnm not respecting/using shell proxy environment variables

    I'm using fnm behind a corporate proxy.

    I have proxy settings in my .zshrc file setup uing

    export http_proxy=http://<proxy>
    export HTTP_PROXY=http://<proxy>
    export https_proxy=http://<proxy>
    export HTTPS_PROXY=http://<proxy>
    export ftp_proxy=http://<proxy>
    export rsync_proxy=http://<proxy>
    export ALL_PROXY=http://<proxy>
    

    but still when running fnm it complains not able to connect to node mirror.

    $ fnm ls-remote
    Looking for some node versions upstream...
    fnm: internal error, uncaught exception:
         (Failure
           "TLS to non-TCP currently unsupported: host=nodejs.org endp=(Unknown \"name resolution failed\")")
    
    opened by hisea 18
  • fnm (installed from tap) doesn't work on macOS 10.15 (Catalina)

    fnm (installed from tap) doesn't work on macOS 10.15 (Catalina)

    On macOS v10.15 Beta (19A471t), fnm crashes with this message

    % fnm
    dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
      Referenced from: /usr/local/bin/fnm
      Reason: image not found
    zsh: abort      fnm
    

    10.15 is still in early beta, so no shame in not supporting it, I just thought you should know.

    opened by mikl 18
  • `fnm exec` usage text is wrong

    `fnm exec` usage text is wrong

    fnm exec without options shows following text:

     $ fnm exec
    error: The following required arguments were not provided:
        <binary>
    
    USAGE:
        fnm exec <binary> --fnm-dir <base-dir> --log-level <log-level> --node-dist-mirror <node-dist-mirror>
    
    For more information try --help
    

    The USAGE text is wrong. fnm exec --help shows right USAGE clause.

    / $ fnm exec --help
    fnm-exec 1.22.9
    Run a command within fnm context
    
    Example: -------- fnm exec --using=v12.0.0 -- node --version => v12.0.0
    
    USAGE:
        fnm exec [OPTIONS] <binary> [arguments]...
    
    FLAGS:
        -h, --help
                Prints help information
    
        -V, --version
                Prints version information
    
    
    OPTIONS:
            --fnm-dir <base-dir>
                The root directory of fnm installations [env: FNM_DIR=/home/lynn/.fnm]
    
            --log-level <log-level>
                The log level of fnm commands [env: FNM_LOGLEVEL=info]  [default: info]
    
            --node-dist-mirror <node-dist-mirror>
                https://nodejs.org/dist/ mirror [env: FNM_NODE_DIST_MIRROR=https://nodejs.org/dist]  [default:
                https://nodejs.org/dist]
            --using <version>
    
    
    
    ARGS:
        <binary>
    
    
        <arguments>...
    
    opened by alexeyten 17
  • Bump tokio from 1.22.0 to 1.24.1

    Bump tokio from 1.22.0 to 1.24.1

    Bumps tokio from 1.22.0 to 1.24.1.

    Release notes

    Sourced from tokio's releases.

    Tokio v1.24.1

    This release fixes a compilation failure on targets without AtomicU64 when using rustc older than 1.63. (#5356)

    #5356: tokio-rs/tokio#5356

    Tokio v1.24.0

    The highlight of this release is the reduction of lock contention for all I/O operations (#5300). We have received reports of up to a 20% improvement in CPU utilization and increased throughput for real-world I/O heavy applications.

    Fixed

    • rt: improve native AtomicU64 support detection (#5284)

    Added

    • rt: add configuration option for max number of I/O events polled from the OS per tick (#5186)
    • rt: add an environment variable for configuring the default number of worker threads per runtime instance (#4250)

    Changed

    • sync: reduce MPSC channel stack usage (#5294)
    • io: reduce lock contention in I/O operations (#5300)
    • fs: speed up read_dir() by chunking operations (#5309)
    • rt: use internal ThreadId implementation (#5329)
    • test: don't auto-advance time when a spawn_blocking task is running (#5115)

    #5186: tokio-rs/tokio#5186 #5294: tokio-rs/tokio#5294 #5284: tokio-rs/tokio#5284 #4250: tokio-rs/tokio#4250 #5300: tokio-rs/tokio#5300 #5329: tokio-rs/tokio#5329 #5115: tokio-rs/tokio#5115 #5309: tokio-rs/tokio#5309

    Tokio v1.23.1

    This release forward ports changes from 1.18.4.

    Fixed

    • net: fix Windows named pipe server builder to maintain option when toggling pipe mode (#5336).

    #5336: tokio-rs/tokio#5336

    Tokio v1.23.0

    Fixed

    • net: fix Windows named pipe connect (#5208)
    • io: support vectored writes for ChildStdin (#5216)
    • io: fix async fn ready() false positive for OS-specific events (#5231)

    ... (truncated)

    Commits
    • 31c7e82 chore: prepare Tokio v1.24.1 (#5357)
    • 8d8db27 tokio: add load and compare_exchange_weak to loom StaticAtomicU64 (#5356)
    • dfe252d chore: prepare Tokio v1.24.0 release (#5353)
    • 21b233f test: bump version of async-stream (#5347)
    • 7299304 Merge branch 'tokio-1.23.x' into master
    • 1a997ff chore: prepare Tokio v1.23.1 release
    • a8fe333 Merge branch 'tokio-1.20.x' into tokio-1.23.x
    • ba81945 chore: prepare Tokio 1.20.3 release
    • 763bdc9 ci: run WASI tasks using latest Rust
    • 9f98535 Merge remote-tracking branch 'origin/tokio-1.18.x' into fix-named-pipes-1.20
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    PR: Dependency Update rust 
    opened by dependabot[bot] 2
  • Is it possible to override the default node-versions and caches directories?

    Is it possible to override the default node-versions and caches directories?

    I'm a little weird and like to manually install things. I noticed that some of the assets spill out from the install directory making uninstalling fnm a bit challenging. I realise I am installing fnm globally, this is intentional.

    My install process:

    # Build
    wget https://github.com/Schniz/fnm/archive/refs/heads/master.zip
    unzip master.zip
    cd fnm-master
    cargo build --release
    
    # Install
    sudo mkdir /opt/fnm
    sudo mv target/release/fnm /opt/fnm
    sudo ln -s /opt/fnm/fnm /usr/local/bin/fnm
    
    # Per-shell setup
    eval "$(fnm env --shell zsh)"
    

    By default node versions install to: /Users/dalsh/Library/Application Support/fnm/node-versions and cache versions are in /Users/dalsh/Library/Caches/fnm_multishells/*.

    I would love to keep everything contained within my install directory of /opt/fnm - perhaps /opt/fnm/node-versions/* and /opt/fnm/multishells/*.

    Is there a way to configure these settings or perhaps have it automatically install next to the binary?

    opened by alshdavid 0
  • Add arch information to GitHub Releases

    Add arch information to GitHub Releases

    The GitHub releases page doesn't include cpu arch information making it difficult to know if the project is supported on my machine.

    Would be great if the releases included arch information, e.g.:

    linux_amd64.zip
    linux_arm64.zip
    macos_amd64.zip
    macos_arm64.zip
    

    Luckily Rust projects are easy to build :)

    opened by alshdavid 0
  • Migrating from nvm to fnm, lost tab completions

    Migrating from nvm to fnm, lost tab completions

    This is not a problem caused by fnm, but nvm. However, I feel this should be mentioned here since many people are migrating from nvm to fnm, and some of them may trip on the same issue. Perhaps this fact could be mentioned in a FAQ or Troubleshooting section?

    Nvm enables Zsh's tab completion (via autoload -U compinit) during initialization. This also enables built-in completions for many other tools, such as Git. I had been unknowingly relying on this behavior since I installed nvm.

    When I removed nvm to use fnm, tab completion was disabled. I had to manually enable completions in my .zshrc to get it working again (and add fnm's own completions):

    # ~/.zshrc
    
    # I put my custom completions in ~/.zcompletions/ 
    fpath+=~/.zcompletions
    autoload -Uz compinit && compinit
    
    # ...
    
    opened by pastelmind 0
  • node_version allows `^` while fnm it doesn't

    node_version allows `^` while fnm it doesn't

    Hola @Schniz πŸ‘‹πŸΌ

    You already know that I love you and respect you, but here's a bug:

    ~ cat .node-version
    ^18.0.0
    

    Results into

    Can't find an installed Node version matching ^18.0.0.
    Do you want to install it? answer [y/n]: y
    error: The requested version is not installable: ^18.0.0
    
    opened by davesnx 2
  • Code sign Windows executable

    Code sign Windows executable

    Current Windows executable is not signed and this makes it a bit challenging adopting fnm in organizations with strict security policies.

    It would be great to have code signed executable (fnm.exe). Organizations could trust/allow execution of fnm by specific certificate.

    opened by minijus 2
Releases(v1.33.1)
Owner
Gal Schlezinger
Gal Schlezinger
Rust bindings for writing safe and fast native Node.js modules.

Rust bindings for writing safe and fast native Node.js modules. Getting started Once you have the platform dependencies installed, getting started is

The Neon Project 7k Jan 4, 2023
Node.js bindings to the ripgrep library, for fast file searching in JavaScript without child processes!

ripgrepjs ripgrepjs: Node.js bindings to the ripgrep library, for direct integration with JS programs without spawning an extra subprocess! This proje

Annika 1 May 10, 2022
πŸš€ Fast and 100% API compatible postcss replacer, built in Rust

postcss-rs ?? Fast and 100% API compatible postcss replacer, built in Rust ⚠️ DO NOT USE. STILL WORK IN PROGRESS. Performance Improvement Tokenize boo

null 472 Dec 28, 2022
Fastest lz4 compression library in Node.js, powered by napi-rs and lz4-flex.

Lz4 Fastest lz4 compression library in Node.js, powered by napi-rs and lz4-flex. Install this package yarn add lz4-napi API export function compress:

Antonio Musolino 34 Nov 22, 2022
ruby-build is a command-line utility that makes it easy to install virtually any version of Ruby, from source.

ruby-build ruby-build is a command-line utility that makes it easy to install virtually any version of Ruby, from source. It is available as a plugin

null 3.7k Jan 5, 2023
Version of Clue made to be compilable in WebAssembly (WIP)

Clue is a programming language that compiles into Lua code with a syntax similar to languages like C or Rust. Clue tries to be almost as simple as Lua

Clue 2 Jun 16, 2022
DEF CON 30 Version of the PACMAN Attack ("PACMAN II")

The PACMAN Attack PACMAN except in rust! Experiments Experiments are launched from src/main.rs. You can uncomment the experiment you'd like to run in

Joseph Ravichandran 16 Nov 14, 2022
Easy way to write Node.js module using Rust

node-bindgen Easy way to write native Node.js module using idiomatic Rust Features Easy: Just write idiomatic Rust code, node-bindgen take care of gen

InfinyOn 346 Jan 3, 2023
Benchmark over Node.js binding frameworks in Rust

Benchmark over Node.js binding frameworks in Rust

LongYinan 7 Dec 28, 2022
Rust Blake hash bindings for Node.js.

@napi-rs/blake-hash Node.js binding for https://github.com/BLAKE3-team/BLAKE3. High performance, and no postinstall scripts. Support matrix node12 nod

LongYinan 35 Aug 12, 2022
lzma-rs binding to Node.js via napi-rs.

@napi-rs/lzma lzma-rs binding to Node.js via napi-rs. ?? Help me to become a full-time open-source developer by sponsoring me on Github Install yarn a

LongYinan 8 Aug 16, 2022
Native webview bindings for Node.js

webview-native Native webview bindings for Node.js Installing webview-native Installing webview-native requires a supported version of Node and Rust.

SnowflakeDev Community ❄️ 7 Nov 16, 2022
Node.js bindings to Lua

Node.js bindings to Lua

Connor Brewster 6 Dec 19, 2022
Libsodium for Node.js

Libsodium for Node.js

Tomio 7 Oct 30, 2022
Ethereal - a general-purpose programming language that is designed to be fast and simple

Ethereal is a general-purpose programming language that is designed to be fast and simple. Heavly inspired by Monkey and written in Rust

Synthesized Infinity 21 Nov 25, 2022
The Hassle-Free JavaScript Tool Manager

The Hassle-Free JavaScript Tool Manager Fast: Install and run any JS tool quickly and seamlessly! Volta is built in Rust and ships as a snappy static

Volta: Start your engines. ⚑ 7.3k Jan 8, 2023
A JavaScript Runtime built with Mozilla's SpiderMonkey Engine and Rust

Spiderfire Spiderfire is a javascript runtime built with Mozilla's SpiderMonkey engine and Rust. Spiderfire aims to disrupt the server-side javascript

Redfire 122 Dec 15, 2022
Livny is a modern JavaScript and TypeScript runtime built on top of Rust

Livny is a modern JavaScript and TypeScript runtime built on top of Rust, Golang and the GraalVM Polyglot infrastructure that can run all of Deno and Node.jS applications. It is fine-tuned for user satisfaction, performance and security.

LivnyJS 1 Mar 2, 2022
The official home of the Nyson Programming Language, built off Rust.

Nyson Programming Language The official home of the Nyson Programming Language, built off Rust. (created by Nyelsonon and AMTitan, 2021) Advertisement

Nyson-Programing-Language 19 Aug 10, 2022