Safe, idiomatic Rust bindings to the primer3 C library for PCR primer design and oligonucleotide thermodynamic calculations.
Warning
primer3-rs is licensed under GPL-2.0-or-later.
This is unusual for our crates, and it is non-negotiable: the upstream
primer3 C library is GPL-2.0-or-later,
and primer3-rs statically compiles and links it. Any application, library, or
pipeline that depends on primer3, primer3-sys, or primer3-tool — whether
via static or dynamic linking — forms a combined work subject to the terms
of the GNU General Public License. In practice this means:
- Distributing a binary that links primer3-rs requires releasing the complete corresponding source of that binary under a GPL-compatible license.
- You cannot combine primer3-rs with proprietary, closed-source, or permissively-licensed-but-non-GPL-compatible code in a distributed product.
- Internal/in-house use is unrestricted; the GPL's obligations trigger on distribution, not on use.
If these constraints are a problem for your use case, consider invoking the
upstream primer3_core binary as a subprocess instead — the GPL does not
reach across process boundaries in the same way. See the License
section below for details.
Not legal advice. The above is our good-faith reading of the GPL and how it applies to primer3-rs. We are not lawyers, this is an opinion rather than a legal determination, and the line between "mere aggregation" and a "combined work" can be fact-specific. If the licensing implications matter to your project, please seek qualified legal counsel.
primer3-rs provides three crates:
primer3-sys-- Raw FFI bindings generated viabindgenagainst the primer3 C headersprimer3-- Safe, idiomatic Rust API with builders, strong types, and proper error handlingprimer3-tool-- CLI binary exposingtm,hairpin,homodimer,heterodimer, anddesignsubcommands
- Melting temperature (
Tm) calculation with multiple methods (Breslauer, SantaLucia, SantaLucia 2004) - Thermodynamic analysis: hairpin, homodimer, heterodimer, and 3' end stability
- Full primer design via
design_primers()with typed settings and results - Builder patterns for all complex configuration
- Thread-safe: thermodynamic functions are safe to call concurrently;
design_primers()andalign()are mutex-guarded - Vendored C source compiled automatically -- no system dependencies required
Supported platforms: Linux and macOS. Windows is not supported.
Add to your Cargo.toml:
[dependencies]
primer3 = "0.1"The primer3 C library source is vendored and compiled automatically during build.
You will need a C/C++ compiler and libclang (for bindgen).
To install the primer3-tool CLI (which exposes tm, hairpin, homodimer, heterodimer, and design subcommands):
cargo install primer3-toolTo link against a system-installed libprimer3 instead of compiling from source:
[dependencies]
primer3 = { version = "0.1", default-features = false, features = ["system"] }use primer3::calc_tm;
let tm = calc_tm("GTAAAACGACGGCCAGT").unwrap();
println!("Tm = {tm:.1} C");use primer3::{calc_hairpin, calc_heterodimer};
let hairpin = calc_hairpin("CCCCCATCCGATCAGGGGG").unwrap();
println!("Hairpin Tm = {:.1} C, dG = {:.0} cal/mol", hairpin.tm(), hairpin.dg());
let dimer = calc_heterodimer("AAAAAAAAAA", "TTTTTTTTTT").unwrap();
println!("Heterodimer Tm = {:.1} C", dimer.tm());use primer3::{design_primers, SequenceArgs, PrimerSettings};
let seq_args = SequenceArgs::builder()
.sequence("ATCGATCGATCGATCGATCG...")
.target(100, 200)
.build()
.unwrap();
let settings = PrimerSettings::builder()
.primer_opt_tm(60.0)
.primer_min_tm(57.0)
.primer_max_tm(63.0)
.product_size_range(75, 150)
.build()
.unwrap();
let result = design_primers(&seq_args, &settings, None, None).unwrap();
for pair in result.pairs() {
let left = pair.left();
let right = pair.right();
println!(
"Left: {} (Tm={:.1}), Right: {} (Tm={:.1}), Penalty={:.2}",
left.sequence(), left.tm(),
right.sequence(), right.tm(),
pair.penalty(),
);
}- Rust (see
rust-toolchain.tomlfor the pinned version) - C/C++ compiler (for compiling the vendored primer3 C library)
libclang(forbindgento generate FFI bindings)
git clone --recurse-submodules https://github.com/fg-labs/primer3-rs.git
cd primer3-rs
cargo build
cargo testInstall pre-commit hooks to run formatting and linting checks before each commit:
./scripts/install-hooks.shcargo ci-fmt # Check formatting
cargo ci-lint # Run clippy with strict settings
cargo ci-test # Run all testsprimer3-rs is licensed under GPL-2.0-or-later. All three crates in
this workspace (primer3-sys, primer3, primer3-tool) carry the same
license. See the warning at the top of this README for the practical
implications.
The upstream primer3 C library is licensed under GPL-2.0-or-later and its copyright holders have declined requests to relicense it under a more permissive license. Because primer3-rs statically compiles and links primer3's C source into the resulting artifacts, the entire workspace is a derivative work and must be distributed under a GPL-compatible license. We chose GPL-2.0-or-later (rather than GPL-2.0 only) to give downstream users the option of combining primer3-rs with GPL-3.0-compatible code, including Apache-2.0–licensed code, at their discretion.
If the GPL's copyleft obligations are incompatible with your project, the only
clean path is to not link against primer3-rs at all. Instead, invoke the
upstream primer3_core binary as a subprocess and communicate via the Boulder
I/O format on stdin/stdout. Running a GPL program as a separate process does
not impose GPL terms on the calling program, provided there is no intimate
linking (shared address space, shared data structures, etc.).
- primer3 -- the underlying C library for primer design
- primer3-py -- Python bindings that inspired this project's API surface