Skip to main content
The node:querystring module provides utilities for parsing and formatting URL query strings. It’s optimized for performance but is not a standardized API.
For new applications, consider using URLSearchParams for standards compliance. Use querystring when performance is critical or working with legacy code.

Installation

import querystring from 'node:querystring';
// or
const querystring = require('node:querystring');

Parsing Query Strings

querystring.parse(str[, sep[, eq[, options]]])

Parses a URL query string into an object of key-value pairs. Parameters:
  • str - The URL query string to parse
  • sep - Delimiter for key-value pairs (default: '&')
  • eq - Delimiter between keys and values (default: '=')
  • options
    • decodeURIComponent - Custom decoding function (default: querystring.unescape())
    • maxKeys - Maximum number of keys to parse (default: 1000, use 0 for unlimited)
Returns: - Parsed object Examples:
import querystring from 'node:querystring';

// Basic parsing
const parsed = querystring.parse('foo=bar&abc=xyz&abc=123');
console.log(parsed);
// { foo: 'bar', abc: ['xyz', '123'] }

// Multiple values for same key
const multi = querystring.parse('name=John&age=30&name=Jane');
console.log(multi);
// { name: ['John', 'Jane'], age: '30' }

// Custom separators
const custom = querystring.parse('foo:bar;baz:qux', ';', ':');
console.log(custom);
// { foo: 'bar', baz: 'qux' }

querystring.decode()

Alias for querystring.parse().
const decoded = querystring.decode('key=value');
// Same as querystring.parse('key=value')

Formatting Query Strings

querystring.stringify(obj[, sep[, eq[, options]]])

Serializes an object into a URL query string. Parameters:
  • obj - The object to serialize
  • sep - Delimiter for key-value pairs (default: '&')
  • eq - Delimiter between keys and values (default: '=')
  • options
    • encodeURIComponent - Custom encoding function (default: querystring.escape())
Returns: - URL query string Supported types: string, number, bigint, boolean, and arrays of these types Examples:
import querystring from 'node:querystring';

// Basic stringification
const str = querystring.stringify({ foo: 'bar', baz: 'qux' });
console.log(str);
// 'foo=bar&baz=qux'

// Array values
const arr = querystring.stringify({ colors: ['red', 'blue', 'green'] });
console.log(arr);
// 'colors=red&colors=blue&colors=green'

// Custom separators
const custom = querystring.stringify(
  { foo: 'bar', baz: 'qux' },
  ';',
  ':'
);
console.log(custom);
// 'foo:bar;baz:qux'

// Empty values
const empty = querystring.stringify({ foo: '', bar: 'value' });
console.log(empty);
// 'foo=&bar=value'

querystring.encode()

Alias for querystring.stringify().
const encoded = querystring.encode({ key: 'value' });
// Same as querystring.stringify({ key: 'value' })

Encoding and Decoding

querystring.escape(str)

Performs URL percent-encoding optimized for query strings. Parameters:
  • str - String to encode
Returns: - Percent-encoded string Example:
const escaped = querystring.escape('hello world!');
console.log(escaped);
// 'hello%20world!'

const specialChars = querystring.escape('foo=bar&baz');
console.log(specialChars);
// 'foo%3Dbar%26baz'

querystring.unescape(str)

Decodes URL percent-encoded characters. Parameters:
  • str - String to decode
Returns: - Decoded string Example:
const unescaped = querystring.unescape('hello%20world');
console.log(unescaped);
// 'hello world'

const decoded = querystring.unescape('foo%3Dbar%26baz');
console.log(decoded);
// 'foo=bar&baz'

Common Use Cases

Parsing URL Query Parameters

import querystring from 'node:querystring';
import { parse } from 'node:url';

const url = 'https://example.com/search?q=nodejs&page=2&sort=date';
const parsedUrl = parse(url);
const params = querystring.parse(parsedUrl.query);

console.log(params);
// { q: 'nodejs', page: '2', sort: 'date' }

console.log(params.q); // 'nodejs'
console.log(params.page); // '2'

Building URLs with Query Parameters

import querystring from 'node:querystring';

function buildApiUrl(baseUrl, params) {
  const query = querystring.stringify(params);
  return `${baseUrl}?${query}`;
}

const url = buildApiUrl('https://api.example.com/users', {
  page: 1,
  limit: 10,
  sort: 'name'
});

console.log(url);
// 'https://api.example.com/users?page=1&limit=10&sort=name'

Handling Form Data

import querystring from 'node:querystring';

// Parse form submission
const formData = 'username=john&email=john%40example.com&age=30';
const fields = querystring.parse(formData);

console.log(fields);
// { username: 'john', email: '[email protected]', age: '30' }

// Create form data
const userData = {
  username: 'jane',
  email: '[email protected]',
  age: 25
};

const encoded = querystring.stringify(userData);
console.log(encoded);
// 'username=jane&email=jane%40example.com&age=25'

Custom Encoding for Special Characters

import querystring from 'node:querystring';

// Custom encoding function
function customEncode(str) {
  return encodeURIComponent(str).replace(/%20/g, '+');
}

const data = { search: 'hello world', filter: 'type:article' };

const encoded = querystring.stringify(data, null, null, {
  encodeURIComponent: customEncode
});

console.log(encoded);
// 'search=hello+world&filter=type%3Aarticle'

Limiting Number of Keys

import querystring from 'node:querystring';

// Limit to prevent DoS attacks
const maliciousInput = 'a=1&b=2&c=3&d=4&e=5';

const limited = querystring.parse(maliciousInput, null, null, {
  maxKeys: 3
});

console.log(limited);
// { a: '1', b: '2', c: '3' }
// Keys d and e are ignored

// Unlimited parsing (use with caution)
const unlimited = querystring.parse(maliciousInput, null, null, {
  maxKeys: 0
});

console.log(unlimited);
// { a: '1', b: '2', c: '3', d: '4', e: '5' }

querystring vs URLSearchParams

Performance Comparison

import querystring from 'node:querystring';

// querystring (faster, Node.js specific)
const qs = querystring.parse('foo=bar&baz=qux');

// URLSearchParams (standard, works in browsers)
const params = new URLSearchParams('foo=bar&baz=qux');
const obj = Object.fromEntries(params);

When to Use Each

Use querystring when:
  • Performance is critical
  • Working with legacy Node.js code
  • Need custom separators
  • Building high-performance APIs
Use URLSearchParams when:
  • Need browser compatibility
  • Want standards compliance
  • Building isomorphic/universal apps
  • Performance is not critical

Best Practices

  1. Validate input - Always validate and sanitize parsed query strings
  2. Set maxKeys - Prevent DoS attacks by limiting keys
  3. Handle arrays - Check if values are arrays when needed
  4. Type conversion - Remember all values are strings; convert as needed
  5. Encoding - Ensure proper encoding of special characters

Security Considerations

import querystring from 'node:querystring';

// Always set maxKeys for untrusted input
function parseUserInput(query) {
  return querystring.parse(query, null, null, {
    maxKeys: 100 // Reasonable limit
  });
}

// Validate and sanitize
function sanitizeParams(params) {
  const safe = {};
  
  for (const [key, value] of Object.entries(params)) {
    // Whitelist allowed parameters
    if (['page', 'limit', 'sort'].includes(key)) {
      safe[key] = Array.isArray(value) ? value[0] : value;
    }
  }
  
  return safe;
}
  • URL - URL parsing and manipulation
  • http - HTTP server and client
  • URLSearchParams - Web standard query string API