15  Variant Annotation and Interpretation: Implementations

Implementationstooling reviewed 2026-09

Everything on this page is generated from tools/annotation.json. If something here is wrong or out of date, the fix belongs in that file, not in this prose.

For why a consequence is a claim about a transcript rather than about a variant, and why the databases matter more than the programs, see Section 14.1.

15.1 Start here

Annotation is two jobs that get called one word. Deriving a consequence computes something new from the variant, the reference and a gene model — Section 14.2. Transferring attaches a fact somebody else established: a population frequency, a clinical assertion, a precomputed score. A pipeline needs both, they fail in different ways, and the tools below are not interchangeable between them — one of them does both, which is convenient and not the same as the distinction going away.

BCFtoolsrecommendedC

What samtools is to alignments, this is to variants: reading, filtering, annotating, merging and subsetting VCF and BCF, released in lockstep with samtools and htslib. Its filtering expression language is the part worth learning first, because it replaces a great deal of fragile text processing. Its csq subcommand is also the rare consequence caller that reads phase, so two variants sharing a codon are annotated as the haplotype they actually form rather than twice, independently, as though each were alone. (Danecek et al. 2021, 2011; Danecek and McCarthy 2017)

Dual-licensed MIT or GPL-3.0. Building against the GNU Scientific Library — optional and off by default — commits you to the GPL branch.
activelast release 2026-07MIT OR GPL-3.0v1.24reviewed 2026-09
Ensembl VEPrecommendedpl

The reference implementation of the consequence vocabulary the rest of the field writes its filters against, released in step with the Ensembl gene set it annotates from. Its plugin interface is the reason to start here rather than the consequence calls themselves: the score sets you will want next — splice models, precomputed missense predictors, loss-of-function confidence, aggregate frequency databases — attach to the same pass instead of becoming a second annotation stage with its own coordinate conventions to get wrong. (McLaren et al. 2016, 2010)

Running offline means a per-species, per-assembly cache, and the cache release has to match the VEP release or the annotations quietly come from a different gene set. Plugins are separate downloads with their own data files and their own licenses. `--mane` is off by default, so a run that does not ask for it reports no MANE Select flag rather than reporting that there is none.
activelast release 2026-09Apache-2.0v116.2reviewed 2026-09
vcfannorecommendedgo

The other half of annotation, and the half a consequence engine does not do: attaching fields from your own tabixed VCF, BED and GFF sources onto a callset. Any number of sources are declared in one TOML file and applied in a single parallel pass, which matters less for the speed than for the file: that config is a checkable record of exactly which database versions produced the INFO fields a downstream filter then keys on. (Pedersen et al. 2016)

It transfers fields; it does not reconcile representations. Sources must already be normalized to the same reference and the same left-aligned form as the callset, or a real match is silently missed — see the normalization discussion in the variant calling part.
activelast release 2026-06MITv0.3.9reviewed 2026-09

15.1.1 The other engine

One alternative worth knowing, and it is not a weaker version of the tools above — it answers a question they answer badly. If your organism is not one of the handful with a curated, versioned annotation set, the problem stops being which consequence caller to run and becomes where an annotation database comes from at all.

Tool Upstream Languages Why / why not
SnpEff activelast release 2026-02 java

A single jar with pre-built databases for a large number of genomes and a build step that makes one from a GFF for anything it does not already have. That is the reason to choose it: outside the well-served human case, getting an annotation database for your organism is the whole problem, and here it is one command rather than a cache-building exercise. SnpSift, shipped alongside, does the filtering half. (Cingolani et al. 2012)

15.2 Predicting what nobody has measured

Nothing in this section is recommended, and that is the finding. The verdicts here are all viable, because a predictor is not a tool you choose once and standardize on — it is evidence of a stated strength, admissible for some claims and not others (Section 14.4).

The practical shape is also different from every other page in this book. For each of these, the thing most readers consume is a precomputed table joined onto a callset, not a program executed on one. The record is here because the model, its license and its release history are what you are actually depending on, and a table hides all three.

Tool Upstream Languages Why / why not
CADD activelast release 2025-10 pysh

One score for every position in the genome, coding and non-coding alike, which is what makes it useful as a ranking prior when you have no other handle on a non-coding candidate. Its label is not curated pathogenicity but a proxy — variants that survived in the human lineage against simulated ones that did not — so it is a measure of depletion, not of disease. Use it to order a list; do not enter it as evidence. (Kircher et al. 2014; Schubach et al. 2024)

Pangolin dormantlast release 2022-03 py

Predicts the change in splice-site usage rather than the presence of a site, and is trained across several tissues and species, so it answers a quantitative question where SpliceAI answers a categorical one. It is also GPL-3.0, which is the practical reason to reach for it: SpliceAI’s non-commercial terms rule that tool out for a large class of users, and this is the closest thing to a drop-in that they do not. (Zeng and Li 2022)

SpliceAI deprecatedlast release 2020-03 py

Predicts splice-altering effects from sequence alone, and is the model the field’s splicing evidence is anchored on — which is the reason to use it and also the reason to treat it as a fixed reference rather than a dependency. The repository is archived, the code is under a license that permits neither modification nor redistribution, and the models are academic and non-commercial only. Consume it as a score source, through the precomputed set or a VEP plugin, and do not plan on the code moving. (Jaganathan et al. 2019)

WarningTwo of these three are not open source

SpliceAI’s code forbids modification and redistribution and its models are academic and non-commercial; CADD’s license runs to non-commercial users. This is not a detail to resolve later — it decides whether a score can appear in a commercial report, a redistributable container, or a public reanalysis, and it does not travel with the score once the score is a column in a VCF. Pangolin is GPL-3.0 and is in this book substantially for that reason.

15.3 From a callset to a shortlist

Annotation produces a file with more columns; it does not produce an answer. What survives every filter that can be applied without knowing what you are looking for is still far more than anyone can read — Section 14.5. The tools here bring in the thing that does know: a pedigree, or a phenotype.

Exomiserrecommendedjava

Ranks candidate genes against the patient’s phenotype rather than filtering variants against thresholds, which is the question a rare-disease case actually poses. Frequency, predicted effect, inheritance model and HPO-term similarity — including similarity to model-organism phenotypes, for genes with no human disease association yet — are combined into one ordering. The analysis is one YAML file against a dated data release, so a re-run a year later is reproducible or visibly not. (Smedley et al. 2015)

Phenotype-driven ranking is only as good as the HPO terms it is given, and terms chosen after the candidate is known will confirm it. The data release is a large separate download and pins the frequency and disease sources; record which one you used.
activelast release 2026-06AGPL-3.0v15.1.0reviewed 2026-09
slivarrecommendednim

Expresses an inheritance model — de novo, recessive, compound heterozygote — as a short JavaScript expression evaluated against a pedigree and the genotype fields, so the filter that produced a candidate list is a line you can paste into a methods section instead of a script nobody will read again. The paper it comes from also publishes the candidate counts each model should yield, which is the number that tells you a filter is working before you go looking at genes. (Pedersen et al. 2021)

It filters what the annotation gave it. Frequency cutoffs are only as trustworthy as the population set attached upstream, and an expression referencing a missing INFO field is a filter that quietly passes everything.
activelast release 2026-05MITv0.3.4reviewed 2026-09
Tool Upstream Languages Why / why not
InterVar dormantlast release 2021-08 py

The first serious attempt to mechanize the ACMG-AMP framework, and still the clearest statement of how much of it can be mechanized: 18 of the 28 criteria, with the remaining ten left for a human because they need evidence a program does not have. That accounting is worth knowing. The output is a starting classification for review, and a pipeline that reports it as a classification has misread the tool rather than misused it. (Li and Wang 2017)

NoteA classifier is not a classification

The ACMG-AMP framework (Richards et al. 2015) is a procedure for weighing evidence by people, not an algorithm. Its own authors say so. A program can assign the criteria that reduce to a database lookup and it cannot assign the ones that require judgment about a specific gene and disease, which is why the tool above that tries reports on 18 of 28 and stops. Software that emits “Pathogenic” as a value has changed what the word means.

15.4 Structural variants

The variant calling part deferred interpretation to this page, and structural variation deferred it twice over, because a rearrangement breaks the model the engines above are built on: there is no single position, no reference and alternate allele to compare, and the consequence depends on how much of a gene the event covers rather than on which codon it lands in (Section 14.6). The tools are correspondingly different, and a small-variant annotation pipeline will not do this job by accident.

AnnotSVrecommendedTclsh

A structural variant is annotated by what it overlaps, so the work is a join against gene models, population frequency sets, dosage sensitivity, regulatory elements and disease databases — and the value here is that the join is assembled, versioned and installed for you rather than rebuilt per project. It reports both a whole-event line and one line per gene the event touches, which is the split the question needs: one deletion is a single variant and several separate clinical arguments. (Geoffroy et al. 2018)

Its ranking adapts the ACMG/ClinGen copy-number recommendations into five classes, which applies to dosage changes and not to balanced events. Sources requiring a commercial license are not downloaded by the installer and have to be supplied.
activelast release 2026-05GPL-3.0v3.5.10reviewed 2026-09
Tool Upstream Languages Why / why not
duphold dormantlast release 2020-12 nim

Adds depth fold-change fields to an SV callset so a deletion can be checked against whether coverage actually fell there. The evidence is orthogonal to what a breakpoint caller used to make the call in the first place, which is what makes it worth a pass: read-pair and split-read support agreeing with each other says less than either agreeing with depth. (Pedersen and Quinlan 2019)

SvAnna activelast release 2025-11 java

Phenotype-driven prioritization for structural variants — the Exomiser argument applied to rearrangements, from the same group — and it scores events that disrupt regulatory sequence rather than only those that hit a coding exon. Reach for it when the case has HPO terms and a long-read callset, which is the setting it was built and evaluated for. (Danis et al. 2022)

15.5 What is not here

ANNOVAR (Wang et al. 2010) is the conspicuous absence. It is one of the three annotators you will meet most often, it is still in production everywhere, and it carries no record in this registry — not because the book has no view of it, but because the book cannot make its usual promise about it. Every record here says “reviewed YYYY-MM” next to a version read automatically from an upstream feed. ANNOVAR has no public source repository, its download is registration-walled, and its releases are dated strings on a web page. A record for it would either carry an empty version field, which reads as “nobody looked”, or a hand-typed one, which is the exact failure mode the refresh script exists to prevent. So the position goes here instead, in prose that can be honest about its own footing: it works, you will inherit pipelines built on it, its database collection is genuinely broad — and for a new pipeline the open engines above give you the same annotations under terms you can redistribute and a release history you can watch.

The databases are not surveyed as tools. gnomAD, ClinVar, dbNSFP, REVEL, AlphaMissense, ClinGen’s dosage-sensitivity map: these are the substance of an annotation, and choosing them is the methods decision (Section 14.3). But they are versioned datasets rather than software, they are consumed through the tools above rather than run, and a survey of them would need a review cadence this book does not have. The ones that carry an argument here are named in the concepts chapter, with citations.

Somatic annotation and reporting. Oncogenicity classification follows a different framework from ACMG-AMP for germline variants, tumor-suppressor and oncogene evidence is asymmetric in ways the tools above do not model, and the output is a clinical report rather than a filtered VCF. Same reason somatic calling is absent from the variant calling part: a different question, not a harder version of this one.

Commercial interpretation platforms. Several exist, some are very widely used in diagnostic laboratories, and none can be surveyed the way this book surveys anything else — there is no repository to read, no license file to check, and no release feed. A page that ranked them would be recycling marketing copy under a review date.

15.6 Language coverage

This part is the most linguistically scattered in the book, and the reason is that no two of these tools are doing the same kind of work.

The consequence engines are Perl and Java — languages chosen when they were written, kept because a consequence caller’s cost is dominated by the database join and not by the inner loop. Nothing here is compiled for speed the way an aligner is, and nothing needs to be.

The tools that are fast are fast because they are doing set operations at genome scale: vcfanno in Go, slivar and duphold in Nim. That is a small, consistent tradition — Brent Pedersen wrote all three of those, plus smoove in the structural variation part — and it is the clearest example in this book of a modern compiled language being adopted for bioinformatics tooling and sticking.

The predictors are Python, because they are neural networks and that is where the frameworks are. And AnnotSV is Tcl, which is the only appearance of that language in this book and needs no defense: it is a data-joining pipeline, it has been maintained continuously for years, and the language it is written in is not something a user of it ever has to touch.

NoteWhat this means in practice

As everywhere else in this book, you drive these from the command line and read the result back in. The difference here is what “the result” is: an annotated VCF whose INFO fields are named by your configuration, not by a standard. A downstream script that hard-codes gnomAD_AF is coupled to the annotation run that produced it. Keep the vcfanno config, or the VEP command, next to the analysis that consumes its output — Section 22.6 is about exactly this.