Maharjan Consulting
All articles
Bioinformatics

Why Your Bioinformatics Pipeline Isn't Reproducible (and How to Fix It)

Reproducibility isn't a virtue you add at the end — it's an architectural decision. Here's a practical framework for pipelines that reproduce exactly, years later, on someone else's machine.

Sagun MaharjanJune 18, 20263 min read

Most analysis code works exactly once: on the machine it was written on, with the packages that happened to be installed that week. Six months later — new dataset, new collaborator, or a reviewer asking you to regenerate a figure — it breaks. The problem is rarely the science. It's the engineering around it.

Reproducibility is not something you bolt on after publication. It's a set of decisions you make up front. Here is the framework I use.

Pin everything, assume nothing

The single biggest source of irreproducibility is unpinned dependencies. "It uses the latest version" is a bug, not a feature.

  • Pin tool versions explicitly — not >=, but exact versions.
  • Capture the environment declaratively (Conda environment.yml, a lockfile, or a container recipe).
  • Treat reference data and databases as versioned inputs, because they change too.

If you can't state exactly which versions produced a result, you can't reproduce it.

Containerize the execution, not just the code

A pinned environment file still depends on the resolver behaving identically. Containers remove that variable entirely.

# One immutable image, byte-for-byte identical across machines
docker build -t mylab/profiler:1.4.2 .

Package each tool — or each pipeline stage — as a container with a fixed tag. On HPC, Singularity/Apptainer runs the same images without root. The payoff: the same command produces the same output on a laptop, a cluster, and a cloud VM.

Make the workflow the source of truth

Hand-run scripts drift. A workflow engine encodes the DAG, the inputs, and the environment for each step in one place.

  • Nextflow and Snakemake give you resumability, parallelism, and provenance for free.
  • Each process declares its own container and resources.
  • A failed run resumes from the last checkpoint instead of restarting.

The workflow file becomes the executable methods section.

Separate parameters from logic

Hard-coded paths and thresholds are reproducibility landmines. Push every knob into a config file that travels with the results. When someone asks "what settings produced this?", the answer is a single committed file.

Validate against known outputs

Reproducibility without correctness is just consistent wrongness. Keep a small reference dataset with expected outputs and run it in CI. If a dependency bump silently changes results, you find out immediately — not after publication.

The payoff

A pipeline built this way reproduces exactly, years later, on hardware that didn't exist when you wrote it. It survives staff turnover. It passes review without a scramble. And it turns every future project into a fork of a working system instead of a fresh start.

Reproducibility is cheaper when it's designed in. Retrofitting it after the fact is where the cost lives.

Have a hard technical problem?

Every engagement begins with a free consultation. Tell me what you're working on and we'll figure out the right approach together — no obligation.