Skip to main content
This guide will help you migrate from nuqs v1 to v2. The biggest change in v2 is the introduction of adapters to support multiple React frameworks beyond Next.js.

Overview of Breaking Changes

Adapters Required

The most significant change in v2 is that you must wrap your app with an adapter. This enables nuqs to support multiple React frameworks beyond just Next.js.

Next.js App Router

Wrap your {children} with the NuqsAdapter component in your root layout:
src/app/layout.tsx

Next.js Pages Router

Wrap the <Component> page outlet in your _app.tsx file:
src/pages/_app.tsx

Unified Adapter (Both Routers)

If your Next.js app uses both app and pages routers, import the unified adapter:
This comes with a slightly larger bundle size (~100B) compared to the router-specific adapters.

Migration Steps

Minimum Next.js Version

nuqs v2 requires Next.js ≥14.2.0
Early versions of Next.js 14 had instability with shallow routing. Supporting those versions required workarounds and performance penalties, which have been removed in v2.

Behaviour Changes

startTransition No Longer Implies shallow: false

In v1, setting startTransition automatically set shallow: false. This is no longer the case in v2 to align with other frameworks that don’t have shallow/deep routing concepts. Before (v1):
After (v2):

“use client” Directive Added

The "use client" directive is now included in the main nuqs import. Server-side code must import from nuqs/server to avoid errors:
Solution: Use nuqs/server for all server-side code:

ESM Only

nuqs v2 is now an ESM-only package. This shouldn’t affect most Next.js users (ESM supported since Next.js 12), but if you’re bundling nuqs into an intermediate CommonJS library, you may encounter:
Solution: Use dynamic imports if converting to ESM is not possible:

Deprecated Exports Removed

queryTypes Object

The queryTypes object has been removed in favor of individual parser exports for better tree-shaking. Before:
After:

subscribeToQueryUpdates

This internal helper has been removed. Next.js 14.1.0+ makes useSearchParams reactive to shallow updates, making this function redundant.

nuqs/parsers Renamed

The nuqs/parsers export has been renamed to nuqs/server to better reflect its purpose. Find and replace:

Debug Printout Detection

The debug logging detection now only checks for nuqs in localStorage.debug (not the old next-usequerystate name). Update your local environment:

Type Changes

The following type changes may affect your TypeScript code:
  • The Options type is no longer generic
  • UseQueryStatesOptions is now a type (not an interface) and is generic over the object passed to useQueryStates
  • parseAsJson now requires a runtime validation function to infer the parsed JSON data type
parseAsJson example:

Testing Improvements

While not a breaking change, v2 introduces a dedicated testing adapter that makes unit testing much easier!
Unit testing components using nuqs v1 required mocking Next.js router internals. In v2, use the NuqsTestingAdapter:

New Framework Support

Beyond Next.js, nuqs v2 now supports:
  • React SPA (Vite, Create React App)
  • Remix
  • React Router (v6 and v7)
  • TanStack Router
See the Adapters documentation for setup instructions for these frameworks.

Summary

The migration to v2 primarily involves:
  1. Adding an adapter wrapper to your app
  2. Updating nuqs/parsers imports to nuqs/server
  3. Ensuring Next.js ≥14.2.0
  4. Explicitly setting shallow: false when using startTransition
  5. Replacing deprecated queryTypes with individual parsers
Most of these changes can be handled with find-and-replace operations in your codebase.