Skip to content

Guide · Open source

How to use nuqs: sync React state with the URL query string

Updated · written with AI from the project's own documentation and checked against our catalogue data

nuqs is an open-source TypeScript library for React apps that keeps state in the URL's query string instead of in memory. It works much like React's useState, so the value survives page reloads and can be shared as a link. This guide shows you how to install it, add the right adapter for your framework, and read and update query values with useQueryState.

nuqs47ng/nuqs · ★ 10.9k · MIT

Quick start

  1. 1Check prerequisites. Make sure you have Node.js and a package manager, and a React project using a supported framework or router.
  2. 2Install the package. Run npm install nuqs or pnpm add nuqs in your project folder.
  3. 3Add the adapter. Wrap your component tree with NuqsAdapter from the path that matches your framework.
  4. 4Call useQueryState. In a client component, call useQueryState with a key name to get a value and a setter.
  5. 5Test the URL. Set a value and check that the query string updates, then reload the page to confirm it persists.
  6. 6Add more keys or parsers. Use useQueryStates for related keys and built-in parsers for typed values.

Install nuqs in your project

nuqs is installed with a package manager. You need Node.js and a package manager such as npm, pnpm, yarn, bun or deno, plus a React project that uses one of the supported frameworks or routers.

  • Supported frameworks include Next.js (app and pages routers), plain React (SPA), Remix, React Router and TanStack Router.
npm install nuqs

Wrap your app with the adapter for your framework

Before using nuqs hooks, wrap your component tree with an adapter that matches your framework. The adapter import path differs by framework, so use the one for your setup.

For Next.js with the app router, the adapter goes in your root layout. The source says Next.js versions 14.2.0 and later are supported. For older Next.js versions, install nuqs@^1, which does not need this adapter code.

  • Next.js app router: import NuqsAdapter from 'nuqs/adapters/next/app' and wrap children in src/app/layout.tsx.
  • Next.js pages router: import NuqsAdapter from 'nuqs/adapters/next/pages' and wrap the component in src/pages/_app.tsx.
  • Plain React (Vite or create-react-app): import NuqsAdapter from 'nuqs/adapters/react' and wrap your App.
  • Remix: import NuqsAdapter from 'nuqs/adapters/remix' in app/root.tsx.
  • React Router v6, v7 and v8 each have their own adapter path under nuqs/adapters/react-router/. TanStack Router uses nuqs/adapters/tanstack-router and is marked experimental in the source, without TanStack Start support.
// src/app/layout.tsx import { NuqsAdapter } from 'nuqs/adapters/next/app' import { type ReactNode } from 'react' export default function RootLayout({ children }: { children: ReactNode }) { return ( <html> <body> <NuqsAdapter>{children}</NuqsAdapter> </body> </html> ) }

Read and update state with useQueryState

useQueryState takes one required argument: the key to use in the query string. Like React.useState, it returns an array with the current value and a setter function. The value is a string, or null when the key is missing from the URL.

Calling the setter updates the URL. Passing null removes the key. In the source example, the input value is written to the name key and a Clear button sets it to null.

Mark components that use this hook with 'use client' in Next.js, since the source notes it only works in client components.

  • / returns null because there is no name key.
  • /?name= returns an empty string.
  • /?name=foo returns 'foo'.
  • /?name=2 returns the string '2'. Values are strings by default; parsers convert them to other types.
'use client' import { useQueryState } from 'nuqs' export default () => { const [name, setName] = useQueryState('name') return ( <> <h1>Hello, {name || 'anonymous visitor'}!</h1> <input value={name || ''} onChange={e => setName(e.target.value)} /> <button onClick={() => setName(null)}>Clear</button> </> ) }

Keep several query values in sync

When a page has several related filters, such as a search term and a page number, nuqs provides useQueryStates. The README lists it under related querystrings. Use it when you want multiple URL keys to be read and updated together.

The README also documents parsers for common types such as integer, float, boolean and Date, and says you can write your own for custom types and pretty URLs. Parsers are covered in the full docs at nuqs.dev.

  • Use useQueryState for a single key.
  • Use useQueryStates for a group of related keys.
  • Built-in parsers convert string values to types like integer or boolean.

Choose how history and updates behave

By default the README describes URL updates in shallow mode, which does not notify server components. You can opt in to notify them. The README also says you can replace history or append entries so the Back button steps through state changes.

Because the URL is the source of truth, anything you store is visible in the address bar and browser history. Do not put sensitive data in query params.

  • Replace history (default behaviour in the examples) to keep the Back button from stepping through every change.
  • Append to history if you want the Back button to undo state updates.
  • Shallow mode is the default for query updates.

What people use it for

  • Filterable product or listing pages where the filters appear in the URL.
  • Searchable pages where a shared link opens with the same search term.
  • Paginated tables where the current page is kept in the address bar.
  • Bookmarkable views in dashboards built with Next.js or React Router.

Frequently asked questions

How do I install nuqs?

Run npm install nuqs, or pnpm add nuqs if you use pnpm. The README also lists yarn, bun and deno commands. You need Node.js and a package manager.

Is nuqs free to use?

nuqs is released under the MIT licence, as stated on its repository page. Check the LICENSE file in the repository for the full terms.

Which frameworks does nuqs support?

The README lists Next.js (app and pages routers), plain React (SPA), Remix, React Router v6 through v8 and TanStack Router. TanStack Router support is experimental and does not yet cover TanStack Start.

Does nuqs work with Next.js 13?

The source says the Next.js adapter needs version 14.2.0 or later. For older versions, the README says to install nuqs@^1, which does not need the adapter code.

Is nuqs safe for sensitive data?

No. Anything stored in the query string is visible in the URL and browser history, so the project is not suited to sensitive data.

How is nuqs different from useSearchParams?

React Router's useSearchParams and TanStack Router's search params also work with the URL. nuqs is built around a useState-style API with type-safe parsers and adapters for several frameworks. Pick based on which router your app already uses.

New agent skills, repos and AI tools — every week

The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.

Our verdict

Use nuqs if you are building a React app where filters, search terms or pages should live in the URL and be shareable or bookmarkable. Pick something else if your project does not use React, if you need to store sensitive data, or if you are on an unsupported framework version.

Install options & downloads