Registry / serialization / qs
library1.4.1jsnpmunverified

qs is a robust JavaScript library for parsing and stringifying URL query strings, with comprehensive support for nesting objects and arrays. It is currently on version 6.15.1 and maintains a steady release cadence with a focus on stability and security patches. Key differentiators include its configurable depth limits for parsing, the ability to handle URI-encoded strings, and built-in protections against prototype pollution through options like `plainObjects` and `allowPrototypes` (which is dangerous if enabled). Unlike the native `querystring` module in Node.js, `qs` offers more advanced features like array indexing and custom parsing/stringifying logic, making it suitable for complex data structures often found in web applications.

npm install qs
INSTALL
IMPORT
SIG · QS
Q
qs
serializationjavascriptv1.4.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

qs
const qs = require('qs');
import qs from 'qs';
CommonJS is the primary documented import style. While `import qs from 'qs'` generally works in modern environments due to bundler/Node.js interop, `require()` is explicitly shown in documentation examples and offers more direct compatibility.
qs.parse
const { parse } = require('qs');
import { parse } from 'qs';
The `qs` module exports a single default object. Named imports like `import { parse } from 'qs'` will not work directly as `parse` is a method of the default exported object, not a top-level named export. Destructuring from the `require`'d object is the correct way.
qs.stringify
const qs = require('qs'); const stringify = qs.stringify;
import { stringify } from 'qs';
`stringify` is a method on the default `qs` object. Attempting to directly import it as a named export will result in an error.

Demonstrates basic `qs.parse` and `qs.stringify` functionality, including nested objects, arrays, and the default depth limit behavior.

const qs = require('qs'); const assert = require('assert'); // Parsing a simple querystring let obj = qs.parse('a=c&b=d'); assert.deepEqual(obj, { a: 'c', b: 'd' }); // Stringifying an object let str = qs.stringify({ a: 'c', b: 'd' }); assert.equal(str, 'a=c&b=d'); // Parsing a nested object obj = qs.parse('foo[bar]=baz'); assert.deepEqual(obj, { foo: { bar: 'baz' } }); // Parsing an array obj = qs.parse('a=b&a=c'); assert.deepEqual(obj, { a: ['b', 'c'] }); // Demonstrating depth limit (default 5) const deepString = 'a[b][c][d][e][f][g]=h'; obj = qs.parse(deepString); assert.deepEqual(obj, { a: { b: { c: { d: { e: { f: { '[g]': 'h' } } } } } } }); console.log('All assertions passed!');
Debug
Known issues
breakingThe `allowDots` option's default value changed from `false` to `true` in `qs` v6.0.0. This means by default, query strings like `a.b=c` will now parse into `{ 'a.b': 'c' }` instead of `{ a: { b: 'c' } }` in previous versions. If you relied on dot notation for nested objects, you might need to explicitly set `allowDots: false` or update your parsing logic.
fix
If nested object parsing via dots is desired, set `qs.parse(str, { allowDots: false })`. If you were relying on `{ 'a.b': 'c' }` behavior and upgraded from v5, ensure your code handles the new default.
affects: >=6.0.0
breakingThe default `arrayLimit` for parsing arrays changed multiple times across major versions (e.g., to 20 in v5, and later). If your application parses arrays with more than the default limit of items (e.g., `a=1&a=2&...&a=21`), elements beyond the limit will be truncated or ignored, potentially leading to data loss if not handled.
fix
Always explicitly set `arrayLimit` in `qs.parse(str, { arrayLimit: <your_desired_limit> })` if you expect arrays with a variable or large number of elements to prevent unexpected truncation.
affects: >=5.0.0
gotchaBy default, `qs.parse` limits object nesting depth to 5 to prevent potential Denial of Service (DoS) attacks from excessively deep query strings. If a query string exceeds this depth, subsequent nested keys are concatenated into a single key, leading to unexpected parsed object structures.
fix
For deeply nested structures, provide a higher `depth` option to `qs.parse(string, { depth: <max_depth> })`. Consider also using `strictDepth: true` to throw an error instead of truncating, making unexpected depth explicit.
affects: >=0.6
breakingSetting `allowPrototypes: true` in `qs.parse` or `qs.stringify` can introduce severe prototype pollution vulnerabilities. This option allows user-controlled input to modify properties on `Object.prototype`, which can impact all objects in the application and lead to remote code execution or other critical security flaws.
fix
NEVER set `allowPrototypes: true` with untrusted user input. By default, `qs` prevents this. If you need to handle keys like `__proto__`, `constructor`, or `prototype` as actual data keys, use `plainObjects: true` to return a null-prototype object (`Object.create(null)`), which isolates the parsed data from the global `Object.prototype`.
affects: >=0.6
Errors
Common errors & fixes
TypeError: qs.parse is not a function
Attempting to use `qs.parse` or `qs.stringify` as a named import (e.g., `import { parse } from 'qs';`) instead of accessing it as a property of the default exported `qs` object.
fix
For CommonJS, use `const qs = require('qs'); const obj = qs.parse('...');`. For ESM, use `import qs from 'qs'; const obj = qs.parse('...');`.
Input depth exceeded depth option of X and strictDepth is true
The parsed querystring exceeded the maximum allowed nesting depth (`depth` option), and the `strictDepth` option was set to `true`, causing an error to be thrown instead of silently truncating the nested keys.
fix
Either increase the `depth` option to accommodate the expected nesting level (`qs.parse(str, { depth: <new_depth> })`) or adjust the input to reduce nesting. If truncation is acceptable, remove `strictDepth: true`.
Unexpected parsed object structure, e.g., `{ 'a[b]': 'c' }` instead of `{ a: { b: 'c' } }` or `{ 'a.b': 'c' }` instead of `{ a: { b: 'c' } }`
This often occurs due to misunderstanding the `allowDots` or `depth` options. For instance, `allowDots` defaults to `true` in v6, preventing dot notation from creating nested objects by default. The `depth` limit can also cause key concatenation.
fix
To parse `a.b=c` into `{ a: { b: 'c' } }`, use `qs.parse(str, { allowDots: false })`. To handle deep nesting, adjust the `depth` option (e.g., `qs.parse(str, { depth: 10 })`).
Upgrade
Version history
1.4.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
14 hits · last 30 days
node
12
OpenAI (training)
2
Resources