Stop Manually Managing URLSearchParams in Next.js — Use nuqs Instead
Source: Dev.to
Modern web applications often represent UI state in the URL, for example:
- search filters
- pagination
- sorting
- tab selection
- dashboard parameters
A typical URL might look like this:
/products?category=books&sort=price&page=2Synchronizing UI state with the URL improves several things:
- Shareability – users can share filtered views
- Bookmarking
- Browser navigation (back/forward)
- Predictable application state
However, implementing this in the Next.js App Router often leads to repetitive and fragile code.
Recently I started using a library called nuqs, and it significantly improved the developer experience when managing URL state.
In this article I’ll cover:
- Why managing query parameters manually is painful
- Why I chose nuqs
- How to use it in real projects
- What improved in my development workflow
The Problem: Manual URL State Management
Without a helper library, managing URL state usually requires combining:
useSearchParamsuseRouterURLSearchParamsuseStateuseEffect
Example
'use client'
import { useRouter, useSearchParams } from 'next/navigation'
import { useState, useEffect } from 'react'
export default function ProductFilter() {
const router = useRouter()
const searchParams = useSearchParams()
const [category, setCategory] = useState(
searchParams.get('category') ?? ''
)
useEffect(() => {
const params = new URLSearchParams(searchParams)
params.set('category', category)
router.push(`?${params.toString()}`)
}, [category, router, searchParams])
return (
setCategory(e.target.value)}
>
All
Books
Games
)
}Problems ⚡️
- Boilerplate code everywhere
- Manual parsing of
URLSearchParams - Hard to scale with multiple filters
- Easy to introduce bugs
- No built‑in type safety
As applications grow (e.g., search pages or dashboards), this logic quickly becomes hard to maintain.
What Is nuqs?
nuqs is a lightweight library that treats URL query parameters as React state.
Instead of manually synchronizing state and the URL, you simply use a hook.
URL Query React StateThis drastically simplifies query‑parameter management.
Installing nuqs
npm install nuqs
# or
yarn add nuqs
# or
pnpm add nuqsThat’s it.
The Same Example Using nuqs
'use client'
import { useQueryState } from 'nuqs'
export default function ProductFilter() {
const [category, setCategory] = useQueryState('category')
return (
setCategory(e.target.value)}
>
All
Books
Games
)
}The URL automatically updates when the state changes.
Resulting URL
/products?category=booksCompared to the manual implementation:
- No router logic
- No
useEffect - No manual query parsing
Type‑Safe Query Parameters
One of the most powerful features of nuqs is its parser system.
Example: Pagination
import { useQueryState, parseAsInteger } from 'nuqs'
const [page, setPage] = useQueryState(
'page',
parseAsInteger.withDefault(1)
)Benefits
pageis always a number- Default value is
1 - Invalid query values are handled safely
This prevents many runtime bugs.
Managing Multiple Query Parameters
Complex UIs usually have multiple filters. nuqs handles this cleanly using useQueryStates.
import { useQueryStates, parseAsString } from 'nuqs'
const [filters, setFilters] = useQueryStates({
category: parseAsString,
sort: parseAsString,
})Updating the filters
setFilters({
category: 'books',
sort: 'price',
})Resulting URL
?category=books&sort=priceThis keeps filter logic predictable and easy to maintain.
Why I Chose nuqs
When selecting a library for URL state management, I considered several factors.
1. Developer Experience
nuqs removes the need to manually synchronize state and the URL.
Instead of juggling useEffect, URLSearchParams, and router updates, query parameters behave like ordinary React state. This dramatically reduces boilerplate and improves readability.
2. Type Safety
The parser system allows query parameters to be typed, ensuring predictable values and reducing runtime errors in TypeScript projects.
3. Zero Dependencies & Lightweight
nuqs has zero runtime dependencies, which brings several advantages:
- Smaller bundle size
- Fewer potential security vulnerabilities
- Lower risk of dependency conflicts
- Easier long‑term maintenance
In modern frontend projects, dependency trees can grow quickly. Using focused libraries with minimal dependencies helps keep applications lean, and nuqs follows this philosophy very well.
4. Designed for Modern Next.js
nuqs integrates naturally with the Next.js App Router and React hooks. It fits seamlessly into modern React architectures without introducing additional complexity.
Real Impact in My Project
After adopting nuqs, I observed:
- ~30% reduction in component boilerplate related to URL handling
- Fewer bugs caused by malformed query strings (thanks to type‑safe parsers)
- Faster onboarding for new team members, as the API is intuitive and self‑documenting
- Cleaner separation of concerns: UI components no longer need to know about routing details
Overall, nuqs turned a painful, error‑prone part of my codebase into a declarative, type‑safe experience.
TL;DR
If you’re building a Next.js app that relies on query parameters for UI state, give nuqs a try. It turns URL management into a simple hook‑based workflow, adds type safety, and keeps your bundle lean. Happy coding!
When Introducing nuqs, Several Improvements Became Clear
Less Boilerplate
Query state logic became significantly smaller and easier to understand.
Better Maintainability
Adding new filters now requires only a few lines.
Fewer Bugs
Type‑safe parsing prevents invalid query states.
Better UX
Because the UI state lives in the URL:
- filters can be shared
- pages can be bookmarked
- browser navigation works naturally
When nuqs Is Especially Useful
From my experience, nuqs works especially well for:
- search / filter pages
- e‑commerce listings
- dashboards
- analytics tools
- pagination systems
- sorting UIs
In other words:
✨ any interface where UI state should be reflected in the URL.
Final Thoughts
Managing URL state manually in Next.js often leads to repetitive and fragile code.
nuqs provides a clean abstraction that treats query parameters as React state while keeping everything type‑safe and lightweight.
For modern React and Next.js applications, it can significantly improve both:
- developer experience
- code maintainability
If you’re building filter‑heavy interfaces or dashboards, I highly recommend giving nuqs a try!