bugl
bugl
HomeLearnPatternsPathsSearch
HomeLearnPatternsPathsSearch

Loading lesson path

Learn/Node.js/Core Modules
Node.js•Core Modules

Node.js DNS Module

Flash cards

Review the key moves

1/4
Core idea

What is the main idea behind Node.js DNS Module?

Lesson checks

Practice each idea before moving on

Short Mimo-style checks built from this lesson's code, terms, and sequence.

1Quick choice

Which statement best captures the main point of this lesson?

2Fill blank

Complete the missing token from the example code.

___ dns = require('dns');
3Order

Put the learning moves in the order that makes the concept easiest to apply.

Importing and Setup
Getting Started with DNS
Introduction to the DNS Module

Introduction to the DNS Module

The DNS (Domain Name System) module provides functionality for name resolution in Node.js.

It offers two main APIs

  • Callback-based API : Traditional Node.js style with callback functions
  • Promise-based API : Modern async/await support via dns.promises

Key features include

  • Resolving domain names to IP addresses (A/AAAA records)
  • Performing reverse DNS lookups (PTR records)
  • Querying various DNS record types (MX, TXT, SRV, etc.)
  • Creating custom DNS resolvers with specific settings
  • Configuring DNS server settings programmatically

Note

The DNS module can operate in two distinct modes - using the operating system's facilities or performing direct network DNS queries.

This affects how hostname resolution works in your application.

Getting Started with DNS

Here's a quick example of using the DNS module to look up a domain's IP address:

Basic DNS Lookup

const dns = require('dns');
// Look up a domain name
dns.lookup('example.com', (err, address, family) => {
 if (err) {
 console.error('Lookup error:', err);
 return;
 }
 console.log(`IP address: ${address}`);
 console.log(`IP version: IPv${family}`);
});

Importing and Setup

To use the DNS module, you can import it in your Node.js application using either the callback or promise-based API:

Callback-based API

// Import the DNS module
const dns = require('dns');
// Example usage dns.lookup('example.com', (err, address, family) => {
if (err) throw err;
console.log(`Resolved: ${address} (IPv${family})`);
});

Promise-based API (Node.js 10.0.0+)

// Import the promises API
const { promises: dns } = require('dns');
// Or: const dns = require('dns').promises;
// Example with async/await async function lookupDomain(domain) { try {
const address = await dns.lookup(domain);
console.log(`Resolved: ${address.address} (IPv${address.family})`);
} catch (err) {
console.error('Lookup failed:', err);
}
}
lookupDomain('example.com');

Note

The promise-based API is generally preferred for new code as it works better with modern async/await patterns and provides better error handling.

Basic DNS Lookups

The DNS module provides several methods for looking up domain names and IP addresses. The most common operations are:

  • dns.lookup() : Uses the operating system's facilities to resolve hostnames
  • dns.resolve*() : Performs DNS queries directly to name servers
  • dns.reverse() : Performs reverse DNS lookups (IP to hostname)

Resolving Domain Names to IP Addresses

const dns = require('dns');
// Callback-based API
dns.lookup('www.example.com', (err, address, family) => {
 if (err) throw err;
 console.log('IP address: %s', address);
 console.log('IP version: IPv%s', family);
});
const dns = require('dns').promises;
// Promise-based API
async function lookupExample() {
 try {
 const result = await dns.lookup('www.example.com');
 console.log('IP address:', result.address);
 console.log('IP version: IPv' + result.family);
 } catch (err) {
 console.error('Lookup failed:', err);
}
}
lookupExample();

Note

The dns.lookup() method uses the operating system's facilities for name resolution and does not necessarily perform any network communication.

Looking Up All IP Addresses for a Domain

const dns = require('dns');
// Get all IPv4 addresses
dns.resolve4('www.google.com', (err, addresses) => {
 if (err) throw err;
 console.log('IPv4 addresses:');
 addresses.forEach(address => {
 console.log(` ${address}`);
 });
 // Perform a reverse lookup on the first IP
 dns.reverse(addresses[0], (err, hostnames) => {
 if (err) throw err;
 console.log(`Reverse lookup for ${addresses[0]}:`);
 hostnames.forEach(hostname => {
 console.log(` ${hostname}`);
 });
 });
});

DNS Record Types

The DNS module supports lookups for various DNS record types:

MethodRecord TypeDescription
resolve4()AIPv4 addresses
resolve6()AAAAIPv6 addresses
resolveMx()MXMail exchange records
resolveTxt()TXTText records
resolveSrv()SRVService records
resolveNs()NSName server records
resolveCname()CNAMECanonical name records
resolveSoa()SOAStart of authority records
resolvePtr()PTRPointer records
resolveNaptr()NAPTRName authority pointer records
resolveAny()ANYAny records

Custom DNS Resolution

Create a custom DNS resolver with specific settings for more control over DNS lookups:

const dns = require('dns');
// Create a new resolver
const resolver = new dns.Resolver();
// Set custom server (Google's public DNS)
resolver.setServers(['8.8.8.8', '8.8.4.4']);
// Use the custom resolver
resolver.resolve4('www.example.com', (err, addresses) => {
 if (err) throw err;
 console.log('Addresses resolved using Google DNS:');
 addresses.forEach(addr => {
 console.log(` ${addr}`);
 });
});
// See what servers are configured
console.log('Current resolver servers:', resolver.getServers());

Note

Creating a custom resolver is useful when you want to use specific DNS servers instead of the system's defaults, or when you need different settings for different lookups.

Network vs. Operating System Level Resolution

The DNS module offers two different approaches to name resolution:

FunctionImplementationNetwork CallsUses
dns.lookup()Uses getaddrinfo() system callNo direct network callsFollows local configuration (hosts file, etc.)
dns.resolve*(), dns.reverse()Makes actual network requestsAlways connects to DNS serversBypasses local configuration, direct DNS queries

Warning

Due to these differences, the results from dns.lookup() and dns.resolve*() methods may not always match, especially in environments with custom host configurations.

Error Handling and Retries

Robust DNS handling requires proper error management. Here's how to handle common DNS errors and implement retry logic:

const dns = require('dns');
function lookupWithErrorHandling(domain) {
 dns.lookup(domain, (err, address, family) => {
 if (err) {
 console.error(`DNS lookup failed for ${domain}`);
 // Check specific error codes
 switch (err.code) {
 case 'ENOTFOUND':
 console.error(' Domain name not found');
 break;
 case 'ETIMEDOUT':
 console.error(' DNS lookup timed out');
 break;
 case 'ENODATA':
 console.error(' Domain exists but no data of requested type');
 break;
 case 'ESERVFAIL':
 console.error(' DNS server returned general failure');
 break;
 default:
 console.error(` Error code: ${err.code}`);
 }
 return;
 }
 console.log(`DNS lookup successful for ${domain}`);
 console.log(` IP address: ${address}`);
 console.log(` IP version: IPv${family}`);
 });
}
// Test with valid and invalid domains
lookupWithErrorHandling('www.google.com');
lookupWithErrorHandling('this-domain-does-not-exist-123456789.com');

Note

DNS errors can be temporary due to network issues or DNS propagation delays.

In production applications, you might want to implement retry logic with exponential backoff.

Performance Optimization

DNS lookups can be a performance bottleneck in applications. Here are strategies to optimize DNS resolution:

Caching

Implement a simple DNS cache to avoid repeated lookups for the same domain:

const dns = require('dns');
const util = require('util');
const lookup = util.promisify(dns.lookup);
const dnsCache = new Map();
async function cachedLookup(domain) {
 if (dnsCache.has(domain)) {
 console.log('Cache hit for:', domain);
 return dnsCache.get(domain);
 }
 console.log('Cache miss for:', domain);
 const result = await lookup(domain);
 dnsCache.set(domain, result);
 return result;
}
// Example usage (async () => {
const domains = ['google.com', 'facebook.com', 'google.com'];
for (const domain of domains) {
 const result = await cachedLookup(domain);
 console.log(`${domain} → ${result.address}`);
}
})();

Parallel Lookups

Use Promise.all() to perform multiple DNS lookups in parallel:

const dns = require('dns').promises;
async function lookupMultiple(domains) {
 try {
 const lookups = domains.map(domain => dns.lookup(domain));
 const results = await Promise.all(lookups);
 return domains.map((domain, i) => ({
 domain,
 ...results[i]
 }));
 } catch (err) {
 console.error('One or more lookups failed:', err);
 throw err;
}
}
// Example usage
lookupMultiple(['google.com', 'facebook.com', 'github.com'])
.then(results => console.log(results))
.catch(console.error);

Custom Resolvers and Timeouts

Configure custom DNS servers and timeouts for better control:

const dns = require('dns');
const { Resolver } = dns;
// Create a custom resolver with timeout
const resolver = new Resolver();
resolver.setServers(['8.8.8.8', '1.1.1.1']); // Google and Cloudflare DNS
// Set timeout for all operations (in ms)
const TIMEOUT = 2000;
async function resolveWithTimeout(domain, rrtype = 'A') {
 return new Promise((resolve, reject) => {
 const timer = setTimeout(() => {
 reject(new Error(`DNS query timed out after ${TIMEOUT}ms`));
 }, TIMEOUT);
 resolver.resolve(domain, rrtype, (err, addresses) => {
 clearTimeout(timer);
 if (err) return reject(err);
 resolve(addresses);
 });
 });
}
// Example usage
resolveWithTimeout('example.com')
.then(console.log)
.catch(console.error);

DNS Module vs. Third-Party DNS Libraries

FeatureNode.js DNS ModuleThird-Party Libraries
InstallationBuilt-in, no dependenciesRequires installation and management
Feature setBasic DNS operationsOften more comprehensive
CachingNot built-inOften includes caching
Advanced featuresLimitedMay include DNSSEC, DoH, DoT support
PerformanceGood for basic useMay be optimized for specific use cases

Popular third-party DNS libraries for Node.js include:

  • dns-packet : Low-level DNS packet encoding/decoding
  • native-dns : More complete DNS implementation
  • dns2 : Modern DNS library with promise support

Summary

The Node.js DNS module provides essential functionality for interacting with the Domain Name System. Key features include:

  • Looking up IP addresses for domain names
  • Resolving various DNS record types (A, AAAA, MX, TXT, etc.)
  • Performing reverse DNS lookups
  • Creating custom resolvers with specific settings
  • Both callback-based and promise-based APIs

Understanding the DNS module is crucial for applications that need to interact with network resources by domain name, implement custom name resolution logic, or verify domain-related information.

Previous

Node.js Timers Module

Next

Node.js Assert Module