SkillAgentSearch skills...

Tangerine

Node.js DNS over HTTPS - :tangerine: Tangerine is the best drop-in replacement for dns.promises.Resolver using DNS over HTTPS ("DoH") via undici with built-in retries, timeouts, smart server rotation, AbortControllers, and caching support for multiple backends (with TTL and purge support). Made for @forwardemail.

Install / Use

/learn @forwardemail/Tangerine

README

<h1 align="center"> <a href="https://github.com/forwardemail/nodejs-dns-over-https-tangerine"><img src="https://raw.githubusercontent.com/forwardemail/nodejs-dns-over-https-tangerine/main/media/header.png" alt="Tangerine" /></a> </h1> <div align="center"> <a href="https://github.com/forwardemail/nodejs-dns-over-https-tangerine/actions/workflows/ci.yml"><img src="https://github.com/forwardemail/nodejs-dns-over-https-tangerine/actions/workflows/ci.yml/badge.svg" alt="build status" /></a> <a href="https://github.com/sindresorhus/xo"><img src="https://img.shields.io/badge/code_style-XO-5ed9c7.svg" alt="code style" /></a> <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/styled_with-prettier-ff69b4.svg" alt="styled with prettier" /></a> <a href="https://lass.js.org"><img src="https://img.shields.io/badge/made_with-lass-95CC28.svg" alt="made with lass" /></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/forwardemail/nodejs-dns-over-https-tangerine.svg" alt="license" /></a> <a href="https://npm.im/tangerine"><img src="https://img.shields.io/npm/dt/tangerine.svg" alt="npm downloads" /></a> </div> <br /> <div align="center"> 🍊 <a href="https://github.com/forwardemail/nodejs-dns-over-https-tangerine" target="_blank">Tangerine</a> is the best <a href="https://nodejs.org" target="_blank">Node.js</a> drop-in replacement for <a href="https://nodejs.org/api/dns.html#resolveroptions" target="_blank">dns.promises.Resolver</a> using <a href="https://en.wikipedia.org/wiki/DNS_over_HTTPS" target="_blank">DNS over HTTPS</a> ("DoH") via <a href="https://github.com/nodejs/undici" target="_blank">undici</a> with built-in retries, timeouts, smart server rotation, <a href="https://developer.mozilla.org/en-US/docs/Web/API/AbortController" target="_blank">AbortControllers</a>, and caching support for multiple backends (with TTL and purge support). </div> <hr /> <div align="center"> ⚡ <a href="#tangerine-benchmarks"><i><u><strong>AS FAST AS</strong></u></i></a> native <a href="https://nodejs.org/api/dns.html" target="_blank">Node.js <code>dns</code></a>! 🚀 &bull; Supports Node v18+ with ESM/CJS &bull; Made for <a href="https://forwardemail.net" target="_blank"><strong>Forward Email</strong></a>. </div> <hr />

Table of Contents

Install

npm install tangerine undici
-import dns from 'dns';
+import Tangerine from 'tangerine';

- const resolver = new dns.promises.Resolver();
+const resolver = new Tangerine();

Foreword

What is this project about

Our team at Forward Email (100% open-source and privacy-focused email service) needed a better solution for DNS.

After years of using the Node.js internal DNS module, we ran into these recurring patterns:

  • Cloudflare and Google now have DNS over HTTPS servers ("DoH") available – and browsers such as Mozilla Firefox now have it enabled by default.
  • DNS cache consistency across multiple servers cannot be easily accomplished using packages such as unbound, dnsmasq, and bind – and configuring /etc/resolv.conf across multiple Ubuntu versions is not enjoyable (even with Ansible). Maintaining logic at the application layer is much easier from a development, deployment, and maintenance perspective.
  • Privacy, security, and caching approaches needed to be constantly scaled, re-written, and re-configured.
  • Our development teams would encounter unexpected 75 second delays while making DNS requests (if they were connected to a VPN and forgot they were behind blackholed DNS servers – and attempting to use patterns such as dns.setServers(['1.1.1.1'])). The default timeout if you are behind a blackholed DNS server in Node.js is 75 seconds (due to c-ares under the hood with 5, 10, 20, and 40 second retry backoff timeout strategy).
  • There are zero existing DNS over HTTPS ("DoH") Node.js npm packages that:
    • Utilize modern open-source software under the MIT license and are currently maintained.
    • Act as a 1:1 drop-in replacement for dns.promises.Resolver with DNS over HTTPS ("DoH").
    • Support caching for multiple backends (with TTL and purge support), retries, smart server rotation, and AbortController usage.
    • Provide out of the box support for both ECMAScript modules (ESM) and CommonJS (CJS) (see discussions for and against).
  • The native Node.js dns module does not support caching out of the box – which is a highly requested feature (but belongs in userland).
  • Writing tests against DNS-related infrastructure requires either hacky DNS mocking or a DNS server (manipulating cache is much easier).
  • <u>The Node.js community is lacking a high-quality and dummy-proof userland DNS package with sensible defaults.</u>

Why integrate DNS over HTTPS

With DNS over HTTPS (DoH), DNS queries and responses are encrypted and sent via the HTTP or HTTP/2 protocols. DoH ensures that attackers cannot forge or alter DNS traffic. DoH uses port 443, which is the standard HTTPS traffic port, to wrap the DNS query in an HTTPS request. DNS queries and responses are camouflaged within other HTTPS traffic, since it all comes and goes from the same port. – Cloudflare

DNS over HTTPS (DoH) is a protocol for performing remote Domain Name System (DNS) resolution via the HTTPS protocol. A goal of the method is to increase user privacy and security by preventing eavesdropping and manipulation of DNS data by [man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-midd

View on GitHub
GitHub Stars201
CategoryCustomer
Updated6h ago
Forks13

Languages

JavaScript

Security Score

100/100

Audited on Mar 28, 2026

No findings