Replacing query-string with Native URLSearchParams
Tags: javascript, node, webdev, npm
Published: 2021-02-11 19:33:29

[`query-string`](https://www.npmjs.com/package/query-string) is an awesome package which allows you to parse URL parameters, however, you may not need it anymore.

[`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) is a **native** interface to easily parse and construct URL parameters in both Node and the browser!

## Usage

The syntax is *slightly* more verbose than `query-string` in places, however, the benefit of a native solution to that of an external dependency outweighs the verbosity.

### Setting Parameters

Parameters can be set both at and after instantiation.

```js
const params = new URLSearchParams({ foo: "" });
// { foo: "" }
params.set('hello', 'world');
// { foo: "", hello: "world" }
params.set('foo', 'bar');
// { foo: "bar", hello: "world" }
```

### Getting Parameters

`URLSearchParams` returns an `iterator` to get values.

The simplest way to get the parameters as an Object is to use `Object.FromEntries` on the interface instance:

```js
const params = new URLSearchParams('?one&foo=bar');

// Get all values.
const parsedParams = Object.fromEntries(params);
// { one: "", foo: "bar" }

// Get a specific value.
params.get('foo');
// "bar"
``` 

### Differences in Implementation

#### Symbols

`query-string` removes leading `#` symbols - `URLSearchParams` does not.

```js
const query = querystring('#foo=bar');
// { foo: "bar" } 

const params = new URLSearchParams('#foo=bar');
// { #foo: "bar" } 
```

#### Implicit Parameter Values

Implicit parameters (parameters without `=`) will evaluate to  `null` with `query-string` and an empty string with `URLSearchParams`.

```js
const queryString = querystring.parse('?implicit&explicit=');
// { implicit: null, explicit: "" }

const params = new URLSearchParam('?implicit&explicit=');
// { implicit: "", explicit: "" }
```

#### Array Values

`query-string` has advanced utilities to parse array values, for example:

```js
queryString.parse('?foo[]=bar&foo[]=baz', { arrayFormat: 'bracket' });
//=> {foo: ['1', '2', '3']}
```

`URLSearchParams` doesn't ship with array utilities so you need to roll your own function to get the full values back from arrays.

```ts
/**
 * Convert `URLSearchParams` `[]` properties to array objects.
 */
const arrayParams = (props) => {
  const params {};

  for (const key of props.keys()) {
    if (key.endsWith('[]')) {
      params[key.replace('[]', '')] = props.getAll(key);
    } else {
      params[key] = props.get(key);
    }
  }

  return params;
};

const params = arrayParams(new URLSearchParams('?foo[]=bar&foo[]=baz'));
// { foo: ["bar", "baz"] } 
```

Otherwise, you'll end up with a single `[]` property with the first value supplied.

```js
const params = new URLSearchParams('?foo[]=bar&foo[]=baz');
const entries Object.fromEntries(params);
// { foo[]: "bar" }
```

If you only need to get a specific value you can use the `.getAll` method directly.

```js
const params = new URLSearchParams('?foo=bar&foo=baz');

params.getAll('foo');
// ["bar", "baz"]
```

## Node and Browser Support

`URLSearchParams` is supported by Node 10+ and browser support is prettay prettay prettay pretty good - It works with Edge 17+ and all evergreen browsers have supported it since 2016~2017.

A [polyfill](https://www.npmjs.com/package/@ungap/url-search-params) is also available for the unfortunate souls who need to support legacy browsers.

![image](https://dev-to-uploads.s3.amazonaws.com/i/4pdbae0pbcbacabylg9l.png) 

## Live Demo

{% codesandbox urlsearchparams-vs-query-string-tflmb %}

## Summary

The native `URLSearchParams` interface removes the need for `query-string`. One fewer dependency 🥳

## Links

- [URLSearchParams on MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
- [URLSearchParams on Can I Use](https://caniuse.com/urlsearchparams)