Back to Blog
SalmonRNA-Seq

Install Salmon for RNA-seq Quantification with Conda (Apple Silicon)

Install Salmon 2.3.4 for RNA-seq transcript quantification on an Apple Silicon Mac using an isolated conda env with native arm64 bioconda builds.

SSSudipta SardarJuly 20, 20268 min read
Install Salmon for RNA-seq Quantification with Conda (Apple Silicon)

Salmon is one of the fastest ways to turn raw RNA-seq reads into transcript-level abundances. Instead of a slow full alignment to the genome, it uses selective alignment against a transcriptome to estimate how many reads came from each transcript, reporting the result in TPM and estimated counts. The everyday workflow is two commands: salmon index builds a searchable index from a transcriptome FASTA, and salmon quant maps your reads against that index and writes a quant.sf table.

In this guide we install Salmon into its own isolated conda environment on an Apple Silicon Mac. The whole point of the one-tool-per-env approach is that the exact build you need lives inside the environment, independent of your system. You can wipe it, rebuild it, or pin a different version tomorrow without touching anything else on your machine.

Salmon 2.x is a ground-up Rust rewrite that uses a new piscem/SSHash-based index format. This is not the old 1.10 C++ Salmon. Because it is largely statically linked, the environment is tiny, but indices built by Salmon 1.x cannot be read by 2.x and must be rebuilt.

Prerequisites

You need a working conda on your Mac. If you do not have one yet, start with our Miniconda on Apple Silicon guide and come back here. This walkthrough was run on an Apple Silicon Mac (arm64), macOS 26.5.2, with conda 25.5.1 and the fast libmamba solver.

We install only from conda-forge and bioconda, and we pass --override-channels so conda never touches the Anaconda defaults channel. On recent conda versions that defaults channel is gated behind a Terms-of-Service prompt, and skipping it entirely is the cleanest way to avoid the error.

TL;DR: copy-paste install

bash
conda create -n bu-salmon --override-channels -c conda-forge -c bioconda salmon=2.3.4
conda activate bu-salmon
salmon --version

That is the whole install. The rest of this guide explains each step and shows the real output so you know what success looks like.

Step 1: Create an isolated environment

We name the environment bu-salmon and ask for salmon explicitly. The channel order matters: conda-forge is listed first so it takes priority, and bioconda supplies Salmon itself.

bash
conda create -n bu-salmon --override-channels -c conda-forge -c bioconda salmon=2.3.4

Here is the real, trimmed output from the test machine:

### env create: bu-salmon  (salmon) ###
Channels:
 - conda-forge
 - bioconda
Platform: osx-arm64
Collecting package metadata (repodata.json): done
Solving environment: done

## Package Plan ##

  environment location: /opt/homebrew/Caskroom/miniconda/base/envs/bu-salmon

  added / updated specs:
    - salmon

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    salmon-2.3.4               |       hfc06a8d_0         2.7 MB  bioconda
    ------------------------------------------------------------
                                           Total:         2.7 MB

The following NEW packages will be INSTALLED:

  salmon             bioconda/osx-arm64::salmon-2.3.4-hfc06a8d_0

Preparing transaction: done
Verifying transaction: done
Executing transaction: done

real 4.89
user 3.43
sys 0.62

Notice how small this is. Salmon downloads as a single 2.7 MB package, the environment lands at roughly 15 MB on disk, and the whole solve-and-install finished in about 5 seconds (real 4.89). That is the payoff of the Rust rewrite: the old 1.x C++ Salmon dragged in boost, tbb, libgomp, icu and libcurl, whereas 2.x is essentially one statically linked binary.

Apple Silicon: this is a native arm64 build

Look closely at the install line:

salmon             bioconda/osx-arm64::salmon-2.3.4-hfc06a8d_0

The osx-arm64 tag confirms bioconda shipped a native Apple Silicon build. No Rosetta 2 emulation is involved here, which is why it is both fast and tiny. You can double-check after activating:

bash
conda list -n bu-salmon salmon
file $(which salmon)

conda list should show the build channel as bioconda and the platform as osx-arm64, and file should report an arm64 binary.

If you later add other bioconda tools to a pipeline and one of them has no arm64 build, the fallback is a separate x86-64 environment run under Rosetta 2: CONDA_SUBDIR=osx-64 conda create -n toolname_x86 --override-channels -c conda-forge -c bioconda toolname, then pin it with conda config --env --set subdir osx-64. Salmon 2.3.4 itself does not need this, so keep it native.

Step 2: Verify the install

Activate the environment (you need to do this in every new shell) and check the version:

bash
conda activate bu-salmon
salmon --version
salmon 2.3.4

Also confirm the binary resolves inside your environment, not some stray system copy:

bash
which salmon

It should point inside .../envs/bu-salmon/bin/salmon. If instead you get salmon: command not found, you simply forgot to activate the environment.

Step 3: Smoke test with a tiny index

The most reassuring check is to actually build an index. Create a toy transcriptome with a couple of short sequences and index it. Because these toy transcripts are short, we pass -k 15; real transcriptomes should keep the default k=31.

bash
mkdir -p /tmp/salmon_smoke && cd /tmp/salmon_smoke
salmon index -t txome.fa -i salmon_idx -k 15

On the test machine that produced the following real output:

INFO piscem_rs::index::reference_index:   2 references, max_ref_len=36
INFO piscem_rs::index::reference_index: Loading equivalence class table from salmon_idx/index.ectab
INFO piscem_rs::index::reference_index:   6 tiles, 3 ECs, 3 label entries
INFO piscem_rs::index::reference_index:   ref_shift=7, pos_mask=0x3f
INFO salmon_index: index built: 2 references

indexed 2 references (k=15, m=8)

The piscem_rs log lines are the giveaway that you are running the modern Rust engine. Salmon read 2 references, built the SSHash index with k=15, and wrote an equivalence-class table into salmon_idx/. That is a clean, healthy index build.

The k=31 default requires transcripts longer than 31 bp, so a synthetic toy FASTA will fail unless you lower k. This is expected for smoke tests only. For a real transcriptome, run salmon index -t transcripts.fa -i my_idx with the default k.

Once you have an index, quantification looks like the command below.

The salmon quant command below was not run on the test machine; only salmon index was executed here. It is included from the official docs so you know the next step in a real workflow.

bash
salmon quant -i salmon_idx -l A -r reads.fq -o quant_out --validateMappings

The -l A lets Salmon auto-detect the library type, and quant_out/quant.sf holds the per-transcript TPM and count table.

Common errors and fixes

ErrorFix
CondaToSNonInteractiveError / Terms of Service not accepted for defaultsDo not use the defaults channel. Install with --override-channels -c conda-forge -c bioconda as shown.
PackagesNotFoundError: ... salmonThe bioconda channel is missing or out of order. Pass both channels with conda-forge first: -c conda-forge -c bioconda.
salmon: command not foundYou did not activate the env. Run conda activate bu-salmon in each new shell, then which salmon.
salmon quant fails loading the index (version/format mismatch)The index was built with 1.x. Salmon 2.x uses a new format; rebuild it with salmon index -t transcripts.fa -i new_idx.
Index build fails on a tiny toy transcript at default k=31Expected for synthetic data. Pass a smaller k, e.g. -k 15. Keep the default for real transcriptomes.
Very slow or hanging solve in baseNever install tools into base. Use an isolated env and the libmamba solver (default since conda 23.10), or mamba create.

Managing the environment

Update Salmon in place:

bash
conda update -n bu-salmon --override-channels -c conda-forge -c bioconda salmon

Snapshot the exact environment so a collaborator can reproduce it:

bash
conda env export -n bu-salmon > salmon-env.yml

And when you are done, remove it cleanly. Because everything lived inside the env, this leaves no trace on your system:

bash
conda remove -n bu-salmon --all

Next steps

Now that Salmon is installed, a couple of natural follow-ons: