NCBI holds the largest collection of biological sequence and literature data in the world, and almost every bioinformatics project starts with getting something out of it. Pointing and clicking through the web interface works for one accession. It does not work for two thousand accessions, and it leaves no record of what you asked for.
EDirect — Entrez Direct — is NCBI’s official command-line interface to the same databases. It exposes search, fetch, linking and parsing as separate programs that you chain with pipes, which means every step of your data retrieval is a command in a script you can commit.
Table of Contents
Installation
sh -c "$(curl -fsSL https://ftp.ncbi.nlm.nih.gov/entrez/entrezdirect/install-edirect.sh)"
# The installer prints a line to add to your shell profile:
export PATH="$HOME/edirect:$PATH"
# Verify
esearch -version
efetch -version
On a managed system, prefer conda, which pins the version and keeps EDirect out of your home directory:
conda create -n edirect -c bioconda entrez-direct
conda activate edirect
Whichever route you take, verify with a trivial query before building anything on top of it. If esearch hangs, the problem is usually a proxy or firewall, not your query.
The five programs and what each does
| Program | Job | Typical use |
|---|---|---|
esearch | Search a database, return matching IDs | Turn a query string into UIDs |
efetch | Download records by ID | Get FASTA, GenBank, abstracts, run info |
elink | Follow links between databases | Find SRA runs for a BioProject |
esummary | Fetch compact metadata documents | Title, organism, length, date |
xtract | Parse XML into columns | Build a TSV from esummary output |
The pattern is always the same: esearch produces UIDs, and something downstream consumes them. Once that clicks, EDirect stops feeling like five tools and starts feeling like one.
Searching PubMed and getting usable output
# How many papers match?
esearch -db pubmed -query "single cell RNA-seq[Title/Abstract] AND 2025[PDAT]" |
grep -o '<Count>[0-9]*</Count>'
# Download abstracts as text
esearch -db pubmed -query "CRISPR delivery[Title]" |
efetch -format abstract > abstracts.txt
# Structured metadata as a table
esearch -db pubmed -query "long read sequencing[Title]" |
esummary |
xtract -pattern DocumentSummary \
-element Id -tab "\t" -element PubDate -tab "\t" -element Title
The final command is the workhorse. xtract -pattern says which repeating XML element to treat as a record, -element names the field, and -tab inserts a separator. Redirect to a file and you have a reproducible literature table instead of a screenshot.
Field tags are case-sensitive and unforgiving. [Title], [Title/Abstract], [PDAT] for publication date, [Organism] for taxonomy, and [Accession] all work; [title] silently changes the meaning of your query. When a search returns zero results, test the same terms in the web interface first and compare.
Fetching sequences
# One accession
esearch -db nucleotide -query NC_000913.3 | efetch -format fasta > ecoli.fa
# Whole genome record with annotations
esearch -db nucleotide -query NC_000913.3 | efetch -format gbwithparts > ecoli.gb
# Proteins matching an organism and a keyword
esearch -db protein -query "insulin[Title] AND Homo sapiens[Organism]" |
efetch -format fasta > insulin.fa
# How many hits before you download them all?
esearch -db protein -query "kinase[Title] AND Mus musculus[Organism]" |
efetch -format fasta |
grep -c '^>'
That last pattern — count before you commit — has saved more disk space and more network time than any other habit in this tutorial. A loose query against protein can easily return hundreds of megabytes.
From a list of accessions to a multi-FASTA
cat accessions.txt
# NM_000546.6
# NM_000546.5
# NM_001354689.3
while read -r acc; do
esearch -db nucleotide -query "$acc" | efetch -format fasta
done < accessions.txt > genes.fa
One query per accession is slow but honest, and it makes failures visible: if an accession has been retired, you see an empty result for that line rather than a silently shortened file. For hundreds of accessions, post them all at once instead:
cat accessions.txt | epost -db nucleotide | efetch -format fasta > genes.fa
Getting SRA run data without downloading reads
The runinfo format is the most useful thing most people never find. It returns the metadata table for every sequencing run in a project — run accessions, sample names, platform, read counts, file sizes — without touching a single FASTQ.
# All runs in a BioProject
esearch -db sra -query PRJNA257197 | efetch -format runinfo > runinfo.csv
# Run accessions only
esearch -db sra -query PRJNA257197 |
efetch -format runinfo |
cut -d, -f1 | tail -n +2 | grep -v '^$' > runs.txt
# Total size before you decide to download
awk -F, 'NR>1 {sum+=$5} END {print sum/1024/1024/1024 " GB"}' runinfo.csv
Column 5 in runinfo.csv is the size in bytes; check the header rather than trusting that number blindly, since NCBI has changed column order historically. Once you have runs.txt, hand it to the SRA toolkit — the download pattern is covered in our public sequencing data guide.
Linking between databases
elink follows NCBI’s internal cross-references. The classic use: you have a paper and want the sequences it deposited, or you have a BioProject and want its publications.
# PubMed ID -> linked nucleotide records
esearch -db pubmed -query "Escherichia coli O157 genome[Title]" |
elink -target nuccore |
efetch -format docsum |
xtract -pattern DocumentSummary -element AccessionVersion -element Title
# Gene -> protein products
esearch -db gene -query "TP53[Gene] AND human[Organism]" |
elink -target protein |
efetch -format fasta > tp53_proteins.fa
Rate limits, API keys, and being a good citizen
NCBI allows three requests per second without a key and ten with one. The limit is not a suggestion: exceed it and you receive errors or, worse, silently truncated results that look like a biological finding.
# Request a key at https://account.ncbi.nlm.nih.gov/settings/
export NCBI_API_KEY="your_key_here"
# Each EDirect program picks the key up from the environment.
# Slow a batch down when you are near the limit:
while read -r acc; do
esearch -db nucleotide -query "$acc" | efetch -format fasta
sleep 0.2
done < accessions.txt > genes.fa
Batch epost plus efetch is far kinder than a loop: one search request instead of hundreds. Use the loop only when you need per-accession error handling.
The failures you will actually hit
| Symptom | Cause | Fix |
|---|---|---|
| Search returns 0 | Invalid field tag or over-specific query | Test the same terms in the web UI, then simplify |
| Empty FASTA with a valid accession | Retired or suppressed record | Check the accession page; use the current version suffix |
| Truncated output on big queries | Rate limiting | Add an API key and batch with epost |
efetch: command not found | Path line not added to profile | Add export PATH="$HOME/edirect:$PATH" |
| XML instead of a table | Missing xtract stage | Pipe through xtract -pattern |
One more quiet trap: esearch with no -db defaults to PubMed, so a nucleotide query that returns nothing may simply have been sent to the wrong database. Always name the database explicitly, even when it feels redundant.
Why this belongs in your project, not your browser history
The real benefit of EDirect is not speed. It is that accessions.txt plus a five-line script fully documents how your dataset was assembled, and a reviewer can rerun it. That is the difference between data you found and data you can defend.
Retrieval is the first step of a longer chain: quality control, alignment, quantification, statistics. If you want that chain mapped out in order, with the decisions that matter at each stage, Ampersand Academy covers it from raw accession to interpreted result.
Practice
- Count how many human mitochondrial genomes exist in
nucleotidefor a given year, without downloading any records. - Build a TSV of the ten most recent papers on a topic you care about, with ID, date and title.
- Take one BioProject and produce both a run list and a total download size in GB.
- Find the protein products of three genes using only
elink, never opening a browser.
Related tutorials
- Top Bioinformatics Databases Every Beginner Should Know — where the databases EDirect queries fit among the major public resources
- How to Interpret BLAST Results: E-Value, Bit Score, Identity, and Coverage — what to do with the sequences once you have downloaded them
- FASTA and FASTQ File Formats Explained for Beginners — the file formats these commands read and write
Is EDirect the same as the Entrez Programming Utilities (E-utilities)?
EDirect is a command-line layer built on top of E-utilities. E-utilities are the underlying HTTP API; EDirect wraps them in Unix-style programs so you can pipe results instead of writing HTTP requests yourself. Anything EDirect does can be done with E-utilities and more code.
Do I need an NCBI API key?
Not for occasional interactive use. You do need one for any batch job that makes more than roughly three requests per second. Keys are free from your NCBI account settings and raise the limit to ten requests per second.
How do I download FASTQ files with EDirect?
You do not — EDirect fetches metadata, not raw reads. Use efetch -format runinfo to get run accessions, then download the reads with the SRA Toolkit (prefetch and fasterq-dump) or from ENA, which serves FASTQ directly.
Why does my esearch return zero results when the website finds papers?
Almost always a field tag problem. Field tags are case-sensitive, and an unsupported tag changes the query meaning rather than raising an error. Remove the tag, confirm the result count, then add tags back one at a time.
Can EDirect fetch a whole genome with annotations?
Yes, with efetch -format gbwithparts for GenBank records, which includes features and sequence. Note that very large eukaryotic genomes may be impractical to fetch this way; downloading assembly files from the FTP site is usually better.
Is it acceptable to script large downloads from NCBI?
Yes, within the published usage limits and with an API key. Batch requests with epost rather than looping one accession at a time, set a contact email for large jobs, and avoid rerunning downloads you already have on disk.

