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.
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
conda create -n bu-salmon --override-channels -c conda-forge -c bioconda salmon=2.3.4
conda activate bu-salmon
salmon --versionThat 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.
conda create -n bu-salmon --override-channels -c conda-forge -c bioconda salmon=2.3.4Here 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:
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:
conda activate bu-salmon
salmon --versionsalmon 2.3.4
Also confirm the binary resolves inside your environment, not some stray system copy:
which salmonIt 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.
mkdir -p /tmp/salmon_smoke && cd /tmp/salmon_smoke
salmon index -t txome.fa -i salmon_idx -k 15On 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.
salmon quant -i salmon_idx -l A -r reads.fq -o quant_out --validateMappingsThe -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
| Error | Fix |
|---|---|
CondaToSNonInteractiveError / Terms of Service not accepted for defaults | Do not use the defaults channel. Install with --override-channels -c conda-forge -c bioconda as shown. |
PackagesNotFoundError: ... salmon | The bioconda channel is missing or out of order. Pass both channels with conda-forge first: -c conda-forge -c bioconda. |
salmon: command not found | You 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=31 | Expected for synthetic data. Pass a smaller k, e.g. -k 15. Keep the default for real transcriptomes. |
Very slow or hanging solve in base | Never 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:
conda update -n bu-salmon --override-channels -c conda-forge -c bioconda salmonSnapshot the exact environment so a collaborator can reproduce it:
conda env export -n bu-salmon > salmon-env.ymlAnd when you are done, remove it cleanly. Because everything lived inside the env, this leaves no trace on your system:
conda remove -n bu-salmon --allNext steps
Now that Salmon is installed, a couple of natural follow-ons:
- Read Conda environments and Bioconda channels to understand why channel order and
--override-channelsmatter. - For a full RNA-seq pipeline you will often pair Salmon with a workflow manager. See Install Nextflow or Install Snakemake to orchestrate indexing and quantification across many samples.