> ## Documentation Index
> Fetch the complete documentation index at: https://proto.evodesign.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Primer3

> [primer3-py](https://github.com/libnano/primer3-py) is a Cython binding to the [Primer3](https://primer3.org/) C library for oligonucleotide thermodynamics. This tool wraps its nearest-neighbor calculators to score a DNA oligo (and an optional partner) for melting temperature, hairpin and dimer stability, GC content, and 3' GC-clamp — the core filters used to judge whether a primer is fit for [qPCR](https://en.wikipedia.org/wiki/Real-time_polymerase_chain_reaction) and general PCR.

<div class="page-hero"><img class="page-hero-banner" src="https://proto-bio.github.io/proto-assets/images/tool/primer3/hero.png" alt="Primer3" /><div class="tool-org-badges page-hero-badges"><a href="/docs/tools/organizations/libnano" class="tool-org-badge" style={{background: "#3F6C51"}} title="libnano"><img src="https://mintcdn.com/bio-pro/2KNs-ARSUr3ypt0h/assets/images/cached/e0098a8ddf41.png?fit=max&auto=format&n=2KNs-ARSUr3ypt0h&q=85&s=5f109dcb2938e98ac0db2436e4d7f9da" alt="" class="tool-org-badge-logo" width="420" height="420" data-path="assets/images/cached/e0098a8ddf41.png" /> libnano</a></div></div>

<Note>
  **License:** Primer3 has a GPL-2.0 license. Please refer to [the license](https://github.com/libnano/primer3-py/blob/master/LICENSE) for full terms.
</Note>

<p class="entity-disclaimer">Proto is not affiliated with libnano. This toolkit is open source and builds on the implementation produced by this organization. Product names, logos, and trademarks are the property of their respective owners.</p>

<hr class="entity-rule" />

<input type="radio" name="tab-primer3" id="none-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="github-primer3" class="tab-radio-input" defaultChecked />

<input type="radio" name="tab-primer3" id="website-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="paper-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="cite-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="source-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="notebook-primer3" class="tab-radio-input" />

<input type="radio" name="tab-primer3" id="proto-primer3" class="tab-radio-input" />

<div class="tool-tab-bar">
  <span class="tool-tab-wrap"><label for="github-primer3" class="tool-tab tab-open badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label><label for="none-primer3" class="tool-tab tab-close badge-github"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> GitHub</label></span> <span class="tool-tab-wrap"><label for="website-primer3" class="tool-tab tab-open badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label><label for="none-primer3" class="tool-tab tab-close badge-website"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Website</label></span> <span class="tool-tab-wrap"><label for="paper-primer3" class="tool-tab tab-open badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label><label for="none-primer3" class="tool-tab tab-close badge-paper"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Publication</label></span> <span class="tool-tab-wrap"><label for="cite-primer3" class="tool-tab tab-open badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label><label for="none-primer3" class="tool-tab tab-close badge-cite"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Cite</label></span> <span class="tool-tab-wrap"><label for="source-primer3" class="tool-tab tab-open badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label><label for="none-primer3" class="tool-tab tab-close badge-source"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Tool Source</label></span> <span class="tool-tab-wrap"><label for="notebook-primer3" class="tool-tab tab-open badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label><label for="none-primer3" class="tool-tab tab-close badge-notebook"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open as Notebook</label></span> <span class="tool-tab-wrap"><label for="proto-primer3" class="tool-tab tab-open badge-proto"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></svg> Open on Proto</label><label for="none-primer3" class="tool-tab tab-close badge-proto"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" /></svg> Open on Proto</label></span>
</div>

<a href="https://github.com/libnano/primer3-py" target="_blank" class="tab-panel github-panel" data-tab="github-primer3">
  <div class="gh-card-wrap">
    <img src="https://opengraph.githubassets.com/1/libnano/primer3-py" class="gh-card-img img-fallback" alt="libnano/primer3-py" />

    <div class="gh-card-fallback">
      <div class="gh-fallback-org"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> libnano/primer3-py</div>
    </div>
  </div>

  <span class="panel-goto-btn gh-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View repo</span></span>
</a>

<a href="https://primer3.org" target="_blank" class="tab-panel website-panel" data-tab="website-primer3">
  <div class="website-info">
    <img src="https://www.google.com/s2/favicons?domain=primer3.org&sz=32" class="website-favicon" width="24" height="24" />

    <span class="website-url">primer3.org</span>
  </div>

  <span class="panel-goto-btn website-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg> Visit website</span></span>
</a>

<a href="https://doi.org/10.1093/nar/gks596" target="_blank" class="tab-panel paper-panel" data-tab="paper-primer3">
  <div class="paper-info">
    <div class="paper-title">Primer3--new capabilities and interfaces</div>
    <div class="paper-meta">Andreas Untergasser, Ioana Cutcutache, ... Steven G. Rozen</div>
    <div class="paper-meta paper-venue">Nucleic Acids Research (2012)</div>
  </div>

  <span class="panel-goto-btn pub-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><polyline points="14 2 14 8 20 8" /><line x1="16" y1="13" x2="8" y2="13" /><line x1="16" y1="17" x2="8" y2="17" /><polyline points="10 9 9 9 8 9" /></svg> Read paper</span></span>
</a>

<div class="tab-panel cite-panel" data-tab="cite-primer3">
  <div class="cite-code-wrap">
    ```bibtex theme={null}
    @article{untergasser2012primer3,
      title={Primer3--new capabilities and interfaces},
      author={Untergasser, Andreas and Cutcutache, Ioana and Koressaar, Triinu and Ye, Jian and Faircloth, Brant C. and Remm, Maido and Rozen, Steven G.},
      journal={Nucleic Acids Research},
      volume={40},
      number={15},
      pages={e115},
      year={2012},
      publisher={Oxford University Press},
      doi={10.1093/nar/gks596}
    }
    ```
  </div>

  <span class="panel-goto-btn cite-copy-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z" /><path d="M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z" /></svg> Copy citation</span></span>
</div>

<a href="https://github.com/evo-design/proto-tools/tree/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3" target="_blank" class="tab-panel source-panel" data-tab="source-primer3">
  <div class="source-info">
    <img src="https://github.com/evo-design.png?size=40" class="source-avatar" width="36" height="36" />

    <span class="source-path">evo-design/proto-tools<span class="source-subpath">/proto\_tools/tools/sequence\_scoring/primer3</span></span>
  </div>

  <span class="panel-goto-btn source-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" /></svg> View source</span></span>
</a>

<a href="https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/examples/example.ipynb" target="_blank" class="tab-panel notebook-panel" data-tab="notebook-primer3">
  <div class="notebook-info">
    <span class="notebook-icon">
      <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
        <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" />

        <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" />
      </svg>
    </span>

    <span class="notebook-label">Open Notebook</span>
  </div>

  <span class="panel-goto-btn notebook-goto-btn"><span><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg> Open notebook</span></span>
</a>

<div class="tab-panel proto-panel" data-tab="proto-primer3">
  <div class="proto-info">
    <div class="proto-cloud">
      <svg class="proto-cloud-bg" viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg">
        <path d="M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z" />
      </svg>

      <img noZoom src="https://mintcdn.com/bio-pro/KVh0EKV-IKblvXR8/assets/logo/evo-logo-light.svg?fit=max&auto=format&n=KVh0EKV-IKblvXR8&q=85&s=0cb66034ba45618505501aee6ea5f5c1" class="proto-panel-logo block dark:hidden" alt="Proto" width="198" height="151" data-path="assets/logo/evo-logo-light.svg" />

      <img noZoom src="https://mintcdn.com/bio-pro/KVh0EKV-IKblvXR8/assets/logo/evo-logo-dark.svg?fit=max&auto=format&n=KVh0EKV-IKblvXR8&q=85&s=2c9e23a14635e60384a434e220788f54" class="proto-panel-logo hidden dark:block" alt="Proto" width="198" height="151" data-path="assets/logo/evo-logo-dark.svg" />
    </div>
  </div>

  <div class="proto-actions">
    <a href="https://proto.evodesign.org/tools/primer3-thermodynamics" target="_blank" class="proto-action-btn"><span>Primer3 Thermodynamics</span><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="17" x2="17" y2="7" /><polyline points="7 7 17 7 17 17" /></svg></a>
  </div>
</div>

<div class="entity-contributors"><span class="entity-contributors-label">Toolkit contributors</span><span class="entity-contributors-people"><a class="entity-contributor" href="https://github.com/nndahiro" target="_blank" rel="noopener" title="nndahiro: 1 commit"><img noZoom class="entity-contributor-avatar" src="https://avatars.githubusercontent.com/u/62033429?v=4&s=64" alt="" loading="lazy" /><span class="entity-contributor-login">nndahiro</span></a></span></div>

| Function                       | Description                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------ | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `run_primer3_thermodynamics()` | Score DNA oligos for Tm, hairpin/homodimer/heterodimer ΔG, GC content, and GC-clamp | <a href="#api-run-primer3-thermodynamics" class="func-table-btn func-api-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20" /></svg> Docs</a> <a href="https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/primer3_thermodynamics.py#L248" target="_blank" class="func-table-btn func-source-btn"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a> |

## Background

Primer3 ([Untergasser et al., 2012](https://doi.org/10.1093/nar/gks596)) is the de-facto standard engine for primer design and evaluation. Its thermodynamic calculations use the [nearest-neighbor model](https://en.wikipedia.org/wiki/Nucleic_acid_thermodynamics), which predicts duplex stability from the stacking energies of adjacent base pairs rather than a naive base count, and applies salt and concentration corrections so that the predicted [melting temperature](https://en.wikipedia.org/wiki/Nucleic_acid_thermodynamics#Melting_temperature) reflects the actual reaction buffer. The free energy (ΔG) of a self-folded hairpin, a self-dimer (homodimer), or a cross-dimer between two oligos (heterodimer) is reported in kcal/mol: a more negative ΔG means a more stable — and therefore more problematic — secondary structure that competes with productive priming.

For a primer to amplify cleanly, its melting temperature must sit in a workable band, its two ends should not fold back on themselves or pair with a partner, and its 3' end should anchor stably to the template. These constraints are what the metrics below quantify. A ΔG of `0.0` with the corresponding structure flag `False` is the favorable case: no significant structure was found. Thermodynamic conditions (monovalent and divalent cation, dNTP, and oligo concentrations) shift every prediction, so they are exposed as configuration and default to Primer3's own defaults for reproducibility against the upstream tool.

### Learning Resources

* [primer3-py documentation](https://libnano.github.io/primer3-py/) (libnano) - API reference for the `calc_tm`, `calc_hairpin`, `calc_homodimer`, and `calc_heterodimer` functions wrapped here, including every thermodynamic parameter.
* [Primer3 manual](https://primer3.org/manual.html) (Untergasser, Rozen, et al.) - the authoritative description of Primer3's parameters, salt-correction formulas, and design logic.
* [Top ten pitfalls in quantitative real-time PCR primer/probe design](https://www.thermofisher.com/us/en/home/references/ambion-tech-support/rtpcr-analysis/general-articles/top-ten-pitfalls-in-quantitative-real-time-pcr-primer.html) (Thermo Fisher) - practical target ranges and failure modes for qPCR assay design.

## Tools

<a name="api-run-primer3-thermodynamics" />

<div class="tool-section-card">
  ### Primer3 Thermodynamics (`primer3-thermodynamics`)

  Scores each input DNA oligo for melting temperature, hairpin/homodimer ΔG, GC content, and 3' GC-clamp, plus heterodimer ΔG against an optional partner oligo.

  #### API Reference

  <div class="api-model-section api-input-section">
    <a href="https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/primer3_thermodynamics.py#L114" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Input: Primer3ThermodynamicsInput">
      <ParamField path="oligos" type="List[Primer3Oligo]" required>
        Oligos to score. A bare DNA string, a `{"sequence": ..., "partner": ...}` dict, or a single oligo are all accepted and coerced to a one-element list. Results are returned in input order.

        <Expandable title="Primer3Oligo">
          <ParamField path="sequence" type="string" required>
            DNA oligo (A/C/G/T only). Scored for Tm, hairpin, homodimer, GC content, and 3' GC-clamp.
          </ParamField>

          <ParamField path="partner" type="string">
            Optional second oligo. When set, heterodimer ΔG is computed between `sequence` and `partner` (e.g. a forward primer with its reverse partner). None ⇒ heterodimer\_dg is null.
          </ParamField>
        </Expandable>
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-config-section">
    <a href="https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/primer3_thermodynamics.py#L141" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Config: Primer3ThermodynamicsConfig">
      <ParamField path="mv_conc" type="number" default="50.0">
        Monovalent cation concentration in mM. Default 50.0.
      </ParamField>

      <ParamField path="dv_conc" type="number" default="1.5">
        Divalent cation (Mg2+) concentration in mM. Default 1.5.
      </ParamField>

      <ParamField path="dntp_conc" type="number" default="0.6">
        dNTP concentration in mM. Default 0.6.
      </ParamField>

      <ParamField path="dna_conc" type="number" default="50.0">
        Oligo (DNA) concentration in nM. Default 50.0.
      </ParamField>

      <ParamField path="temp_c" type="number" default="37.0">
        Temperature in °C for hairpin/dimer ΔG. Default 37.0.
      </ParamField>

      <ParamField path="verbose" type="integer" default="0">
        Verbosity level (0=quiet, 1=info, 2=debug, 3=raw subprocess stderr). `True` is coerced to `1` and `False` to `0`.
      </ParamField>

      <ParamField path="device" type="string" default="cpu">
        Device to run the tool on.
      </ParamField>

      <ParamField path="timeout" type="integer" default="3600">
        Maximum execution time in seconds. `None` waits indefinitely.
      </ParamField>

      <ParamField path="seed" type="integer">
        Random seed. When set, tools run reproducibly up to small GPU float noise (see `BaseToolOutput.approx_equal`), and the seed participates in cache keys. When None, cacheable seed-sensitive tools skip cache until seeded.
      </ParamField>
    </Accordion>
  </div>

  <div class="api-model-section api-output-section">
    <a href="https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/primer3_thermodynamics.py#L188" target="_blank" class="func-table-btn func-source-btn api-model-source"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg> Source</a>

    <Accordion title="Output: Primer3ThermodynamicsOutput">
      <ResponseField name="results" type="List[Primer3OligoResult]">
        Per-oligo scores, in input order.

        <Expandable title="Primer3OligoResult">
          <ResponseField name="oligo_id" type="string" required>
            Positional label of the input oligo (`oligo_0` ...).
          </ResponseField>

          <ResponseField name="length" type="integer" required>
            Oligo length in nucleotides.
          </ResponseField>

          <ResponseField name="tm" type="number" required>
            Melting temperature in °C.
          </ResponseField>

          <ResponseField name="hairpin_dg" type="number" required>
            Hairpin ΔG in kcal/mol (more negative = more stable).
          </ResponseField>

          <ResponseField name="homodimer_dg" type="number" required>
            Self-dimer ΔG in kcal/mol.
          </ResponseField>

          <ResponseField name="heterodimer_dg" type="number">
            Cross-dimer ΔG with the partner, or None when no partner was supplied.
          </ResponseField>

          <ResponseField name="gc_content" type="number" required>
            Fraction of G/C bases, 0-1.
          </ResponseField>

          <ResponseField name="gc_clamp" type="boolean" required>
            True if either of the last two 3' bases is G or C.
          </ResponseField>

          <ResponseField name="hairpin_structure_found" type="boolean" required>
            Whether a hairpin structure was found.
          </ResponseField>

          <ResponseField name="homodimer_structure_found" type="boolean" required>
            Whether a homodimer structure was found.
          </ResponseField>

          <ResponseField name="heterodimer_structure_found" type="boolean">
            Whether a heterodimer was found, or None when no partner was supplied.
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Accordion>
  </div>

  #### Applications

  Use this to screen candidate PCR and qPCR primers before ordering them, or as the scoring step inside a primer-selection pipeline. Pair a forward primer with its reverse as its `partner` to check the primer *pair* for cross-dimerization, the most common cause of a failed or noisy amplification.

  #### Usage Tips

  * **For qPCR, aim for Tm 58–62 °C, GC 40–60%, and a GC clamp.** Keep the two primers of a pair within \~1 °C of each other. `gc_clamp=True` (a G or C in the last two 3' bases) helps 3' anchoring, but avoid more than three G/C in the last five bases to prevent mispriming.
  * **Treat ΔG thresholds as guidelines: hairpin > −2 kcal/mol, homodimer and heterodimer > −6 kcal/mol.** More negative values indicate stable competing structures. Because ΔG depends on temperature, set `temp_c` to your annealing temperature (default 37 °C) for the most relevant hairpin/dimer numbers.
  * **Defaults match primer3-py, not a qPCR preset.** `dv_conc=1.5`, `dntp_conc=0.6`, and `dna_conc=50` reproduce Primer3 directly. Typical qPCR conditions are closer to `dv_conc≈3`, `dntp_conc≈0.8`, `dna_conc≈200–250`; set them explicitly to match your master mix, since they shift Tm and every ΔG.
</div>

## Toolkit Notes

These apply to the Primer3 tool in this toolkit (`primer3-thermodynamics`).

* **Runs on CPU, no model weights.** primer3-py compiles the Primer3 C library into its wheel, so a single `pip install` provides everything; there is no GPU path and nothing to download at first use.
* **Inputs are strictly A/C/G/T.** Sequences are uppercased and validated; degenerate bases (`N`, IUPAC ambiguity codes) are rejected because the nearest-neighbor model needs concrete bases.
* **Scoring is per-oligo and batchable.** Pass a list of oligos to score them in one call; results are returned in input order. Bundle a `partner` with an oligo to compute its heterodimer ΔG.

<Tip>
  **Example notebook:** See the [full working example](https://github.com/evo-design/proto-tools/blob/55339880a8d5da4f1c7677518bcf90974a6365b7/proto_tools/tools/sequence_scoring/primer3/examples/example.ipynb) for a copy-paste-ready walkthrough.
</Tip>

## Infrastructure Guides

The following guides cover how to run tools efficiently and at scale.

<CardGroup cols={2}>
  <Card title="Tool Persistence" icon="repeat" href="/docs/tools/guides/tool-persistence">Keep a tool's model warm across calls instead of reloading it every invocation.</Card>
  <Card title="Device Management" icon="cpu" href="/docs/tools/guides/device-management">How GPUs are allocated to tools and how to target specific devices.</Card>
  <Card title="Parallel Execution" icon="layers" href="/docs/tools/guides/parallel-execution">Fan a batch of inputs out across multiple GPUs.</Card>
</CardGroup>
