npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cogs/nuqs

v0.2.0

Published

Reusable nuqs (URL search-param state) patterns — table pagination/filter hook factories, page-index conversion, sort/filter parser builders, and typed search-param API helpers.

Readme

@cogs/nuqs

Reusable nuqs (URL search-param state) patterns extracted from environment-manager-ui's ~20 near-identical table pagination/filter hooks: page-index conversion, sort/filter parser builders, typed search-param API helpers, and a createTableUrlState factory that collapses the whole table-filtering template into one call. Re-exports nuqs's own primitives too, so consumers can depend on @cogs/nuqs alone.

Features

  • createTableUrlState(config) — the core abstraction. Generalizes envmgr-ui's use*Filters.ts template (page/per_page, sort, search, faceted filters) into a factory that always resets page back to 0 on any filter/sort/search change, accepts an optional startTransition uniformly, and exposes both a combined resetFiltersAndSearch and split resetFilters/resetSearch.
  • pageIndexParser / pageIndexParserStrict — 0-indexed internal state, 1-indexed URL (?page=1page 0 internally), for human-friendly pagination links.
  • buildFilterParsers — maps a generic { id, options? }[] field list to nuqs parsers (faceted → comma-array, text → string).
  • getColumnsSortParser — encodes/decodes multi-column { id, desc }[] sort state as col-dir,col-dir query tokens, with optional column-id validation against a sample row.
  • createSearchParamsAPI / createSerializerForParams — typed, server-safe URLSearchParams ↔ object helpers.
  • useSyncedQueryParamField — keeps a single URL query param in sync with a form field's onChange.
  • parseServerSeed — server-side half of "seed a React Hook Form default from the URL, then sync back client-side."
  • @cogs/nuqs/testing — a stateful useQueryState/useQueryStates test double that correctly round-trips index-conversion parsers (like pageIndexParserStrict) and respects clearOnDefault, unlike a naive no-op mock.
  • Re-exports nuqs's client hooks and parser builders (useQueryState, parseAsInteger, etc.), so apps depend on one package for both.

Installation

pnpm add @cogs/nuqs

nuqs is a direct dependency (tracks its own latest major independently of any one consuming app's pinned version — see Compatibility below). react is an optional peer dependency, required only if you use the hook-based exports (createTableUrlState, useSyncedQueryParamField, @cogs/nuqs/testing).

Usage

Table pagination/filter/sort/search state

// dnsHealthTableUrlState.ts
import { buildFilterParsers, createTableUrlState, type FilterParserBuilder } from '@cogs/nuqs'

const filters = buildFilterParsers(
  [
    { id: 'status', options: ['healthy', 'degraded', 'down'] },
    { id: 'checkType', options: ['a', 'cname', 'mx'] },
  ],
  { shallow: true },
) as Record<'status' | 'checkType', FilterParserBuilder<string[]>>

export const { useTableUrlState: useDnsHealthFilters } = createTableUrlState({ filters })
// DnsHealthTable.tsx
import { useTransition } from 'react'
import { useDnsHealthFilters } from './dnsHealthTableUrlState'

export function DnsHealthTable() {
  const [, startTransition] = useTransition()
  const {
    pagination,
    filters,
    sorting,
    searchQuery,
    isAnyFilterActive,
    setFilters,
    setSorting,
    setSearchQuery,
    resetFiltersAndSearch,
  } = useDnsHealthFilters({ startTransition })

  const table = useReactTable({
    data,
    columns,
    state: {
      pagination: { pageIndex: pagination.page, pageSize: pagination.per_page },
      sorting,
    },
    // ...
  })

  // setFilters/setSorting/setSearchQuery all reset `page` back to 0 automatically.
}

Page-index conversion

import { pageIndexParserStrict } from '@cogs/nuqs'

pageIndexParserStrict.parse('1') // 0  (0-indexed internally)
pageIndexParserStrict.serialize(0) // '1' (1-indexed in the URL)

Multi-column sort

import { getColumnsSortParser } from '@cogs/nuqs'

const sortParser = getColumnsSortParser<{ name: string; createdAt: string }>()
sortParser.parse('name-asc,createdAt-desc')
// → [{ id: 'name', desc: false }, { id: 'createdAt', desc: true }]

Testing

// jest/vitest module mapper — point `nuqs`, `nuqs/server`, and
// `nuqs/adapters/next/app` all at this one module:
// moduleNameMapper: {
//   '^nuqs$': '@cogs/nuqs/testing',
//   '^nuqs/server$': '@cogs/nuqs/testing',
//   '^nuqs/adapters/next/app$': '@cogs/nuqs/testing',
// }

For hook-level tests of code built with createTableUrlState directly (not through the app's mocked nuqs), prefer nuqs's own nuqs/adapters/testing (NuqsTestingAdapter / withNuqsTestingAdapter, with hasMemory: true) as a renderHook wrapper — that's what this package's own test suite uses to verify createTableUrlState against real nuqs behavior, not a hand-mimicked stub.

Compatibility

This package depends on nuqs@latest and tracks upstream independently — it is not pinned to any particular consuming app's nuqs version. If your app is on an older nuqs major, verify createParser/withOptions/Options shapes still match before adopting.

Development

pnpm --filter @cogs/nuqs build
pnpm --filter @cogs/nuqs typecheck
pnpm --filter @cogs/nuqs lint
pnpm --filter @cogs/nuqs test
  • createTableUrlState's filters config expects an all-faceted (array-valued) parser record — pass only faceted fields from buildFilterParsers. A standalone text filter should be wired up on its own useQueryState, outside the factory.
  • No module in this package has import-time side effects — every export is safe to import at module scope without triggering unrelated app initialization.