purrfold
v0.8.0
Published
Scaffold a production-ready frontend app with shadcn, strict quality tooling, agent docs, Claude hooks, and optional tests. Starts with Next.js. 🐱
Maintainers
Readme
purrfold 🐱
purrfold creates a new latest Next.js or Astro app and applies a production-oriented quality baseline: shadcn setup, strict ESLint with @shadcn/lint design system rules, Prettier, Husky, React Doctor, React Scan, agent docs, Claude compatibility, and optional testing/commit tooling.
npx purrfold@latest my-appV1 supports new projects created with create-next-app@latest or create-astro@latest. It does not retrofit existing apps.
What It Generates
- Next.js App Router project with TypeScript, Tailwind, ESLint, and
@/*alias. - shadcn initialized through the official
shadcn initflow. @shadcn/lintin the ESLint config, blocking restyled components, raw colors, arbitrary values, inline styles, dynamic and unknown classes; the generatedDESIGN.mdexplains each rule.- Quality scripts for linting, formatting, typechecking, React Doctor, React Scan, and final checks.
- Optional Vitest + React Testing Library.
- Optional Playwright E2E testing.
- Optional commitlint + Husky commit-msg hook.
- Optional GitHub Actions workflows:
.github/workflows/quality.yml, plusplaywright.ymlwhen E2E is enabled. - Optional Motion for React plus the
motion-frameragent skill. - Generic
README.md,DESIGN.md,AGENTS.md,CLAUDE.md,.agents/skills, and Claude hooks in generated apps. - A local component-boundary skill that reserves the shadcn
uipath for registry primitives and routes product-owned components tocommonor feature folders.
Usage
purrfold <target-dir> [options]Options:
--pm npm|pnpm|bun: choose the package manager.--framework next|astro: choose the framework. Defaults to Next.js.--ssr: enable Astro SSR instead of a static build.--adapter node|vercel|netlify|cloudflare: choose the Astro SSR adapter when SSR is enabled. Defaults to cloudflare.--unit/--no-unit: include or skip Vitest + React Testing Library.--e2e/--no-e2e: include or skip Playwright.--commitlint/--no-commitlint: include or skip commitlint.--ci/--no-ci: include or skip GitHub Actions workflows. Defaults to off. Writes.github/workflows/quality.yml, andplaywright.ymlas well when--e2eis on.--motion: install[email protected]and themotion-frameragent skill. Opt-in only;--yesdoes not enable it.--yes: use non-interactive defaults.--dry-run: print operations without writing files or installing packages.--skip-install: generate quality files without installing additional quality dependencies.--shadcn-args <args...>: forward extra arguments toshadcn init, including--preset <id>.--mcp/--no-mcp: optionally install shadcn MCP for Claude, Codex, and OpenCode. Defaults to off.--icons <lucide|phosphor|tabler>: icon library for the home-page cat. Defaults to shadcn's choice (or lucide). If shadcn is configured with an unsupported icon library, purrfold normalizes it to lucide.
Dry-run examples:
npm run dev -- my-app --pm npm --unit --e2e --commitlint --dry-run
npm run dev -- my-app --pm pnpm --no-unit --e2e --no-commitlint --dry-run
npm run dev -- my-app --pm bun --unit --no-e2e --commitlint --dry-runFor AI agents
purrfold is designed to be driven by coding agents (Claude Code, Codex, opencode). An agent can discover the full option schema at runtime:
npx purrfold@latest info --jsonMachine-readable guidance also lives in llms.txt, and a Claude
Code skill is available in skills/purrfold/SKILL.md.
Map a user's intent to the right command:
| The user wants… | Run |
| --- | --- |
| Defaults (unit tests, no e2e/commitlint) | npx purrfold@latest my-app --yes |
| Scaffold Astro instead of Next.js | npx purrfold@latest my-app --framework astro --yes |
| Scaffold Astro SSR with the Cloudflare adapter | npx purrfold@latest my-app --framework astro --ssr --adapter cloudflare --yes |
| No testing at all | npx purrfold@latest my-app --no-unit --no-e2e --yes |
| Full setup (unit + e2e + commitlint) | npx purrfold@latest my-app --unit --e2e --commitlint --yes |
| A specific package manager | npx purrfold@latest my-app --pm pnpm --yes |
| Motion for React | npx purrfold@latest my-app --motion --yes |
| A specific icon library for the cat | npx purrfold@latest my-app --icons phosphor --yes |
| shadcn MCP for Claude/Codex/OpenCode | npx purrfold@latest my-app --mcp --yes |
| A shadcn preset | npx purrfold@latest my-app --shadcn-args --preset b3REw8vwo --yes |
| Preview without writing | npx purrfold@latest my-app --yes --dry-run |
Always pass --yes when running non-interactively so purrfold does not block on prompts.
Install the Claude Code skill
npx skills@latest add github:C3SC0-V4113/Scaffold --skill purrfold --copy --yesOr copy skills/purrfold/SKILL.md into your .claude/skills/ (project) or
~/.claude/skills/ (global) directory.
Local Development
npm install
npm run checknpm run check runs typecheck, tests, and the tsup build.
CLI E2E tests
Heavy CLI E2E tests live outside npm run check so the normal gate stays fast
and deterministic.
npm run test:e2e:cli:quick
npm run test:e2e:cli:astro
npm run test:e2e:cli -- --work-dir E:\Repositorios\smoke --keep
npm run test:e2e:cli:heavyThe quick suite builds the local CLI and verifies dry-run command generation,
including shadcn MCP commands and preset forwarding. The default suite
(test:e2e:cli) generates real Next.js and Astro apps for the supported package
managers, checks generated files, and runs each generated app's package-manager
run check. test:e2e:cli:astro isolates the Astro SSG, Playwright, and SSR
adapter matrix.
Default temporary workspaces are deleted after every run, including failures.
Pass --keep explicitly when a preserved workspace is needed for debugging;
an explicit --work-dir is never removed automatically.
Extra-heavy scenarios (heavy: true) are excluded from the default suite
because they are network-bound, slow, and timing-fragile. Run them on demand
with npm run test:e2e:cli:heavy, or target one with
npm run test:e2e:cli -- --scenario external-shadcn-interactive. Today this
covers external-shadcn-interactive, a full no---yes generation that drives
create-next-app and the external shadcn CLI through their own interactive
prompts.
TTY-driven prompt coverage runs through a node-pty adapter. node-pty is a
dev dependency and ships a native addon, so it must compile on the host (Windows
needs the standard Node build toolchain). When it is installed, the TTY
scenarios run; when it is missing they skip gracefully and never affect
npm run check. Pass --require-tty to turn a missing-node-pty skip into a
hard failure (the heavy command sets it, since these scenarios require a PTY).
On a timeout the adapter force-kills the PTY child's process tree
(taskkill /T /F on Windows) so a stuck interactive run fails the scenario
instead of wedging the whole suite.
Smoke matrix
npm run smoke builds the CLI and generates real apps across package managers,
shadcn presets, testing, and commitlint combinations; each generated app
uses the same scenario definitions as the CLI E2E suite and self-tests via its
own check. It is heavy and network-bound, so run it
manually before a release:
npm run smoke
npm run smoke -- --work-dir E:\Repositorios\smoke --keepPacked artifact test
Every other tier runs the local dist/ bundle. This one runs the tarball users
install:
npm run test:packIt packs the package, asserts the tarball still contains dist/index.js,
README.md, llms.txt, and package.json, installs it into a throwaway
project, and drives the installed CLI through --version, info --json, and a
dry-run generation. Run it after touching files, bin, prepack, or the
build output — src/cli.ts resolves ../package.json relative to the bundle,
so dist/index.js must stay exactly one directory below the package root.
CI runs it on ubuntu and windows, because the executable shim npm links is platform-specific.
Releases
Versioning and the changelog are managed with Changesets, and publishing is automated. After a change, describe it and pick the bump type:
npm run changesetCommit that file with your work. From there
.github/workflows/release.yml runs on every
push to main:
- With changesets pending, it opens or updates a
chore: releasepull request that applies the bumps and writesCHANGELOG.md. - Merging that pull request publishes to npm and creates the release tag.
Publishing uses npm trusted publishing over OIDC, so no npm token exists in this repository, and every release carries a provenance attestation linking the published tarball to the workflow run and commit that produced it.
Do not run npm run changeset:version locally or edit CHANGELOG.md by hand —
the workflow owns both.
The package is built with tsup into a single dist/index.js.
Agent Setup
Project agent guidance lives in AGENTS.md. Claude Code loads CLAUDE.md, which points to AGENTS.md. Skills live in .agents/skills; .claude/skills is only a compatibility bridge.
