or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.mdparsers.mdquery-states.mdserialization.mdserver-cache.md
tile.json

tessl/npm-nuqs

Type-safe search params state manager for Next.js - Like React.useState, but stored in the URL query string

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/nuqs@1.20.x

To install, run

npx @tessl/cli install tessl/npm-nuqs@1.20.0

index.mddocs/

nuqs

nuqs is a type-safe state management library for Next.js that synchronizes React component state with URL query parameters. It provides React hooks that work like useState but store values in the URL query string, enabling shareable URLs and maintaining state across page refreshes.

Package Information

  • Package Name: nuqs
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install nuqs

Core Imports

import { useQueryState, useQueryStates, parseAsInteger } from "nuqs";

For server-side usage:

import { createSearchParamsCache, parseAsString } from "nuqs/server";

Basic Usage

import { useQueryState, parseAsInteger } from "nuqs";

export default function SearchPage() {
  const [search, setSearch] = useQueryState('q');
  const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1));
  
  return (
    <div>
      <input 
        value={search || ''} 
        onChange={(e) => setSearch(e.target.value)} 
        placeholder="Search..."
      />
      <p>Current page: {page}</p>
      <button onClick={() => setPage(page + 1)}>Next Page</button>
    </div>
  );
}

Architecture

nuqs is built around several key components:

  • Query State Hooks: useQueryState and useQueryStates provide React state management synchronized with URL query parameters
  • Parser System: Type-safe parsers for converting between query strings and typed values (integers, booleans, dates, arrays, etc.)
  • Server-Side Cache: Server components can access and parse query parameters with createSearchParamsCache
  • Synchronization Engine: Cross-hook synchronization and external URL change detection
  • URL Serialization: Utilities for generating query strings from typed values

Capabilities

Single Query State Management

Core hook for managing individual query parameters with type safety and default values.

function useQueryState<T>(
  key: string,
  options?: UseQueryStateOptions<T>
): UseQueryStateReturn<T, undefined>;

function useQueryState<T>(
  key: string,
  options: UseQueryStateOptions<T> & { defaultValue: T }
): UseQueryStateReturn<T, T>;

interface UseQueryStateOptions<T> extends Parser<T>, Options {}

type UseQueryStateReturn<Parsed, Default> = [
  Default extends undefined ? Parsed | null : Parsed,
  (value: Parsed | null | ((old: Parsed | null) => Parsed | null)) => Promise<URLSearchParams>
];

Query State Management

Multiple Query States Management

Hook for managing multiple related query parameters as a single state object.

function useQueryStates<KeyMap extends UseQueryStatesKeysMap>(
  keyMap: KeyMap,
  options?: UseQueryStatesOptions
): UseQueryStatesReturn<KeyMap>;

type UseQueryStatesKeysMap<Map = any> = {
  [Key in keyof Map]: KeyMapValue<Map[Key]>;
};

type UseQueryStatesReturn<T extends UseQueryStatesKeysMap> = [
  Values<T>,
  SetValues<T>
];

Multiple Query States

Type-Safe Parsers

Built-in parsers for common data types with fluent API for configuration and default values.

const parseAsString: ParserBuilder<string>;
const parseAsInteger: ParserBuilder<number>;
const parseAsHex: ParserBuilder<number>;
const parseAsFloat: ParserBuilder<number>;
const parseAsBoolean: ParserBuilder<boolean>;
const parseAsTimestamp: ParserBuilder<Date>;
const parseAsIsoDateTime: ParserBuilder<Date>;

function parseAsStringEnum<Enum extends string>(validValues: Enum[]): ParserBuilder<Enum>;
function parseAsStringLiteral<Literal extends string>(validValues: readonly Literal[]): ParserBuilder<Literal>;
function parseAsNumberLiteral<Literal extends number>(validValues: readonly Literal[]): ParserBuilder<Literal>;
function parseAsArrayOf<ItemType>(itemParser: Parser<ItemType>, separator?: string): ParserBuilder<ItemType[]>;
function parseAsJson<T>(parser?: (value: unknown) => T): ParserBuilder<T>;

interface ParserBuilder<T> extends Required<Parser<T>> {
  withDefault(defaultValue: NonNullable<T>): ParserBuilder<T> & { defaultValue: NonNullable<T> };
  withOptions(options: Options): ParserBuilder<T>;
}

Type-Safe Parsers

Server-Side Cache

Server-side utilities for accessing and parsing query parameters in React Server Components.

function createSearchParamsCache<Parsers extends Record<string, ParserBuilder<any>>>(
  parsers: Parsers
): {
  parse(searchParams: SearchParams): ParsedSearchParams;
  get<Key extends keyof Parsers>(key: Key): ParsedSearchParams[Key];
  all(): ParsedSearchParams;
};

type SearchParams = Record<string, string | string[] | undefined>;

Server-Side Cache

URL Serialization

Utilities for generating query strings from typed values using parser configuration.

function createSerializer<Parsers extends Record<string, ParserBuilder<any>>>(
  parsers: Parsers
): SerializerFunction<Parsers>;

interface SerializerFunction<Parsers extends Record<string, ParserBuilder<any>>> {
  (values: Values<Parsers>): string;
  (base: string | URLSearchParams | URL, values: Values<Parsers> | null): string;
}

type Values<Parsers extends Record<string, ParserBuilder<any>>> = Partial<{
  [K in keyof Parsers]?: ExtractParserType<Parsers[K]>;
}>;

type ExtractParserType<Parser> = Parser extends ParserBuilder<any>
  ? ReturnType<Parser['parseServerSide']>
  : never;

URL Serialization

Query Update Notifications (Deprecated)

Deprecated synchronization utility for listening to URL query changes.

/**
 * @deprecated Since Next.js introduced shallow routing in 14.0.3, this method is no longer needed.
 * This method will be removed in nuqs@2.0.0.
 */
function subscribeToQueryUpdates(
  callback: (args: QueryUpdateNotificationArgs) => void
): () => void;

type QueryUpdateSource = 'internal' | 'external';
interface QueryUpdateNotificationArgs {
  search: URLSearchParams;
  source: QueryUpdateSource;
}

Legacy APIs (Deprecated)

Deprecated APIs maintained for backward compatibility.

/**
 * @deprecated renamed to Parser
 */
type Serializers<T> = Parser<T>;

/**
 * @deprecated renamed to ParserBuilder. You should probably use createParser instead.
 */
type SerializersWithDefaultFactory<T> = ParserBuilder<T>;

/**
 * @deprecated use individual parseAsXyz imports instead.
 */
const queryTypes: {
  readonly string: ParserBuilder<string>;
  readonly integer: ParserBuilder<number>;
  readonly float: ParserBuilder<number>;
  readonly boolean: ParserBuilder<boolean>;
  readonly timestamp: ParserBuilder<Date>;
  readonly isoDateTime: ParserBuilder<Date>;
  readonly stringEnum: typeof parseAsStringEnum;
  readonly json: typeof parseAsJson;
  readonly array: typeof parseAsArrayOf;
};

/**
 * @deprecated use individual parseAsXyz imports instead
 */
type QueryTypeMap = typeof queryTypes;

Core Types

interface Parser<T> {
  /** Convert a query string value into a state value */
  parse: (value: string) => T | null;
  /** Render the state value into a query string value */
  serialize?: (value: T) => string;
  /** Check if two state values are equal */
  eq?: (a: T, b: T) => boolean;
}

interface Options<Shallow = unknown> {
  /** How the query update affects page history (defaults to 'replace') */
  history?: 'replace' | 'push';
  /** Scroll to top after a query state update (defaults to false) */
  scroll?: boolean;
  /** Shallow mode keeps updates client-side only (defaults to true) */
  shallow?: Extract<Shallow | boolean, boolean>;
  /** Maximum time (ms) between URL query string updates (defaults to 50ms) */
  throttleMs?: number;
  /** React transition function for observing Server Component loading states */
  startTransition?: TransitionStartFunction;
  /** Clear key-value pair from URL when setting state to default value */
  clearOnDefault?: boolean;
}

type HistoryOptions = 'replace' | 'push';

type TransitionStartFunction = (callback: () => void) => void;

type Nullable<T> = {
  [K in keyof T]: T[K] | null;
};