Back to Blog
bedtoolsGenomics

Install bedtools with Conda: Genome Arithmetic on Apple Silicon

Install bedtools 2.31.1 natively on Apple Silicon with conda and bioconda in a tiny isolated env, then verify it with a quick genome arithmetic smoke test.

SSSudipta SardarJuly 20, 20266 min read
Install bedtools with Conda: Genome Arithmetic on Apple Silicon

bedtools is the Swiss-army knife of genome arithmetic. It compares, merges, intersects, and shuffles genomic intervals across BED, GFF/GTF, VCF, and BAM files. If you have ever wanted to ask "which of my peaks overlap these genes?" or "collapse these overlapping features into one", bedtools answers it in a single fast command.

In this guide we install bedtools 2.31.1 into its own isolated conda environment on an Apple Silicon Mac. Why isolate it? Because the exact build you need lives inside the environment, independent of your system. Nothing leaks into your base install, nothing clashes with other tools, and you can delete the whole thing later without a trace. bedtools is a great first tool to practice this on: the solve is tiny and the install finishes in seconds.

Prerequisites

You need a working conda. If you have not set one up yet, follow our Miniconda on Apple Silicon guide first, then 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 from the conda-forge and bioconda channels and pass --override-channels so the Anaconda defaults channel (and its Terms-of-Service gate) never enters the picture. If channels are new to you, the conda environments and bioconda channels guide covers the why in depth.

TL;DR install

Copy-paste this. It creates the env, pins the version, and activates it.

bash
conda create -n bu-bedtools \
  --override-channels -c conda-forge -c bioconda \
  bedtools=2.31.1

conda activate bu-bedtools
bedtools --version

Step by step

1. Create an isolated environment

One env per tool is the rule. We name ours bu-bedtools so it is obvious what lives inside.

bash
conda create -n bu-bedtools \
  --override-channels -c conda-forge -c bioconda \
  bedtools=2.31.1

A few things worth understanding in that one line:

  • -n bu-bedtools names the environment. Keeping tools separate means their dependencies never fight each other.
  • --override-channels tells conda to ignore any channels configured globally (including defaults). This is what sidesteps the Anaconda ToS prompt.
  • -c conda-forge -c bioconda lists channels in priority order. conda-forge first (highest priority) for the C/C++ runtime libraries, bioconda for bedtools itself.
  • bedtools=2.31.1 pins the exact version so this env is reproducible on any machine.

2. Watch the solve

With libmamba the solve is near-instant. Here is the real output from the run, trimmed:

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-bedtools

  added / updated specs:
    - bedtools

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    bedtools-2.31.1            |       he85ad4a_3         743 KB  bioconda
    ------------------------------------------------------------
                                           Total:         743 KB

The following NEW packages will be INSTALLED:

  bedtools           bioconda/osx-arm64::bedtools-2.31.1-he85ad4a_3
  bzip2              conda-forge/osx-arm64::bzip2-1.0.8-hd037594_9
  libcxx             conda-forge/osx-arm64::libcxx-22.1.8-h55c6f16_0
  liblzma            conda-forge/osx-arm64::liblzma-5.8.3-h8088a28_0
  libzlib            conda-forge/osx-arm64::libzlib-1.3.2-h8088a28_2

Notice how lean this is: bedtools plus just four runtime libraries, five packages total. The bedtools download itself is only 743 KB. The whole operation completed in about 7 seconds of real time (real 6.60), which is why this makes such a satisfying first install.

3. Activate the environment

The tools are installed, but your shell still needs to step into the env.

bash
conda activate bu-bedtools

From here on, bedtools on your PATH means the exact 2.31.1 build inside this environment.

Only bedtools (and its libraries) exists inside bu-bedtools. This is the whole point of env isolation: the required build lives in the env, not scattered across your system, so you can reproduce or remove it cleanly.

Apple Silicon note

bedtools 2.31.1 ships a native osx-arm64 build, so no Rosetta 2 is needed. You can see it in the plan above: the Platform: osx-arm64 line and the bioconda/osx-arm64::bedtools-2.31.1-he85ad4a_3 package. On an M1/M2/M3/M4 Mac, the install command resolves to that native arm64 package automatically. It runs directly on the Apple Silicon CPU, no translation layer.

You would only reach for Rosetta if you ever needed an older bedtools that predates arm64 builds. In that case you would force the x86-64 build with CONDA_SUBDIR=osx-64 in front of the conda create command, and it would run under Rosetta 2. For 2.31.1 this is unnecessary.

Verify the install

First, confirm the version. This is the real output from the test machine:

bash
bedtools --version
bedtools v2.31.1

That single line is your proof the native build is on PATH and runnable. You can also check where it lives and skim the subcommand list:

bash
which bedtools
bedtools --help

Smoke test: a real intersect

The classic bedtools job is finding where two sets of intervals overlap. Make two tiny BED files and intersect them:

bash
cd "$(mktemp -d)"
printf 'chr1\t10\t20\nchr1\t30\t40\n' > a.bed
printf 'chr1\t15\t35\n' > b.bed
bedtools intersect -a a.bed -b b.bed

The overlapping regions come back as:

chr1	15	20
chr1	30	35

Feature a runs 10-20 and 30-40; feature b runs 15-35. The output is exactly the overlap of each a feature with b. That is genome arithmetic in one command. The sibling command bedtools merge collapses overlapping intervals in a single sorted file into one, and together intersect and merge cover a huge share of everyday interval work.

The version check above (bedtools v2.31.1) was captured live on the test machine. The intersect smoke test and its expected output come from the bedtools documentation and were not re-run during this capture. Run it yourself; the numbers above are what a correct install produces.

Common errors and fixes

ErrorFix
CondaToSNonInteractiveError / "Terms of Service have not been accepted" pointing at the defaults channelsDo not use defaults at all. Keep --override-channels -c conda-forge -c bioconda as shown, which bypasses the ToS gate. Or run conda config --remove channels defaults.
PackagesNotFoundError: bedtools not availableYou dropped a channel or reversed the order. Always pass -c conda-forge -c bioconda (conda-forge first). bedtools lives in bioconda, not defaults.
Dependency conflicts after installing into baseNever install tools into base. Use one env per tool: conda create -n bu-bedtools ... then conda activate bu-bedtools.
bedtools: command not found right after installYou forgot to activate. Run conda activate bu-bedtools. If activate is unrecognized, run conda init zsh once and restart the shell.
A new machine installs a different versionPin the version (bedtools=2.31.1) and record the env with conda env export --from-history > environment.yml.

Managing the environment

Update bedtools within the env later:

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

Export a reproducible spec so a collaborator (or future you) can rebuild the exact env:

bash
conda env export --from-history > environment.yml

Recreate it anywhere with:

bash
conda env create -f environment.yml

And when you are done, remove the whole environment cleanly, no leftovers on your system:

bash
conda remove -n bu-bedtools --all

Next steps

Now that you can slice intervals, pair bedtools with an aligner and a variant toolkit for a full workflow: