Functions for working with query strings.


stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
10Dec 1, 2017Mar 18, 2017Minified + gzip package size for @m59/qs in KB



Functions for working with query strings.

Build Status


$ npm install @m59/qs


import { stringify, parse, extract, replace } from '@m59/qs'

stringify({ crust: 'thin', toppings: ['pepperoni', 'pepperoni', 'bacon'] })
// => 'crust=thin&toppings=pepperoni&toppings=pepperoni&toppings=bacon'

// => { crust: 'thin', toppings: ['pepperoni', 'pepperoni', 'bacon'] }

// => 'breadsticks=please'

replace('http://pizza.pl0x?breadsticks=please#yum', queryString => 'breadsticks=seriously&marinara')
// => 'http://pizza.pl0x?breadsticks=seriously&marinara#yum'

array formats

stringify() can output array values in different formats. parse() will parse all of them.

A key with a bracket will always have a value that is an array, even if the key appears only once.

// "foo" appears once - treat as single value
parse('foo=a') // => { foo: 'a' }

// "foo" appears twice - treat as array
parse('foo=a&foo=b') // => { foo: [ 'a', 'b' ] }

// "foo" appears once, but has a bracket - treat as array
parse('foo[]=a') // => { foo: [ 'a' ] }

duplicate (default)

stringify({ foo: ['a', 'b', 'c'] }, { arrayFormat: 'duplicate' })
// => 'foo=a&foo=b&foo=c'


stringify({ foo: ['a', 'b', 'c'] }, { arrayFormat: 'bracket' })
// => 'foo[]=a&foo[]=b&foo[]=c'


Indices are only aesthetic. They do not necessarily correspond to array index. Items should appear in order.

stringify({ foo: ['a', 'b', 'c'] }, { arrayFormat: 'index' })
// => 'foo[0]=a&foo[1]=b&foo[2]=c'


Turn arrays into JSON strings.

stringify({ foo: [true, 123, 'abc', {x: false}] }, { arrayFormat: 'json' })
// => 'foo=%5Btrue%2C123%2C%22abc%22%2C%7B%22x%22%3Afalse%7D%5D'


Arrays can be output as a single key=value pair with the items joined by a delimiter.

stringify({ foo: ['a', 'b', 'c'] }, { arrayFormat: { delimiter: ';' } })
// => 'foo=a;b;c'

Values with delimiters can be parsed as arrays.

parse('foo=a;b;c', { delimiters: [';'] })
// => { foo: ['a', 'b', 'c'] }

If parse() is given multiple delimiters, the first given delimiter that exists in the value will be used to split it into an array.

parse('foo=a;b;c&bar=a,b,c&baz=,;,', { delimiters: [';', ','] })
// => { foo: ['a', 'b', 'c'], bar: ['a', 'b', 'c'], baz: [',', ','] }


Objects and nested arrays will be stringified as JSON. JSON strings are parsed back to objects by default.


According to RFC 1738, a space should be encoded as +, and + should be parsed back to a space. That specification was updated in 2005 by RFC 3986, which states that + should be encoded as UTF-8 %20. Query strings ought to adhere to 3986 and therefore the meaning of + in a query string is technically ambiguous. However, many query string encoders still encode spaces to +, so parsers must parse + as a space.


parse(queryString, options)

  • queryString: string a query string
  • options: object
    • json: boolean, true when a value is a JSON string, parse it to object
    • delimiters: [...strings], [] parse values as arrays when they contain a delimiter
    • plus: boolean, true when true (default), decode + into a space
  • => object parsed query string

stringify(object, options)

  • object: object object to be stringified into a query string
  • options: object
    • arrayFormat: string | object, 'duplicate'
      • 'duplicate'
      • 'bracket'
      • 'index'
      • { delimiter: string }
    • plus: boolean, false when true, encode spaces as +
  • => string query string


  • uri: string uri to extract the query string from
  • => string extracted query string

replace(uri, replacer, options)

  • uri: string uri to replace the query string in
  • replacer: string | function
    • string new query string value
    • replacer(queryString)
      • queryString: string the query string from uri or an empty string if uri does not have a query string
      • uri the uri argument passed to replace
      • => newQueryString: string new query string value
  • options: object
    • separator: boolean, false when true, the ? separator will be included in the replacement, so queryString passed to replacer will include it if it exists in uri, and it will be replaced in uri by replacer.
  • => string uri with the query string replaced

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.