Query specific DNS server in nodejs with native-dns

01 Mar 2012

Ataraxia Consulting

The DNS options available to node.js are a little slim. They only provide a wrapper to c-ares to the point of doing the simplest of record type lookups. There’s not a useful or more granular interface for customizing your queries than to modify your platform’s equivalent of /etc/resolv.conf.

With the idea of customization in mind I created native-dns. Which is an implementation of a DNS stack in pure javascript. Below you’ll find a quick example of how to query the google public DNS servers for the A records for “www.google.com”. To install native-dns you simply need to “npm install native-dns”.

var dns = require('native-dns'),
  util = require('util');

var question = dns.Question({
  name: 'www.google.com',
  type: 'A', // could also be the numerical representation

var start = new Date().getTime();

var req = dns.Request({
  question: question,
  server: '',
  // Optionally you can define an object with these properties,
  // only address is required
  server: { address: '', port: 53, type: 'udp' },
  timeout: 1000, /* Optional -- default 4000 (4 seconds) */

req.on('timeout', function () {
  console.log('Timeout in making request');

req.on('message', function (err, res) {
  /* answer, authority, additional are all arrays with ResourceRecords */
  res.answer.forEach(function (a) {
    /* promote goes from a generic ResourceRecord to A, AAAA, CNAME etc */

req.on('end', function () {
  /* Always fired at the end */
  var delta = (new Date().getTime()) - start;
  console.log('Finished processing request: ' + delta.toString() + 'ms');


/* You could also req.cancel() which will emit 'cancelled' */

You of course can use native-dns as a drop in replacement of the builtin ‘dns’ module. And there is even a very basic DNS server which you can use to respond to DNS requests, semantics of which are beyond the module itself.

You can find the source and more information and examples at the github repository which is named node-dns because I created it before I realized that was taken in npm.