nuqs-scaffolder
Scaffolds URL-state filters for a Next.js page — typed `searchParams.ts` parser map and a `<Filters />` client component backed by `useQueryStates`. From a single JSON spec, generates four files in lockstep — client parser map, server loader/cache/serializer, client component, and Vitest test — all sharing the same parser definitions per the nuqs Standard Schema pattern. Trigger even when the user only says "add filters to /search" or "I need a typed query string for this page" — both are exactly this skill's job.
How do I install this agent skill?
npx skills add https://github.com/pproenca/dot-skills --skill nuqs-scaffolderIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill is a template-driven scaffolding tool that generates Next.js files from a JSON specification. It follows project conventions and library best practices without executing remote code, accessing sensitive files, or performing network operations.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
nuqs Scaffolder
Generate a coherent set of nuqs files from one spec. The skill is template-driven — you read the spec, copy the templates, and substitute placeholders. No build step, no codegen runtime; the templates ARE the artifact.
When to Apply
Use this skill when:
- A new Next.js page needs URL-backed filters, pagination, search, or sort state
- You're standardising an existing page's ad-hoc
useStatefilters onto nuqs - A code review keeps catching client/server drift in parser definitions — this skill makes drift mechanically impossible because both sides import the same map
- A user asks to "add Standard Schema validation to these query params for tRPC" — the generated
searchParams.server.tsalready exports the schema
If the codebase has legacy nuqs patterns instead, run the nuqs-codemod-runner skill first.
How to Use
- Read or create a spec. Start from
assets/templates/spec.template.jsonand fill inname,module, andparams. See "Spec Format" below. - Render each template by replacing placeholders with values derived from the spec.
- Write each rendered file to the path computed from
config.json(overridable per-call). - Show the user the diff before committing — this skill never modifies existing files; if a target path exists, ask before overwriting.
The agent does the rendering — Claude is the templating engine. Each template is annotated with markers (/*= ... =*/) that name the placeholder slot and document the substitution rule.
Spec Format
{
"name": "Search", // PascalCase — drives the exported symbol names
"module": "search", // kebab-case — drives file paths and the "module" folder
"params": {
"q": { "type": "string", "default": "" },
"page": { "type": "integer", "default": 1 },
"limit": { "type": "integer", "default": 10 },
"categories": { "type": "array-of-string-native", "default": [] },
"sort": { "type": "string-literal", "values": ["asc","desc"], "default": "asc" },
"minPrice": { "type": "float", "default": null },
"lastSeen": { "type": "iso-date", "default": null }
}
}
Supported type values
type | Parser used | Notes |
|---|---|---|
string | parseAsString | |
integer | parseAsInteger | |
float | parseAsFloat | |
boolean | parseAsBoolean | |
iso-date | parseAsIsoDate | Date-only |
iso-date-time | parseAsIsoDateTime | Date + time |
timestamp | parseAsTimestamp | ms since epoch |
hex | parseAsHex | Numeric value, hex URL form |
index | parseAsIndex | 0-based in code, 1-based in URL |
array-of-string | parseAsArrayOf(parseAsString) | ?tags=a,b,c |
array-of-string-native | parseAsNativeArrayOf(parseAsString) | ?tag=a&tag=b — requires nuqs ≥ 2.7 |
string-literal | parseAsStringLiteral(values) | Requires values: string[] |
number-literal | parseAsNumberLiteral(values) | Requires values: number[] |
json | parseAsJson(SchemaName.parse) | Generates a Zod schema stub; mark default separately |
If default is null, the param is nullable; otherwise the template uses .withDefault(...).
Available Templates
| Template | Renders to (default) | Loaded when |
|---|---|---|
searchParams.ts.template | lib/{module}-search-params.ts | Always |
searchParams.server.ts.template | lib/{module}-search-params.server.ts | Always |
filters.tsx.template | components/{module}/{name}-filters.tsx | Always |
filters.test.tsx.template | components/{module}/{name}-filters.test.tsx | If config.generate_tests is true |
spec.json.template | Anywhere — starter for the user | First-run prompt |
Template files end in .template so editors don't apply syntax highlighting to placeholder markers — the original extension is preserved as the suffix-before-.template so you can still tell at a glance what the rendered file will be.
Paths are configurable in config.json — override globs, file naming style (kebab vs PascalCase), and whether tests are emitted.
Placeholder Reference
All templates use the same placeholder syntax. The agent substitutes them in one pass:
| Placeholder | Source | Example |
|---|---|---|
__NAME__ | spec.name | Search |
__name__ | camelCase form of spec.name | search |
__module__ | spec.module | search |
/*= PARSERS =*/ | Iterate spec.params → key: parseAsXxx.withDefault(...) lines | see template |
/*= COMPONENT_FIELDS =*/ | Iterate spec.params → one input/select per type | see template |
/*= TEST_CASES =*/ | Iterate spec.params → one assertion per default | see template |
/*= NULLABLE_IMPORTS =*/ | Add Nullable helper import if any param is nullable | conditional |
/*= ZOD_SCHEMAS =*/ | For json type params, emit a Zod schema stub | conditional |
/*= ... =*/ markers are instructions to the agent, not literal substitutions. Replace the entire marker (including the /*= =*/ delimiters) with the expanded content.
Conventions
Read references/conventions.md for:
- File naming (kebab-case) and why
- Import ordering (external → nuqs → internal → relative) and why
- Why the server file exists as a sibling, not inside
app/ - When to fork the templates (you usually shouldn't)
Setup
config.json is pre-populated with sensible Next.js App Router defaults. Override only if your repo uses different conventions:
{
"lib_dir": "lib",
"components_dir": "components",
"generate_tests": true,
"test_runner": "vitest"
}
On first use, the agent should ask the user for the spec via AskUserQuestion if no spec file is provided.
Related Skills
nuqs— Best-practice reference these templates encode. Read it to understand WHY the templates are shaped this way.nuqs-codemod-runner— Run BEFORE this skill if migrating an existing page from pre-v2.5 nuqs.
Gotchas
See gotchas.md for edge cases discovered during use.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/pproenca/dot-skills/nuqs-scaffolder">View nuqs-scaffolder on skillZs</a>