diff --git a/packages/docs/src/registry/items/useDateRange.json b/packages/docs/src/registry/items/useDateRange.json
new file mode 100644
index 000000000..dfa5f3c0b
--- /dev/null
+++ b/packages/docs/src/registry/items/useDateRange.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useDateRange",
+ "title": "Date Range Hook",
+ "description": "Date range selection with URL synchronization and preset support. Includes common presets like last 7 days, last 30 days, and custom ranges.",
+ "dependencies": ["nuqs", "date-fns@^4.1.0"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useDateRange.ts",
+ "target": "~/hooks/nuqs-presets/useDateRange.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useDateRange.md b/packages/docs/src/registry/items/useDateRange.md
new file mode 100644
index 000000000..2b4e252ef
--- /dev/null
+++ b/packages/docs/src/registry/items/useDateRange.md
@@ -0,0 +1,99 @@
+```tsx
+'use client'
+
+import { useDateRange } from '@/hooks/nuqs-presets/useDateRange'
+
+export function DateRangePicker() {
+ const {
+ startDate, // Start date
+ endDate, // End date
+ setRange, // Set both dates
+ setStartDate, // Set start only
+ setEndDate, // Set end only
+ clearRange, // Clear both
+ presets, // Quick preset functions
+ daysInRange, // Number of days
+ isValid, // Valid range (start <= end)
+ } = useDateRange({
+ defaultPreset: 'last7days',
+ })
+
+ return (
+
+
+
+
+
+
+
+
+
+ setStartDate(e.target.value)}
+ />
+ to
+ setEndDate(e.target.value)}
+ />
+
+
+ {isValid && (
+
{daysInRange} days selected
+ )}
+
+
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseDateRangeOptions {
+ defaultStartDate?: string // ISO date string
+ defaultEndDate?: string // ISO date string
+ defaultPreset?: PresetKey // Apply preset on mount
+ shallow?: boolean
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Presets
+
+Available preset functions:
+- `presets.today()` - Today only
+- `presets.yesterday()` - Yesterday only
+- `presets.last7days()` - Last 7 days
+- `presets.last30days()` - Last 30 days
+- `presets.thisMonth()` - Current month
+- `presets.lastMonth()` - Previous month
+
+### Return Value
+
+```typescript
+interface UseDateRangeResult {
+ startDate: string | null
+ endDate: string | null
+ setStartDate: (date: string | null) => void
+ setEndDate: (date: string | null) => void
+ setRange: (start: string | null, end: string | null) => void
+ clearRange: () => void
+ presets: DateRangePresets
+ daysInRange: number | null // Days between dates
+ isValid: boolean // startDate <= endDate
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/useFilters.json b/packages/docs/src/registry/items/useFilters.json
new file mode 100644
index 000000000..bcf7cb7cb
--- /dev/null
+++ b/packages/docs/src/registry/items/useFilters.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useFilters",
+ "title": "Filters Hook",
+ "description": "Type-safe multi-filter state management with URL synchronization. Uses nuqs parsers for strong typing and validation.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useFilters.ts",
+ "target": "~/hooks/nuqs-presets/useFilters.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useFilters.md b/packages/docs/src/registry/items/useFilters.md
new file mode 100644
index 000000000..e404611a9
--- /dev/null
+++ b/packages/docs/src/registry/items/useFilters.md
@@ -0,0 +1,97 @@
+```tsx
+'use client'
+
+import { useFilters } from '@/hooks/nuqs-presets/useFilters'
+import { parseAsString, parseAsFloat, parseAsBoolean } from 'nuqs'
+
+const filterParsers = {
+ category: parseAsString,
+ minPrice: parseAsFloat,
+ maxPrice: parseAsFloat,
+ inStock: parseAsBoolean,
+}
+
+export function FilterPanel() {
+ const {
+ filters, // Current filters (type-safe)
+ setFilter, // Set single filter
+ setFilters, // Set multiple filters
+ clearFilters, // Clear all filters
+ clearFilter, // Clear single filter
+ hasFilters, // Any filters active?
+ } = useFilters({
+ parsers: filterParsers,
+ })
+
+ // filters.category is string | null
+ // filters.minPrice is number | null
+ // filters.inStock is boolean | null
+
+ return (
+
+
+
+ setFilter('minPrice', e.target.value ? Number(e.target.value) : null)}
+ />
+
+
+
+ {hasFilters && (
+
+ )}
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseFiltersOptions> {
+ parsers: T // nuqs parser map
+ shallow?: boolean
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Return Value
+
+```typescript
+interface UseFiltersResult {
+ filters: ParsedFilters // Current filters (type-safe)
+ setFilter: (key: K, value: T[K]) => void
+ setFilters: (filters: Partial>) => void
+ clearFilter: (key: keyof T) => void
+ clearFilters: () => void
+ hasFilters: boolean // Any active filters?
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/useMultiSelect.json b/packages/docs/src/registry/items/useMultiSelect.json
new file mode 100644
index 000000000..03592301c
--- /dev/null
+++ b/packages/docs/src/registry/items/useMultiSelect.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useMultiSelect",
+ "title": "Multi-Select Hook",
+ "description": "Array-based multi-selection state management with URL synchronization. Supports toggle, select all, and deselect all operations.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useMultiSelect.ts",
+ "target": "~/hooks/nuqs-presets/useMultiSelect.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useMultiSelect.md b/packages/docs/src/registry/items/useMultiSelect.md
new file mode 100644
index 000000000..cb68443c1
--- /dev/null
+++ b/packages/docs/src/registry/items/useMultiSelect.md
@@ -0,0 +1,82 @@
+```tsx
+'use client'
+
+import { useMultiSelect } from '@/hooks/nuqs-presets/useMultiSelect'
+
+const ITEMS = ['item1', 'item2', 'item3', 'item4']
+
+export function MultiSelectList() {
+ const {
+ selected, // Selected item IDs
+ toggle, // Toggle single item
+ selectAll, // Select all items
+ deselectAll, // Deselect all
+ isSelected, // Check if item selected
+ selectCount, // Number selected
+ } = useMultiSelect({
+ allItems: ITEMS,
+ })
+
+ return (
+
+
+
+
+ {selectCount} selected
+
+
+
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseMultiSelectOptions {
+ allItems?: readonly T[] // All available items
+ defaultSelected?: T[] // Initially selected
+ shallow?: boolean
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Return Value
+
+```typescript
+interface UseMultiSelectResult {
+ selected: T[] // Selected items
+ toggle: (item: T) => void // Toggle selection
+ select: (item: T) => void // Add to selection
+ deselect: (item: T) => void // Remove from selection
+ selectAll: () => void // Select all items
+ deselectAll: () => void // Clear selection
+ isSelected: (item: T) => boolean // Check if selected
+ selectCount: number // Number of selected items
+ isAllSelected: boolean // All items selected
+ isNoneSelected: boolean // No items selected
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/usePagination.json b/packages/docs/src/registry/items/usePagination.json
new file mode 100644
index 000000000..affed74a4
--- /dev/null
+++ b/packages/docs/src/registry/items/usePagination.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "usePagination",
+ "title": "Pagination Hook",
+ "description": "Complete pagination state management with URL synchronization. Handles page navigation, page size control, and edge cases.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/usePagination.ts",
+ "target": "~/hooks/nuqs-presets/usePagination.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/usePagination.md b/packages/docs/src/registry/items/usePagination.md
new file mode 100644
index 000000000..6b8e702ae
--- /dev/null
+++ b/packages/docs/src/registry/items/usePagination.md
@@ -0,0 +1,86 @@
+```tsx
+'use client'
+
+import { usePagination } from '@/hooks/nuqs-presets/usePagination'
+
+export function ProductList() {
+ const {
+ page, // Current page (1-indexed)
+ pageSize, // Items per page
+ totalPages, // Computed total pages
+ hasNextPage, // Can go forward
+ hasPrevPage, // Can go back
+ nextPage, // Go to next page
+ prevPage, // Go to previous page
+ goToPage, // Go to specific page
+ setPageSize, // Change page size
+ } = usePagination({
+ defaultPageSize: 10,
+ totalItems: 1000,
+ })
+
+ return (
+
+
+ {/* Your paginated content */}
+ Page {page} of {totalPages}
+
+
+
+
+ Page {page}
+
+
+
+
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UsePaginationOptions {
+ defaultPage?: number // Default: 1
+ defaultPageSize?: number // Default: 10
+ totalItems?: number // For computing totalPages
+ shallow?: boolean // nuqs shallow option
+ history?: 'push' | 'replace' // nuqs history option
+ scroll?: boolean // nuqs scroll option
+}
+```
+
+### Return Value
+
+```typescript
+interface UsePaginationResult {
+ page: number // Current page
+ pageSize: number // Items per page
+ totalPages: number | undefined // Computed if totalItems provided
+ hasNextPage: boolean // Can navigate forward
+ hasPrevPage: boolean // Can navigate backward
+ nextPage: () => void // Go to next page
+ prevPage: () => void // Go to previous page
+ goToPage: (page: number) => void // Go to specific page
+ setPageSize: (size: number) => void // Change page size (resets to page 1)
+ goToFirstPage: () => void // Jump to first page
+ goToLastPage: () => void // Jump to last page (requires totalPages)
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/useSearch.json b/packages/docs/src/registry/items/useSearch.json
new file mode 100644
index 000000000..8263ac8d2
--- /dev/null
+++ b/packages/docs/src/registry/items/useSearch.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useSearch",
+ "title": "Search Hook",
+ "description": "Debounced search state management with URL synchronization. Includes minimum length validation and debounce control.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useSearch.ts",
+ "target": "~/hooks/nuqs-presets/useSearch.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useSearch.md b/packages/docs/src/registry/items/useSearch.md
new file mode 100644
index 000000000..cfa861fa0
--- /dev/null
+++ b/packages/docs/src/registry/items/useSearch.md
@@ -0,0 +1,71 @@
+```tsx
+'use client'
+
+import { useSearch } from '@/hooks/nuqs-presets/useSearch'
+
+export function SearchBar() {
+ const {
+ query, // Current search query
+ debouncedQuery, // Debounced value for API calls
+ setQuery, // Update search
+ isDebouncing, // Debounce in progress
+ clearQuery, // Clear search
+ } = useSearch({
+ debounce: 300, // ms to wait
+ minLength: 2, // minimum chars
+ trim: true, // auto-trim whitespace
+ })
+
+ // Use debouncedQuery for API calls
+ const { data } = useQuery({
+ queryKey: ['products', debouncedQuery],
+ queryFn: () => fetchProducts(debouncedQuery),
+ })
+
+ return (
+
+ setQuery(e.target.value)}
+ placeholder="Search..."
+ />
+ {isDebouncing && Searching...}
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseSearchOptions {
+ defaultQuery?: string // Default: ''
+ debounce?: number // Default: 300ms
+ minLength?: number // Default: 0 (no minimum)
+ trim?: boolean // Default: true
+ shallow?: boolean // nuqs shallow option
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Return Value
+
+```typescript
+interface UseSearchResult {
+ query: string // Current query (immediate)
+ debouncedQuery: string // Debounced query (for API calls)
+ setQuery: (query: string) => void // Update query
+ clearQuery: () => void // Clear search
+ isDebouncing: boolean // Debounce in progress
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/useSorting.json b/packages/docs/src/registry/items/useSorting.json
new file mode 100644
index 000000000..860133390
--- /dev/null
+++ b/packages/docs/src/registry/items/useSorting.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useSorting",
+ "title": "Sorting Hook",
+ "description": "Multi-column sorting state management with URL synchronization. Supports ascending, descending, and null states with smart toggling.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useSorting.ts",
+ "target": "~/hooks/nuqs-presets/useSorting.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useSorting.md b/packages/docs/src/registry/items/useSorting.md
new file mode 100644
index 000000000..c05abdc75
--- /dev/null
+++ b/packages/docs/src/registry/items/useSorting.md
@@ -0,0 +1,72 @@
+```tsx
+'use client'
+
+import { useSorting } from '@/hooks/nuqs-presets/useSorting'
+
+export function DataTable() {
+ const {
+ sortBy, // Current sort column
+ sortOrder, // 'asc' | 'desc' | null
+ toggleSort, // Toggle column sort
+ isSortedBy, // Check if column is sorted
+ clearSort, // Clear all sorting
+ } = useSorting({
+ columns: ['name', 'date', 'price'] as const,
+ defaultColumn: 'name',
+ defaultOrder: 'asc',
+ })
+
+ return (
+
+
+
+ | toggleSort('name')}>
+ Name {isSortedBy('name') && (sortOrder === 'asc' ? '↑' : '↓')}
+ |
+ toggleSort('price')}>
+ Price {isSortedBy('price') && (sortOrder === 'asc' ? '↑' : '↓')}
+ |
+ toggleSort('date')}>
+ Date {isSortedBy('date') && (sortOrder === 'asc' ? '↑' : '↓')}
+ |
+
+
+ {/* Table body with sorted data */}
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseSortingOptions {
+ columns: T // Available columns
+ defaultColumn?: T[number] // Initial sort column
+ defaultOrder?: 'asc' | 'desc' // Initial order
+ shallow?: boolean
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Return Value
+
+```typescript
+interface UseSortingResult {
+ sortBy: T | null // Current column
+ sortOrder: 'asc' | 'desc' | null // Current order
+ toggleSort: (column: T) => void // Toggle column (null→asc→desc→null)
+ setSorting: (column: T | null, order: 'asc' | 'desc' | null) => void
+ isSortedBy: (column: T) => boolean // Check if column is active
+ clearSort: () => void // Clear sorting
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)
diff --git a/packages/docs/src/registry/items/useTabs.json b/packages/docs/src/registry/items/useTabs.json
new file mode 100644
index 000000000..7cd3b3ae2
--- /dev/null
+++ b/packages/docs/src/registry/items/useTabs.json
@@ -0,0 +1,14 @@
+{
+ "type": "registry:item",
+ "name": "useTabs",
+ "title": "Tabs Hook",
+ "description": "Type-safe tab navigation with URL synchronization. Provides strongly-typed tab values and active state checking.",
+ "dependencies": ["nuqs"],
+ "files": [
+ {
+ "type": "registry:file",
+ "path": "https://raw.githubusercontent.com/iHiteshAgrawal/nuqs-presets/a230a749daab2327dae9907f845b445a0653dc04/registry/default/useTabs.ts",
+ "target": "~/hooks/nuqs-presets/useTabs.ts"
+ }
+ ]
+}
diff --git a/packages/docs/src/registry/items/useTabs.md b/packages/docs/src/registry/items/useTabs.md
new file mode 100644
index 000000000..c0c42df61
--- /dev/null
+++ b/packages/docs/src/registry/items/useTabs.md
@@ -0,0 +1,76 @@
+```tsx
+'use client'
+
+import { useTabs } from '@/hooks/nuqs-presets/useTabs'
+
+export function TabsExample() {
+ const {
+ activeTab, // Current tab (type-safe)
+ setTab, // Change tab
+ isActive, // Check if tab is active
+ } = useTabs(['overview', 'analytics', 'settings'] as const)
+
+ // activeTab is typed as 'overview' | 'analytics' | 'settings'
+
+ return (
+
+
+
+
+
+
+
+
+ {activeTab === 'overview' &&
}
+ {activeTab === 'analytics' &&
}
+ {activeTab === 'settings' &&
}
+
+
+ )
+}
+```
+
+## API Reference
+
+### Options
+
+```typescript
+interface UseTabsOptions {
+ tabs: T // Available tabs
+ defaultTab?: T[number] // Initial tab
+ shallow?: boolean
+ history?: 'push' | 'replace'
+ scroll?: boolean
+}
+```
+
+### Return Value
+
+```typescript
+interface UseTabsResult {
+ activeTab: T // Current tab (type-safe)
+ setTab: (tab: T) => void // Change tab
+ isActive: (tab: T) => boolean // Check if tab is active
+}
+```
+
+## More Information
+
+- **GitHub**: [nuqs-presets](https://github.com/iHiteshAgrawal/nuqs-presets)
+- **npm**: [nuqs-presets](https://www.npmjs.com/package/nuqs-presets)
+- **Examples**: See the [examples directory](https://github.com/iHiteshAgrawal/nuqs-presets/tree/main/examples)