This is the full developer documentation for xtarter # xtarter > Production-grade starter templates for JavaScript and TypeScript projects. Scaffold your next project with a single command. 01 // 01 the xtarter ecosystem ## Two tools, one standard Start a new project from a production-grade template, or bring an existing repo up to standard. Either way you land on the same conformance baseline. [scaffolding CLI](/create-xtarter-app/) [create-xtarter-app→](/create-xtarter-app/) [New project, fully configured, in one command.](/create-xtarter-app/) [Five production-grade starters. One command lays down the whole baseline: Biome, strict TS, CI, editor configs, agent skills.](/create-xtarter-app/) [$ pnpm create xtarter-appStart with a template→](/create-xtarter-app/) [conformance CLI](/xtarterize/) [xtarterize→](/xtarterize/) [Bring any project up to standard without overwriting your files.](/xtarterize/) [Point it at code you already have. It detects the stack, plans the fixes, and writes nothing until you approve.](/xtarterize/) [$ npx xtarterize@latest initConform your project→](/xtarterize/) 02 // 02 why conformant ## Standards that hold their shape Configs drift when enforcement lives in someone's head. Someone formats locally, CI disagrees, reviews turn into style debates. This baseline lives in the repo instead. * ### Reviews that read themselves Biome and strict TypeScript run from the first commit. Pull requests argue about features, not formatting. * ### CI that stays green GitHub Actions runs the same configs your editor enforces. Local and CI cannot disagree about what passing means. * ### Agent-ready by default Agent skills ship next to every config, so AI assistants working in your repo follow the same standard you do. 03 // 03 ## Starter templates Five curated starters. Each ships Biome, strict TypeScript, CI, VS Code settings, and agent skills before your first commit. * [Next.js + Chakra UINext.js 16 prewired with Chakra UI v3, Biome, Playwright, and Turborepo.Next.js 16Chakra UI v3BiomeTurborepoView repository→](https://github.com/agustinusnathaniel/nextarter-chakra) * [Next.js + TailwindNext.js 16 with Tailwind CSS v4 and Biome, tuned for fast iteration.Next.js 16Tailwind CSS v4BiomeView repository→](https://github.com/agustinusnathaniel/nextarter-tailwind) * [Vite + React + ChakraVite+ and React 19 on TanStack Router, styled with Chakra UI v3, tested with Vitest.Vite+ (Vite 8)React 19Chakra UI v3TanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-chakra-starter) * [Vite + React + TailwindVite+ and React 19 with Tailwind CSS v4 and TanStack Query caching built in.Vite+ (Vite 8)React 19Tailwind CSS v4TanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-tailwind-starter) * [Vite + React + Hero UIVite+ and React 19 with HeroUI components wired through TanStack Router.Vite+ (Vite 8)React 19Hero UITanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-hero-starter) Ready to use one? [Scaffold with create-xtarter-app →](/create-xtarter-app/) [All source repositories on GitHub](https://github.com/agustinusnathaniel?tab=repositories\&q=\&type=source) 04 // 04 ## The project lifecycle Two tools, one path from first commit to shipped project. 1. [Choose](#starter-templates) 2. [Scaffold](/create-xtarter-app/) 3. [Conform](/xtarterize/) 4. [Ship](#get-started) ## Pick your door. Both commands land on the same baseline. Scaffold something new, or conform code you already have. [Start with a template](/create-xtarter-app/)[Conform an existing project](/xtarterize/) # 404 > Lost? That page doesn't exist. Try searching or head back home. The page you were looking for does not exist at this address. Here are the most useful places to go instead: * [Home](/) * [xtarterize docs](/xtarterize/) * [create-xtarter-app docs](/create-xtarter-app/) * [llms.txt](/llms.txt) * [llms-full.txt](/llms-full.txt) * [agents.md](/agents.md) * [Sitemap](/sitemap-index.xml) * [About](/about/) * [Contact](/contact/) * [Privacy](/privacy/) # create-xtarter-app > Scaffold a new JavaScript/TypeScript project from production-grade templates with a single command. 01 // 01 included in every scaffold ## One baseline, five ways Every template carries the identical production baseline. Your only decision is UI library and router. * Biome lint + format * TypeScript strict mode * GitHub Actions CI * VS Code settings + recommended extensions * Agent skills for AI editors 02 // 02 ## The templates Next.js or Vite+ with React. Chakra UI, Tailwind, or HeroUI up front. Pick by taste. * [Next.js + Chakra UINext.js 16 prewired with Chakra UI v3, Biome, Playwright, and Turborepo.Next.js 16Chakra UI v3BiomeTurborepoView repository→](https://github.com/agustinusnathaniel/nextarter-chakra) * [Next.js + TailwindNext.js 16 with Tailwind CSS v4 and Biome, tuned for fast iteration.Next.js 16Tailwind CSS v4BiomeView repository→](https://github.com/agustinusnathaniel/nextarter-tailwind) * [Vite + React + ChakraVite+ and React 19 on TanStack Router, styled with Chakra UI v3, tested with Vitest.Vite+ (Vite 8)React 19Chakra UI v3TanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-chakra-starter) * [Vite + React + TailwindVite+ and React 19 with Tailwind CSS v4 and TanStack Query caching built in.Vite+ (Vite 8)React 19Tailwind CSS v4TanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-tailwind-starter) * [Vite + React + Hero UIVite+ and React 19 with HeroUI components wired through TanStack Router.Vite+ (Vite 8)React 19Hero UITanStack RouterView repository→](https://github.com/agustinusnathaniel/vite-react-hero-starter) [All source repositories on GitHub](https://github.com/agustinusnathaniel?tab=repositories\&q=\&type=source) 03 // 03 ## Quick start Scaffold a new project in one command. * npm ```sh npm create xtarter-app@latest ``` * pnpm ```sh pnpm create xtarter-app@latest ``` * yarn ```sh yarn create xtarter-app ``` * bun ```sh bun create xtarter-app@latest ``` Follow the prompts to pick a template. Next, keep the project conformant as standards evolve: [npx xtarterize init](/xtarterize/getting-started/installation/). ## Start conformant. Stay conformant. Hand the fresh scaffold to xtarterize whenever standards move. Each run realigns the project without manual drift. [Run xtarterize init](/xtarterize/getting-started/installation/)[About xtarterize](/xtarterize/) # Getting Started with create-xtarter-app > Scaffold a new JavaScript/TypeScript project from production-grade templates in seconds. `create-xtarter-app` scaffolds a new project from a curated template, installs its dependencies, and can initialize Git. Templates include Biome, strict TypeScript, CI, VS Code settings, and agent skills. ## Quick start [Section titled “Quick start”](#quick-start) Scaffold a new project in one command: * npm ```sh npm create xtarter-app@latest ``` * pnpm ```sh pnpm create xtarter-app@latest ``` * yarn ```sh yarn create xtarter-app ``` * bun ```sh bun create xtarter-app@latest ``` The interactive CLI will guide you through: 1. **Project name** - what to call your new project 2. **Template** - pick from Next.js, Vite + React, and more 3. **Package manager** - pnpm (recommended), npm, bun, or yarn 4. **Git init** - whether to initialize a git repository 5. **CI/CD cleanup** - whether to remove pre-configured CI configs Note Use `--yes` / `-y` to skip the template, package manager, Git, and cleanup prompts. It uses pnpm, the `next-chakra` template, Git init, and no CI cleanup. The project-name prompt still appears unless you provide a positional name. Any explicit flag such as `--pm bun` or `--clean` takes priority over `--yes`. * npm Scaffold with defaults ```sh npm create xtarter-app@latest -- my-app --yes ``` * pnpm Scaffold with defaults ```sh pnpm create xtarter-app@latest my-app --yes ``` * yarn Scaffold with defaults ```sh yarn create xtarter-app my-app --yes ``` * bun Scaffold with defaults ```sh bun create xtarter-app@latest my-app --yes ``` - npm Scaffold into current directory ```sh npm create xtarter-app@latest -- . -t vite-tailwind ``` - pnpm Scaffold into current directory ```sh pnpm create xtarter-app@latest . -t vite-tailwind ``` - yarn Scaffold into current directory ```sh yarn create xtarter-app . -t vite-tailwind ``` - bun Scaffold into current directory ```sh bun create xtarter-app@latest . -t vite-tailwind ``` * npm Overwrite existing directory ```sh npm create xtarter-app@latest -- my-app -t vite-tailwind --force ``` * pnpm Overwrite existing directory ```sh pnpm create xtarter-app@latest my-app -t vite-tailwind --force ``` * yarn Overwrite existing directory ```sh yarn create xtarter-app my-app -t vite-tailwind --force ``` * bun Overwrite existing directory ```sh bun create xtarter-app@latest my-app -t vite-tailwind --force ``` - npm Pin to a specific template version ```sh npm create xtarter-app@latest -- my-app --ref v1.0.0 ``` - pnpm Pin to a specific template version ```sh pnpm create xtarter-app@latest my-app --ref v1.0.0 ``` - yarn Pin to a specific template version ```sh yarn create xtarter-app my-app --ref v1.0.0 ``` - bun Pin to a specific template version ```sh bun create xtarter-app@latest my-app --ref v1.0.0 ``` [Browse all templates →](/create-xtarter-app/guide/templates/) ## Next steps [Section titled “Next steps”](#next-steps) * [Usage Guide](/create-xtarter-app/getting-started/usage/) - Walk through each prompt and option * [CLI Reference](/create-xtarter-app/guide/cli/) - All commands, arguments, and flags * [Template Catalog](/create-xtarter-app/guide/templates/) - Detailed descriptions of every template * [Keep in Sync](/xtarterize/) - After scaffolding, use xtarterize to maintain your configs # Usage Guide > Step-by-step guide through the create-xtarter-app interactive scaffolding flow. ## Scaffolding a project [Section titled “Scaffolding a project”](#scaffolding-a-project) 1. ### Start the wizard [Section titled “Start the wizard”](#start-the-wizard) * npm ```sh npm create xtarter-app@latest ``` * pnpm ```sh pnpm create xtarter-app@latest ``` * yarn ```sh yarn create xtarter-app ``` * bun ```sh bun create xtarter-app@latest ``` You’ll see a banner and the first prompt. 2. ### Enter a project name [Section titled “Enter a project name”](#enter-a-project-name) The first prompt asks for your project name: ```plaintext ┌ Project name: └ my-new-app ``` * Must be **alphanumeric** plus hyphens and underscores (`my-app_v2`) * Maximum **214 characters** * You can also pass it as a positional argument: `pnpm create xtarter-app my-app` 3. ### Pick a template [Section titled “Pick a template”](#pick-a-template) Choose from the available templates: ```plaintext ┌ Select a template: │ ● Next.js + Chakra UI │ ○ Next.js + Tailwind │ ○ Vite + React + Chakra │ ○ Vite + React + Tailwind │ ○ Vite + React + Hero UI └ ``` Use `--template` / `-t` to skip the prompt: * npm ```sh npm create xtarter-app@latest -- my-app --template vite-tailwind ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template vite-tailwind ``` * yarn ```sh yarn create xtarter-app my-app --template vite-tailwind ``` * bun ```sh bun create xtarter-app@latest my-app --template vite-tailwind ``` 4. ### Choose a package manager [Section titled “Choose a package manager”](#choose-a-package-manager) ```plaintext ┌ Select a package manager: │ ● pnpm (recommended) │ ○ npm │ ○ bun │ ○ yarn └ ``` Use `--pm` / `-p` to skip: * npm ```sh npm create xtarter-app@latest -- my-app --pm bun ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --pm bun ``` * yarn ```sh yarn create xtarter-app my-app --pm bun ``` * bun ```sh bun create xtarter-app@latest my-app --pm bun ``` 5. ### Decide on git init [Section titled “Decide on git init”](#decide-on-git-init) ```plaintext ┌ Initialize a git repository? └ Yes / No ``` * Creates a `.git` repo with an initial commit (`"Initial commit from create-xtarter-app"`) * Requires `git` to be installed on your system * Use `--no-git` to skip 6. ### Clean CI/CD configs (optional) [Section titled “Clean CI/CD configs (optional)”](#clean-cicd-configs-optional) ```plaintext ┌ Remove CI/CD configurations (GitHub Actions, Vercel, etc.)? └ Yes / No ``` When enabled, removes: * `.github/` directory and all workflow files * `.gitlab-ci.yml`, `.travis.yml`, `.circleci/` * `vercel.json`, `netlify.toml`, `.netlify/` * `railway.toml`, `.railway/`, `fly.toml`, `.fly/` Use `--clean` to enable it directly. 7. ### Wait for download and install [Section titled “Wait for download and install”](#wait-for-download-and-install) The CLI downloads the template via tarball (no local Git clone required), modifies the `package.json` name, installs dependencies, and initializes Git if enabled and available. 8. ### You’re ready [Section titled “You’re ready”](#youre-ready) ```plaintext ┌ Success! Project created at /path/to/my-app │ │ Next steps: │ cd my-app │ pnpm dev │ │ Template: Vite + React + Tailwind └ ``` ## Preview a template before scaffolding [Section titled “Preview a template before scaffolding”](#preview-a-template-before-scaffolding) Use the `preview` subcommand to see a template’s details without scaffolding: * npm Choose a template to preview ```sh npm create xtarter-app@latest -- preview ``` * pnpm Choose a template to preview ```sh pnpm create xtarter-app@latest preview ``` * yarn Choose a template to preview ```sh yarn create xtarter-app preview ``` * bun Choose a template to preview ```sh bun create xtarter-app@latest preview ``` - npm Preview a specific template ```sh npm create xtarter-app@latest -- preview vite-tailwind ``` - pnpm Preview a specific template ```sh pnpm create xtarter-app@latest preview vite-tailwind ``` - yarn Preview a specific template ```sh yarn create xtarter-app preview vite-tailwind ``` - bun Preview a specific template ```sh bun create xtarter-app@latest preview vite-tailwind ``` This shows the template’s name, description, repository, branch, and feature list. ## Use defaults mode [Section titled “Use defaults mode”](#use-defaults-mode) Skip the selection prompts with `--yes` / `-y`. The project name is still required for a fully non-interactive run: * npm ```sh npm create xtarter-app@latest -- my-app --yes ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --yes ``` * yarn ```sh yarn create xtarter-app my-app --yes ``` * bun ```sh bun create xtarter-app@latest my-app --yes ``` This uses: pnpm, `next-chakra` template, git init enabled, CI/CD cleanup disabled. ## Skipping git initialization [Section titled “Skipping git initialization”](#skipping-git-initialization) If you don’t want a git repo initialized during scaffolding: * npm ```sh npm create xtarter-app@latest -- my-app --no-git ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --no-git ``` * yarn ```sh yarn create xtarter-app my-app --no-git ``` * bun ```sh bun create xtarter-app@latest my-app --no-git ``` The CLI checks if `git` is installed. If not, git init is skipped automatically. ## Package manager installation [Section titled “Package manager installation”](#package-manager-installation) The CLI runs ` install` after downloading. If installation fails, the process exits with an error. When the CLI created the target directory, it removes that directory during cleanup; if you scaffolded into an existing empty directory, the downloaded files remain and you can run the install manually. ## What’s modified after download [Section titled “What’s modified after download”](#whats-modified-after-download) * **`package.json` name** - normalized to lowercase; unsupported characters become hyphens * **Workspace references** - `workspace:` entries in `pnpm.overrides` are removed * **CI/CD files** - removed if `--clean` is enabled # AI Agent Skills > Install the create-xtarter-app skill for guidance on scaffolding commands, templates, and project creation workflows. Install the create-xtarter-app skill in a compatible AI tool to provide guidance for scaffolding, template selection, and project creation. When installed, your AI assistant knows how to pick the right template from your stack description, use proper flags, and follow best practices. ## Install [Section titled “Install”](#install) ```bash npx skills add agustinusnathaniel/xtarter ``` ## How it works [Section titled “How it works”](#how-it-works) The skill activates when you ask about creating a project or mention a template: | You ask… | The agent… | | ------------------------------------ | ---------------------------------------------------------------------- | | “Scaffold a new project” | Runs interactive mode or suggests a template based on your stack | | “I want a Next.js app with Tailwind” | Maps to `next-tailwind`, runs scaffold with `--template next-tailwind` | | “Create a Vite SPA with Chakra UI” | Maps to `vite-chakra`, runs scaffold with `--template vite-chakra` | | “What templates are available?” | Uses the template catalog to explain the 5 valid IDs | | “Preview the vite-tailwind template” | Runs `preview vite-tailwind` to show repo and branch details | Tip The skill teaches agents to match your stack description to the correct template ID using a decision table, so you don’t need to remember template names. ## What’s included [Section titled “What’s included”](#whats-included) * Scaffold and preview commands with all CLI flags, including `--template`, `--pm`, `--no-git`, `--clean`, `--force`, `--ref`, `--yes`, `--quiet`, and `--json` * Template selection decision table mapping stack descriptions to template IDs * All 5 templates (`next-chakra`, `next-tailwind`, `vite-chakra`, `vite-tailwind`, `vite-hero`) * Agent workflows for scaffolding, previewing, and CI usage * Anti-patterns - common mistakes agents should avoid ## Resources [Section titled “Resources”](#resources) * [CLI Reference](/create-xtarter-app/guide/cli/) - Full command reference * [Templates](/create-xtarter-app/guide/templates/) - Template catalog * [skills.sh](https://skills.sh) - Learn more about AI skills [Browse Templates →](/create-xtarter-app/guide/templates/) # CLI Reference > Complete command reference for create-xtarter-app - all arguments, options, and usage examples. ## Command [Section titled “Command”](#command) ```plaintext npx create-xtarter-app@latest [project-name] [options] ``` ## Arguments [Section titled “Arguments”](#arguments) | Argument | Required | Description | | -------------- | -------- | --------------------------------------------------------- | | `project-name` | No | Name for the new project. If omitted, you’ll be prompted. | ## Options [Section titled “Options”](#options) | Option | Alias | Type | Default | Description | | ------------------------ | ----- | ------- | ------- | ---------------------------------------------------------------------------------------- | | `--template` | `-t` | string | - | Template ID to use (skips prompt). See [Templates](/create-xtarter-app/guide/templates/) | | `--pm` | `-p` | string | - | Package manager (`pnpm`, `npm`, `bun`, `yarn`) | | `--git` / `--no-git` | - | boolean | `true` | Git init is on by default; `--no-git` skips it | | `--clean` | - | boolean | - | Remove CI/CD config files after scaffolding | | `--force` | `-f` | boolean | - | Overwrite existing target directory | | `--ref` | - | string | - | Git ref (branch, tag, or commit SHA) to download | | `--yes` | `-y` | boolean | - | Skip selection prompts and use defaults (`next-chakra`, pnpm, Git init, no cleanup) | | `--quiet` | - | boolean | - | Suppress banners, spinners, and decorative output | | `--json` | - | boolean | - | Output scaffold result as JSON (also suppresses banners and spinners) | | `--color` / `--no-color` | - | boolean | `true` | Colorized output is on by default; `--no-color` disables it | | `--help` | `-h` | boolean | - | Show help text | | `--version` | `-v` | boolean | - | Show version | The project name has no default. Provide `[project-name]` when using `--yes` for a fully non-interactive run; otherwise the CLI still prompts for a name. ## Subcommands [Section titled “Subcommands”](#subcommands) | Command | Description | | -------------------- | -------------------------------------------- | | `preview [template]` | Preview template details without scaffolding | ## Package managers [Section titled “Package managers”](#package-managers) | Manager | Command | Note | | ------- | ------------------- | -------------------------------------- | | `pnpm` | Default for `--yes` | Disk-efficient package management | | `npm` | Supported | npm package manager | | `bun` | Supported | JavaScript runtime and package manager | | `yarn` | Supported | Yarn package manager | ## Examples [Section titled “Examples”](#examples) * npm Interactive ```sh npm create xtarter-app@latest ``` * pnpm Interactive ```sh pnpm create xtarter-app@latest ``` * yarn Interactive ```sh yarn create xtarter-app ``` * bun Interactive ```sh bun create xtarter-app@latest ``` - npm Quick start with defaults ```sh npm create xtarter-app@latest -- my-app --yes ``` - pnpm Quick start with defaults ```sh pnpm create xtarter-app@latest my-app --yes ``` - yarn Quick start with defaults ```sh yarn create xtarter-app my-app --yes ``` - bun Quick start with defaults ```sh bun create xtarter-app@latest my-app --yes ``` * npm Scaffold in current directory ```sh npm create xtarter-app@latest -- . -t vite-tailwind ``` * pnpm Scaffold in current directory ```sh pnpm create xtarter-app@latest . -t vite-tailwind ``` * yarn Scaffold in current directory ```sh yarn create xtarter-app . -t vite-tailwind ``` * bun Scaffold in current directory ```sh bun create xtarter-app@latest . -t vite-tailwind ``` - npm Pick a template ```sh npm create xtarter-app@latest -- my-app --template vite-tailwind ``` - pnpm Pick a template ```sh pnpm create xtarter-app@latest my-app --template vite-tailwind ``` - yarn Pick a template ```sh yarn create xtarter-app my-app --template vite-tailwind ``` - bun Pick a template ```sh bun create xtarter-app@latest my-app --template vite-tailwind ``` * npm Specific package manager, no git ```sh npm create xtarter-app@latest -- my-app --pm bun --no-git ``` * pnpm Specific package manager, no git ```sh pnpm create xtarter-app@latest my-app --pm bun --no-git ``` * yarn Specific package manager, no git ```sh yarn create xtarter-app my-app --pm bun --no-git ``` * bun Specific package manager, no git ```sh bun create xtarter-app@latest my-app --pm bun --no-git ``` - npm Overwrite existing directory ```sh npm create xtarter-app@latest -- my-app -t vite-tailwind --force ``` - pnpm Overwrite existing directory ```sh pnpm create xtarter-app@latest my-app -t vite-tailwind --force ``` - yarn Overwrite existing directory ```sh yarn create xtarter-app my-app -t vite-tailwind --force ``` - bun Overwrite existing directory ```sh bun create xtarter-app@latest my-app -t vite-tailwind --force ``` * npm Download a specific tag ```sh npm create xtarter-app@latest -- my-app --ref v1.0.0 ``` * pnpm Download a specific tag ```sh pnpm create xtarter-app@latest my-app --ref v1.0.0 ``` * yarn Download a specific tag ```sh yarn create xtarter-app my-app --ref v1.0.0 ``` * bun Download a specific tag ```sh bun create xtarter-app@latest my-app --ref v1.0.0 ``` - npm Preview a template ```sh npm create xtarter-app@latest -- preview next-tailwind ``` - pnpm Preview a template ```sh pnpm create xtarter-app@latest preview next-tailwind ``` - yarn Preview a template ```sh yarn create xtarter-app preview next-tailwind ``` - bun Preview a template ```sh bun create xtarter-app@latest preview next-tailwind ``` ## Error handling [Section titled “Error handling”](#error-handling) * **Invalid template ID** - prints all valid template IDs and exits * **Invalid package manager** - prints valid options and exits * **Validation order** - template, package manager, and other explicit inputs are validated before the target directory is created, modified, or deleted, so `--force` never removes a directory for an invalid invocation * **Target directory exists** - cancels with an error unless `--force` is used * **Unknown option or command** - exits `1` before anything runs, with a suggested correction when one is close (for example, `Unknown option --jsn ... Did you mean --json?`), so a typo never silently changes behavior * **Invalid project name** - the interactive prompt rejects names containing characters outside letters, numbers, hyphens, and underscores * **Download failure** - network failures are retried up to 3 times, then the command exits with an error * **Install failure** - cleans up the created directory (if the CLI created it), then exits * **Git init failure** - logs a warning and reports `gitInitialized: false` in `--json` output; the successful scaffold is not discarded * **Partial scaffold** - if a non-git scaffold step fails after download, a directory created by the CLI is cleaned up automatically ## Programmatic API [Section titled “Programmatic API”](#programmatic-api) The package also exports a programmatic API for use in scripts and tooling: ```ts import { downloadTemplateFiles, modifyPackageJson, installDependencies, initializeGit, isGitInstalled, cleanCIConfigs, getTemplateById, getTemplateChoices, TEMPLATES, } from 'create-xtarter-app' // Download a template await downloadTemplateFiles({ template: getTemplateById('vite-tailwind')!, targetPath: './my-app', }) // Modify package.json await modifyPackageJson({ projectPath: './my-app', projectName: 'my-app' }) // Install dependencies await installDependencies({ packageManager: 'pnpm', projectPath: './my-app' }) // Initialize git if (isGitInstalled()) { await initializeGit({ projectPath: './my-app' }) } ``` See [Templates](/create-xtarter-app/guide/templates/) for the full `TemplateConfig` type. # Vite+ Organization Templates > Use @xtarter/create with vp create to scaffold projects via Vite+. [`@xtarter/create`](https://www.npmjs.com/package/@xtarter/create) is a Vite+ organization template package. It exposes the same curated starter templates as `create-xtarter-app` through the `vp create` workflow. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * [Vite+](https://viteplus.dev) installed (`npm install -g vite-plus`) ## Usage [Section titled “Usage”](#usage) ```bash # Interactive picker vp create @xtarter # Direct selection vp create @xtarter:vite-tailwind # With a specific version vp create @xtarter:vite-tailwind@0.1.0 ``` ## Available Templates [Section titled “Available Templates”](#available-templates) | Command | Template | | ---------------------------------- | -------------------------------------------------- | | `vp create @xtarter:next-chakra` | Next.js 16 + Chakra UI v3 + Biome + Turborepo | | `vp create @xtarter:next-tailwind` | Next.js 16 + Tailwind CSS v4 | | `vp create @xtarter:vite-chakra` | Vite+ (Vite 8) + TanStack Router + Chakra UI v3 | | `vp create @xtarter:vite-tailwind` | Vite+ (Vite 8) + TanStack Router + Tailwind CSS v4 | | `vp create @xtarter:vite-hero` | Vite+ (Vite 8) + Hero UI | ## Limitations [Section titled “Limitations”](#limitations) `vp create` copies template files as-is - it does not run a template engine. Unlike `create-xtarter-app`, these are **not** performed automatically: * `package.json` project name update * Dependency installation * Git repository initialization * CI/CD config cleanup If you need the full interactive workflow, use `create-xtarter-app` instead. ## Comparison [Section titled “Comparison”](#comparison) | Feature | `vp create @xtarter` | `create-xtarter-app` | | ---------------------- | ----------------------------------- | ---------------------------------------- | | Template selection | Interactive picker built into Vite+ | Interactive prompts via `@clack/prompts` | | Package manager choice | - (manual) | pnpm, npm, bun, yarn | | Deps installation | - | Auto with chosen package manager | | Git init | - | Auto | | CI/CD cleanup | - | Optional (`--clean`) | | Requires Vite+ | Yes | No | # Templates > All available templates for create-xtarter-app - framework, tools, and features for each. Every template is a production-grade starter with Biome linting & formatting, TypeScript strict mode, GitHub Actions CI, and VS Code settings pre-configured. ## Available Templates [Section titled “Available Templates”](#available-templates) ### Next.js + Chakra UI [Section titled “Next.js + Chakra UI”](#nextjs--chakra-ui) | | | | --------- | ---------------------------------------------------------------------------- | | **ID** | `next-chakra` | | **Stack** | Next.js 16, Chakra UI v3, TypeScript | | **Repo** | [`nextarter-chakra`](https://github.com/agustinusnathaniel/nextarter-chakra) | **Features:** Next.js 16, Chakra UI v3, Biome, Turborepo, TypeScript, Playwright * npm ```sh npm create xtarter-app@latest -- my-app --template next-chakra ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template next-chakra ``` * yarn ```sh yarn create xtarter-app my-app --template next-chakra ``` * bun ```sh bun create xtarter-app@latest my-app --template next-chakra ``` *** ### Next.js + Tailwind [Section titled “Next.js + Tailwind”](#nextjs--tailwind) | | | | --------- | -------------------------------------------------------------------------------- | | **ID** | `next-tailwind` | | **Stack** | Next.js 16, Tailwind CSS v4, TypeScript | | **Repo** | [`nextarter-tailwind`](https://github.com/agustinusnathaniel/nextarter-tailwind) | **Features:** Next.js 16, Tailwind CSS v4, Biome, TypeScript, Playwright * npm ```sh npm create xtarter-app@latest -- my-app --template next-tailwind ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template next-tailwind ``` * yarn ```sh yarn create xtarter-app my-app --template next-tailwind ``` * bun ```sh bun create xtarter-app@latest my-app --template next-tailwind ``` *** ### Vite + React + Chakra [Section titled “Vite + React + Chakra”](#vite--react--chakra) | | | | --------- | ---------------------------------------------------------------------------------------------- | | **ID** | `vite-chakra` | | **Stack** | Vite+ (Vite 8), React 19, Chakra UI v3, TanStack Router | | **Repo** | [`vite-react-chakra-starter`](https://github.com/agustinusnathaniel/vite-react-chakra-starter) | **Features:** Vite+ (Vite 8), React 19, Chakra UI v3, TanStack Router, TanStack Query, Biome, Vitest * npm ```sh npm create xtarter-app@latest -- my-app --template vite-chakra ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template vite-chakra ``` * yarn ```sh yarn create xtarter-app my-app --template vite-chakra ``` * bun ```sh bun create xtarter-app@latest my-app --template vite-chakra ``` *** ### Vite + React + Tailwind [Section titled “Vite + React + Tailwind”](#vite--react--tailwind) | | | | --------- | -------------------------------------------------------------------------------------------------- | | **ID** | `vite-tailwind` | | **Stack** | Vite+ (Vite 8), React 19, Tailwind CSS v4, TanStack Router | | **Repo** | [`vite-react-tailwind-starter`](https://github.com/agustinusnathaniel/vite-react-tailwind-starter) | **Features:** Vite+ (Vite 8), React 19, Tailwind CSS v4, TanStack Router, TanStack Query, Biome, Vitest * npm ```sh npm create xtarter-app@latest -- my-app --template vite-tailwind ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template vite-tailwind ``` * yarn ```sh yarn create xtarter-app my-app --template vite-tailwind ``` * bun ```sh bun create xtarter-app@latest my-app --template vite-tailwind ``` *** ### Vite + React + Hero UI [Section titled “Vite + React + Hero UI”](#vite--react--hero-ui) | | | | --------- | ------------------------------------------------------------------------------------------ | | **ID** | `vite-hero` | | **Stack** | Vite+ (Vite 8), React 19, Hero UI | | **Repo** | [`vite-react-hero-starter`](https://github.com/agustinusnathaniel/vite-react-hero-starter) | **Features:** Vite+ (Vite 8), React 19, Hero UI, TanStack Router, Biome, Vitest * npm ```sh npm create xtarter-app@latest -- my-app --template vite-hero ``` * pnpm ```sh pnpm create xtarter-app@latest my-app --template vite-hero ``` * yarn ```sh yarn create xtarter-app my-app --template vite-hero ``` * bun ```sh bun create xtarter-app@latest my-app --template vite-hero ``` *** ## Template structure [Section titled “Template structure”](#template-structure) Every template follows a consistent layout: ```plaintext my-app/ ├── src/ # Application source ├── public/ # Static assets ├── biome.json # Biome linting + formatting config ├── tsconfig.json # TypeScript strict mode ├── package.json # Dependencies and scripts ├── .vscode/ # Editor settings + extensions ├── .github/workflows/ # CI/CD workflows └── .agents/ # AI agent skills ``` ## TemplateConfig type [Section titled “TemplateConfig type”](#templateconfig-type) For programmatic usage, the `TemplateConfig` type: ```ts interface TemplateConfig { id: string // Unique identifier (e.g. "vite-tailwind") name: string // Human-readable name description: string // One-line description repo: string // GitHub owner/repo branch: string // Git branch (always "main") provider: "github" // Download provider path?: string // Optional subdirectory within repo } ``` # xtarterize > The conformance CLI for JavaScript/TypeScript projects. Detect, validate, and sync your tooling automatically. 01 // 01 ## How a run works Five steps, every run: read the project, resolve tasks, compare files, show the plan, apply with backups. 1. Detect Profile your project: framework, bundler, package manager, existing configs. 2. Resolve Map that profile to the conformance tasks that apply to your stack. 3. Check Compare each file against the standard: new, patch, skip, or conflict. 4. Plan Review the conformance plan before anything is written. 5. Apply Back up originals, then merge or rewrite configs. Current focus: Vite + React + TypeScript Detection covers a wide range of frameworks. Task coverage is deepest for Vite, React, and TypeScript projects. Other stacks such as Vue, Svelte, Solid, Node CLIs, and Bun work but stay experimental: fewer tasks, less maturity. Contributions to expand coverage are welcome. 02 // 02 safety model ## Nothing moves without you Built for repos you care about. Changes are previewed, originals are backed up, and writes happen only when you approve. * ### Preview the plan Run init or sync with --dry-run first. It prints every planned change before anything touches your files. * ### Backups by default Modified files are copied to .xtarterize/backups/ first. Undo and restore are built in. * ### You approve writes init asks before it applies: everything, selected tasks, dry run, or quit. Conflicts surface instead of overwriting your configs. 03 // 03 task catalog ## What it can manage Task groups cover linting, types, CI, editor setup, agent skills, Vite plugins, and more. Each task is small enough to review at a glance. * Linting & Formatting * TypeScript * Vite Plugins * CI/CD * Editor * Agent * Release * [More in the task overview](/xtarterize/guide/tasks/overview/) - [Conformance tasks](/xtarterize/guide/tasks/overview/) - [Configuration](/xtarterize/guide/config/overview/) - [Monorepo support](/xtarterize/guide/monorepo/) 04 // 04 ## Quick start Three commands cover the loop. * npm Initialize conformance ```sh npx xtarterize@latest init ``` * pnpm Initialize conformance ```sh pnpm xtarterize@latest init ``` * yarn Initialize conformance ```sh yarn xtarterize@latest init ``` * bun Initialize conformance ```sh bunx xtarterize@latest init ``` * deno Initialize conformance ```sh deno x xtarterize@latest init ``` * ni Initialize conformance ```sh nlx xtarterize@latest init ``` - npm Check conformance ```sh npx xtarterize@latest check ``` - pnpm Check conformance ```sh pnpm xtarterize@latest check ``` - yarn Check conformance ```sh yarn xtarterize@latest check ``` - bun Check conformance ```sh bunx xtarterize@latest check ``` - deno Check conformance ```sh deno x xtarterize@latest check ``` - ni Check conformance ```sh nlx xtarterize@latest check ``` * npm Preview changes ```sh npx xtarterize@latest diff ``` * pnpm Preview changes ```sh pnpm xtarterize@latest diff ``` * yarn Preview changes ```sh yarn xtarterize@latest diff ``` * bun Preview changes ```sh bunx xtarterize@latest diff ``` * deno Preview changes ```sh deno x xtarterize@latest diff ``` * ni Preview changes ```sh nlx xtarterize@latest diff ``` - [Getting Started](/xtarterize/getting-started/installation/) - [CLI Reference](/xtarterize/guide/cli/overview/) - [Conformance Tasks](/xtarterize/guide/tasks/overview/) ## Starting from scratch? create-xtarter-app scaffolds new projects on this same baseline. [Start with a template](/create-xtarter-app/)[Star on GitHub](https://github.com/agustinusnathaniel/xtarterize) # Changelog > What's new in xtarterize. Latest updates and feature releases for xtarterize. ## v1.23.2 - 2026-08-24 [Section titled “v1.23.2 - 2026-08-24”](#v1232---2026-08-24) ### Honest automation signals [Section titled “Honest automation signals”](#honest-automation-signals) `add --all` in JSON mode now reports failed task checks in the `errors` array and sets `ok` to false, keeping the machine-readable contract aligned with the exit code. ## v1.23.0 - 2026-08-24 [Section titled “v1.23.0 - 2026-08-24”](#v1230---2026-08-24) ### Persistent task selection [Section titled “Persistent task selection”](#persistent-task-selection) Configure `skip` and `only` defaults in `.xtarterizerc` or `package.json`, with command-line flags taking precedence when needed. ### Consistent JSON output [Section titled “Consistent JSON output”](#consistent-json-output) `undo` and `restore` now support machine-readable JSON output, completing a consistent JSON contract across the CLI. ## v1.22.0 - 2026-08-22 [Section titled “v1.22.0 - 2026-08-22”](#v1220---2026-08-22) ### Task-aware query results [Section titled “Task-aware query results”](#task-aware-query-results) Query results now show whether each task is new, changed, skipped, or in conflict, making it easier to decide what to apply. ## v1.20.1 - 2026-08-17 [Section titled “v1.20.1 - 2026-08-17”](#v1201---2026-08-17) ### More reliable automation [Section titled “More reliable automation”](#more-reliable-automation) JSON output now remains valid when there are no pending changes or when a dry run fails. Fresh projects without a lockfile also use the detected package manager for dependency installation. ## v1.20.0 - 2026-08-14 [Section titled “v1.20.0 - 2026-08-14”](#v1200---2026-08-14) ### Machine-readable CLI output [Section titled “Machine-readable CLI output”](#machine-readable-cli-output) `add`, `init`, and `sync` now support JSON output that can be consumed directly by CI pipelines and automation. ### Conflict-aware changes [Section titled “Conflict-aware changes”](#conflict-aware-changes) Conflicting tasks are now reported clearly, and `--include-conflicts` works consistently across `add`, `init`, and `sync`. Individual task-check failures no longer abort the entire command. ## v1.19.0 - 2026-08-11 [Section titled “v1.19.0 - 2026-08-11”](#v1190---2026-08-11) ### CI feedback [Section titled “CI feedback”](#ci-feedback) `check` can now emit GitHub Actions annotations for non-conformant tasks and failing diagnostics, with automatic enablement in GitHub Actions. ### Reliable badges and undo [Section titled “Reliable badges and undo”](#reliable-badges-and-undo) Badge output stays clean in JSON and stdout modes, and `undo` now removes files created by the last run instead of failing when no backup exists. ## v1.18.0 - 2026-08-04 [Section titled “v1.18.0 - 2026-08-04”](#v1180---2026-08-04) ### CI-friendly exit codes [Section titled “CI-friendly exit codes”](#ci-friendly-exit-codes) `check`, `diff`, and `doctor` now return non-zero exit codes when conformance checks, pending changes, or diagnostics fail. Dry-run failures are also reported to CI. ## v1.17.0 - 2026-07-21 [Section titled “v1.17.0 - 2026-07-21”](#v1170---2026-07-21) ### More project setup options [Section titled “More project setup options”](#more-project-setup-options) New `quality/package-engines`, `workspace/pnpm-workspace`, and `release/versionrc` tasks help projects describe their runtime, workspace, and release configuration. ### Better generated configuration [Section titled “Better generated configuration”](#better-generated-configuration) Generated TypeScript, Git hook, VS Code, and CI configuration is stricter and better aligned with modern Node.js projects. Existing workspace files are preserved, and package-manager metadata reflects the project’s actual package manager. ## v1.16.4 - 2026-07-01 [Section titled “v1.16.4 - 2026-07-01”](#v1164---2026-07-01) ### Cleaner project artifacts [Section titled “Cleaner project artifacts”](#cleaner-project-artifacts) The `.xtarterize/` directory for backups and cache is now automatically added to `.gitignore`, keeping generated internals out of project status. ## v1.16.0 - June 29, 2026 [Section titled “v1.16.0 - June 29, 2026”](#v1160---june-29-2026) ### Natural language task query [Section titled “Natural language task query”](#natural-language-task-query) New `xtarterize query ` command that discovers tasks using a pure-algorithmic scoring engine (no AI). Five weighted signals (label, id, group, keywords, config) with Levenshtein fuzzy matching, domain-specific synonym expansion, and coverage-based ranking. Results are grouped by domain bundle (e.g. TypeScript, CI/CD) with per-group actionable `xtarterize add` commands. New `xtarterize init --compose ` flag that reorders init tasks by relevance. ### Task metadata enrichment [Section titled “Task metadata enrichment”](#task-metadata-enrichment) New optional `searchMeta` field on the Task interface (`tags`, `configTargets`, `keywords`) enables richer search. All 26 built-in tasks include search metadata. ## v1.15.2 - June 29, 2026 [Section titled “v1.15.2 - June 29, 2026”](#v1152---june-29-2026) ### Monorepo-aware task filtering [Section titled “Monorepo-aware task filtering”](#monorepo-aware-task-filtering) Running `xtarterize` in a monorepo now shows only relevant tasks for where you’re running from: * Running from the monorepo root? You’ll see CI/CD, release tooling, turbo, renovate, and editor config tasks - not package-level tsconfig or Vite plugin tasks. * Running inside a workspace package? You’ll see tsconfig path aliases, `vite-plugin-checker`, and `rollup-plugin-visualizer` - not root-level CI or release tasks. * Tasks that apply everywhere continue to work as before. Also fixes a detection bug where Node.js projects using Vite for build orchestration were misidentified as `runtime: 'browser'` instead of `runtime: 'node'`. ### Concurrency and CI resilience [Section titled “Concurrency and CI resilience”](#concurrency-and-ci-resilience) Running `xtarterize` concurrently across multiple workspace packages no longer crashes with spurious file-not-found errors thanks to cache collision protection. Tests are also now more resilient to transient failures and version drift in external tools. ## v1.15.0 - June 29, 2026 [Section titled “v1.15.0 - June 29, 2026”](#v1150---june-29-2026) ### Restore, add, and doctor flags [Section titled “Restore, add, and doctor flags”](#restore-add-and-doctor-flags) New flags across the restoration, add, and diagnostic commands: `restore --yes` skips confirmation when restoring the latest backup, while `restore --quiet` suppresses verbose output. `add --all` applies all new and patch tasks without interaction, and `doctor --json` is now visible in command-level `--help`. ### create-xtarter-app scaffolding enhancements [Section titled “create-xtarter-app scaffolding enhancements”](#create-xtarter-app-scaffolding-enhancements) `create-xtarter-app` gains several new flags: `--quiet` suppresses banners and progress output, `--json` outputs the scaffold result as structured JSON, and `--no-color` disables colorized output. The `--yes` flag now defaults to the `next-chakra` template when `-t` is omitted. The help system has been migrated from hand-rolled `HELP_TEXT` to citty auto-generated help. ### Documentation updates [Section titled “Documentation updates”](#documentation-updates) CLI reference documentation in Starlight now covers the new flags, agent skills have been updated for accurate flag references, and JSON output examples have been corrected to match the actual output shape. ## v1.14.3 - June 29, 2026 [Section titled “v1.14.3 - June 29, 2026”](#v1143---june-29-2026) ### Multi-package-manager git hooks [Section titled “Multi-package-manager git hooks”](#multi-package-manager-git-hooks) Git hooks generated by `xtarterize add release/git-hooks` now work across npm, yarn, and bun, using the correct command format for each package manager via `nypm`. ### Engine and safety hardening [Section titled “Engine and safety hardening”](#engine-and-safety-hardening) The minimum Node.js version has been raised to 24 - projects using Node 18–23 now receive a clear error from npm instead of a cryptic runtime failure. Backup collision resolution ensures files with names that could collide in the backup directory (e.g., `a/b.js` and `a__b.js`) use a collision-safe encoding scheme. `xtarterize undo` and `xtarterize restore` now reject restore operations targeting files outside the project root via path traversal protection. ### Detection and dry-run accuracy [Section titled “Detection and dry-run accuracy”](#detection-and-dry-run-accuracy) Vite plugin dry-run output for tasks like `vite-plugin-checker` and `rollup-plugin-visualizer` now matches what `xtarterize add` actually writes. The detection cache has been improved so config directory changes (`.github/`, `.vscode/`, `.changeset/`) are tracked at the file level, ensuring stale project profiles are invalidated when files within these directories change. ## v1.14.2 - June 17, 2026 [Section titled “v1.14.2 - June 17, 2026”](#v1142---june-17-2026) Edge-case hardening across the entire pipeline - no new features, but significantly improved stability for all commands and surfaces. ### CLI resilience improvements [Section titled “CLI resilience improvements”](#cli-resilience-improvements) try/catch guards prevent crashes on individual task failures across `init`, `sync`, `diff`, `add`, `doctor`, and `restore`. The `--skip`/`--only` flags no longer filter phantom empty-string values, and `doctor` uses `Promise.allSettled` for resilient diagnostics when one check fails. ### Core stability hardening [Section titled “Core stability hardening”](#core-stability-hardening) Robust error handling for atomic writes with temp file cleanup ensures no orphaned temp files. Schema validation guards against corrupted cache entries. Fixed a React Native + React co-detection issue that returned `null`. The skipped count now correctly tracks explicit skips from the check phase. ### Task reliability fixes [Section titled “Task reliability fixes”](#task-reliability-fixes) Fixed `this.getScripts` undefined crash in `packageScriptsTask`. The `commitMsgHook` now accepts a package manager parameter instead of hardcoding pnpm. Corrected `check()` return values for proper `conflict` vs `new` status detection. ### UI and JSON output fixes [Section titled “UI and JSON output fixes”](#ui-and-json-output-fixes) The merged multi-diff view now preserves all diffs instead of dropping earlier ones. The JSON `ok` field reflects actual conformance state, not intention. Multiselect cancel properly aborts via `abortIfCancelled`. ### create-xtarter-app cross-platform fixes [Section titled “create-xtarter-app cross-platform fixes”](#create-xtarter-app-cross-platform-fixes) Windows-compatible path handling, fixed pnpm overrides crash, async `readdir` replaces sync `readdirSync`, improved project name sanitization, and proper handling of explicit `false` CLI flag values. ### Documentation corrections [Section titled “Documentation corrections”](#documentation-corrections) Outdated content refreshed - Node.js minimum bumped to 24, missing `--timing` and `--format` flags documented, Rspack added to detected bundlers, task applicability fixed for renovate/lint-staged, and CLI path corrected from `apps/cli` to `apps/xtarterize`. ## v1.14 - May 29, 2026 [Section titled “v1.14 - May 29, 2026”](#v114---may-29-2026) ### Undo command [Section titled “Undo command”](#undo-command) New \`undo\` command `xtarterize undo` reverts the last run by restoring all backed-up files in one command - no need to manually cherry-pick individual file restores. ### Interactive add and conformance badges [Section titled “Interactive add and conformance badges”](#interactive-add-and-conformance-badges) `xtarterize add` without a task ID now shows a grouped multi-select menu for interactive task selection. `xtarterize check --badge ` generates an SVG conformance badge with score, progress bar, and status. ### Task cleanup and framework gating [Section titled “Task cleanup and framework gating”](#task-cleanup-and-framework-gating) Removed `editorconfig`, `nvmrc`, and `agent/skills` tasks - editorconfig is redundant with linters and VS Code settings, nvmrc `lts/*` is too vague, and agent/skills duplicated AGENTS.md content. The `codegen/plop` task now requires a detected framework to be applicable. ## v1.13 - May 17, 2026 [Section titled “v1.13 - May 17, 2026”](#v113---may-17-2026) ### Oxlint and Oxfmt support [Section titled “Oxlint and Oxfmt support”](#oxlint-and-oxfmt-support) Oxlint & Oxfmt support When Vite+ is detected, xtarterize now configures oxlint/oxfmt (via `vp`) instead of Biome as the default linting/formatting stack. Generates `oxlint.config.ts` / `oxfmt.config.ts` (or `.oxlintrc.json` / `.oxfmtrc.json` for existing configs), extends Ultracite presets, and uses a single `vp check` CI step. ### Enhanced lint rule coverage [Section titled “Enhanced lint rule coverage”](#enhanced-lint-rule-coverage) Non-recommended lint rules are now mapped from ESLint configs: `eqeqeq`, `prefer-const`, `no-shadow`, `max-params`, React rules, and Vitest overrides for Oxlint; `noExcessiveCognitiveComplexity` and `useMaxParams` for Biome. ### TypeScript config templates [Section titled “TypeScript config templates”](#typescript-config-templates) Generated config templates for Biome, Oxlint, Oxfmt, and commitlint now ship with proper TypeScript types. ## v1.12 - May 15, 2026 [Section titled “v1.12 - May 15, 2026”](#v112---may-15-2026) ### Node.js 24 minimum requirement [Section titled “Node.js 24 minimum requirement”](#nodejs-24-minimum-requirement) The minimum Node.js version has been bumped to 24. Older versions receive a clear error from npm instead of a cryptic runtime failure. ## v1.11 - May 13, 2026 [Section titled “v1.11 - May 13, 2026”](#v111---may-13-2026) ### Per-task progress indicators [Section titled “Per-task progress indicators”](#per-task-progress-indicators) Each task during `init` and `sync` now shows a spinner animation at the task level, giving you real-time feedback on what’s being applied. The conformance plan table uses colored status tags (`new`, `patch`, `skip`, `conflict`) for at-a-glance understanding. ### Monorepo dependency management [Section titled “Monorepo dependency management”](#monorepo-dependency-management) The workspace flag (`-w`) is now supported for pnpm dependency installs in monorepo roots, making it easier to manage shared dependencies alongside per-package installs. ## v1.10 - May 12, 2026 [Section titled “v1.10 - May 12, 2026”](#v110---may-12-2026) ### Unified diff output format [Section titled “Unified diff output format”](#unified-diff-output-format) A new `--format` flag for `init`, `sync`, `diff`, and `add` commands lets you choose between terminal-friendly and JSON output: * Terminal output Shows `+N -M` change stats per file and `@@` hunk headers in git-style unified diff format. * JSON output Includes structured hunks, stats, and semantic key-level diffs - designed for CI pipelines and AI-agent consumption. ## v1.9 - May 12, 2026 [Section titled “v1.9 - May 12, 2026”](#v19---may-12-2026) ### Changeset-aware release workflows [Section titled “Changeset-aware release workflows”](#changeset-aware-release-workflows) The release workflow task now detects whether your project uses Changesets and generates the appropriate workflow - either `changesets/action@v1` for Changesets projects or tag-push for simple versioning. ### Automatic Node.js version detection [Section titled “Automatic Node.js version detection”](#automatic-nodejs-version-detection) Node.js version is now auto-detected from `.nvmrc` and `package.json engines.node`, ensuring CI and local environments stay in sync. ## v1.8 - May 12, 2026 [Section titled “v1.8 - May 12, 2026”](#v18---may-12-2026) ### Doctor command [Section titled “Doctor command”](#doctor-command) The new `doctor` command provides environment and project health diagnostics: Environment Node version, package manager, OS detection Tools Displays installed tool versions (Biome, oxlint, etc.) Project Project health checks and diagnostics Configuration Config file status and detected settings ### Verbose and JSON output modes [Section titled “Verbose and JSON output modes”](#verbose-and-json-output-modes) The `--verbose` flag provides detailed system information, and JSON output mode enables machine consumption of diagnostic data. ## v1.7 - May 12, 2026 [Section titled “v1.7 - May 12, 2026”](#v17---may-12-2026) ### Native package manager auto-updates [Section titled “Native package manager auto-updates”](#native-package-manager-auto-updates) The auto-update workflow now uses native package manager commands (`pnpm update && pnpm dedupe`) instead of `npm-check-updates`, reducing external dependencies and aligning with package manager best practices. ## v1.6 - May 11, 2026 [Section titled “v1.6 - May 11, 2026”](#v16---may-11-2026) ### JSONC preservation [Section titled “JSONC preservation”](#jsonc-preservation) JSONC preservation Config files now preserve comments, key ordering, indentation style, and trailing commas during edits - no more losing your inline annotations. ### Smarter script management [Section titled “Smarter script management”](#smarter-script-management) Duplicate scripts with the same command are now skipped automatically during package script management. The `"extends": "config:base"` format is treated as equivalent to `"extends": ["config:base"]`, and only missing scripts are added - existing scripts are never overwritten. ## v1.5 - May 8, 2026 [Section titled “v1.5 - May 8, 2026”](#v15---may-8-2026) ### Unified diff format [Section titled “Unified diff format”](#unified-diff-format) All dry-run and diff output now uses a consistent git-style patch view across new, modified, and JSON files, providing a uniform review experience regardless of file type. ## v1.4 - May 8, 2026 [Section titled “v1.4 - May 8, 2026”](#v14---may-8-2026) ### New conformance tasks [Section titled “New conformance tasks”](#new-conformance-tasks) Six new conformance tasks expand xtarterize coverage: EditorConfig `.editorconfig` generation for consistent editor settings npmrc `.npmrc` with strict engine checks and exact version pinning nvmrc Node version pinning in `.nvmrc` lint-staged Run linters only on staged files - faster pre-commit hooks Git hooks Pre-configured git hooks via simple-git-hooks pnpm catalogs Workspace `catalog:` protocol for centralized dependency versions ### Optimized skill installation [Section titled “Optimized skill installation”](#optimized-skill-installation) Skills from the same source repo are now grouped into a single `npx` command with multiple `--skill` flags, reducing redundant downloads and setup time. ## v1.3 - May 2, 2026 [Section titled “v1.3 - May 2, 2026”](#v13---may-2-2026) ### Expanded skills catalog [Section titled “Expanded skills catalog”](#expanded-skills-catalog) The agent skills catalog has been expanded to 20+ stack-specific skills: Frontend / UI `baseline-ui`, `fixing-accessibility`, `fixing-metadata`, `fixing-motion-performance` React `react-dev`, `react-useeffect` Vue / Nuxt `vue`, `vue-best-practices`, `nuxt` Expo / React Native `upgrading-expo`, `vercel-react-native-skills` Build tools `vite`, `vitest`, `tsdown`, `turborepo` Database / Auth `supabase-postgres-best-practices`, `postgres-drizzle`, `redis-best-practices`, `better-auth-best-practices`, `create-auth-skill` AI / SDKs `ai-sdk` Specialized `remotion-best-practices` ## v1.2 - May 1, 2026 [Section titled “v1.2 - May 1, 2026”](#v12---may-1-2026) ### Unified JSON diffs [Section titled “Unified JSON diffs”](#unified-json-diffs) Diffs targeting the same JSON file are now merged into a single unified view instead of separate per-task diffs - see the complete intended state at once. ## v1.1 - April 29, 2026 [Section titled “v1.1 - April 29, 2026”](#v11---april-29-2026) ### Automatic agent skill installation [Section titled “Automatic agent skill installation”](#automatic-agent-skill-installation) Automatic agent skill installation `xtarterize init` now detects your stack and installs relevant agent skills from the [skills.sh](https://skills.sh) ecosystem automatically - React gets React skills, Vue gets Vue skills, no manual setup. ### Config and CLI improvements [Section titled “Config and CLI improvements”](#config-and-cli-improvements) Framework-aware Biome config, Plop templates, and CI workflows are now generated based on your project’s detected stack. The `--cwd` flag is correctly resolved throughout the full pipeline, and conformance plan and dry-run output are rendered as proper tables. ## v1.0 - April 21, 2026 [Section titled “v1.0 - April 21, 2026”](#v10---april-21-2026) ### Initial release [Section titled “Initial release”](#initial-release) Initial release Core commands: `init`, `sync`, `diff`, `doctor`. Full support for Biome, TypeScript strict mode, CI workflows, Renovate, commitlint, VS Code settings, and more. # Architecture Overview > Understand how xtarterize is structured and how the packages work together. xtarterize is organized as a monorepo using [Turborepo](https://turbo.build/repo) for task orchestration, [pnpm](https://pnpm.io/) for package management, and [Vite Plus](https://viteplus.dev) for build, test, and development workflows. ## Package Structure [Section titled “Package Structure”](#package-structure) * packages/ * core/ - [`@xtarterize/core`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/core) - [`detect.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts) + [`detect/`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/core/src/detect), [`resolve.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/resolve.ts), [`apply/`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/core/src/apply), [`backup.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/backup.ts), [`preflight.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/preflight.ts) * … * patchers/ - [`@xtarterize/patchers`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/patchers) - [`json-merge.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/patchers/src/json-merge.ts), [`ast-patch.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/patchers/src/ast-patch.ts) * … * tasks/ - [`@xtarterize/tasks`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/tasks) - [`factory/define-task.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/factory/define-task.ts), [`factory/package-json.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/factory/package-json.ts), all task implementations * … * apps/ * xtarterize/ - **xtarterize** - CLI binary ([citty](https://github.com/unjs/citty) + [@clack/prompts](https://github.com/natemoo-re/clack)) * … * create-xtarter-app/ - **create-xtarter-app** - Template scaffolding CLI ([citty](https://github.com/unjs/citty) + [giget](https://github.com/unjs/giget)) * … * xtarter-create/ - **@xtarter/create** - Vite+ organization template manifest * … * docs/ - @xtarter/docs - This documentation site ([Astro](https://astro.build/)/[Starlight](https://starlight.astro.build/)) * … * test/ * fixtures/ - Test fixtures for various project types * … ## Package Dependencies [Section titled “Package Dependencies”](#package-dependencies) ``` flowchart TD CLI["xtarterize
apps/xtarterize"] --> Core["@xtarterize/core"] CLI --> Tasks["@xtarterize/tasks"] Tasks --> Core Tasks --> Patchers["@xtarterize/patchers"] style CLI fill:#6366f1,color:#fff style Core fill:#22c55e,color:#fff style Tasks fill:#f59e0b,color:#fff style Patchers fill:#a855f7,color:#fff ``` Note `@xtarterize/patchers` and `@xtarterize/core` have no internal workspace dependencies - they are leaf packages that can be used independently. ## How It Works [Section titled “How It Works”](#how-it-works) ``` sequenceDiagram participant User participant CLI as CLI (citty) participant Session as CommandSession participant Core as @xtarterize/core participant Tasks as @xtarterize/tasks participant Patchers as @xtarterize/patchers User->>CLI: xtarterize init CLI->>Session: open(args) Session->>Core: ensureXtarterizeGitignore(cwd) Session->>Core: runPreflight(cwd) Core-->>Session: PreflightResult Session->>Core: detectProject(cwd) + resolveProjectTasks(tasks) Core-->>Session: ProjectProfile + statuses + timing Session->>Core: planTasks(tasks, statuses) Core-->>Session: ApplyPlan (diffs, dependencies, files) Session->>User: reportPlan / confirm (injected prompter) User->>Session: Confirm Session->>Core: executePlan(plan) Core->>Core: backupFile(cwd, filepath) + writeRunManifest Core->>Core: installDependenciesBatch(dependencies) Core->>Tasks: task.apply(cwd, profile) Tasks->>Patchers: mergeJson / patchJson / injectVitePluginIntoCode Patchers-->>Tasks: Modified content Tasks-->>Core: Applied Core-->>Session: ApplyResult Session->>User: report outcome (terminal or JSON) ``` ## Key Design Decisions [Section titled “Key Design Decisions”](#key-design-decisions) * **Detection lives in core** - No CLI dependency, reusable by other consumers * **Tasks are independent** - Each task can run standalone via `add ` * **One resolution per task** - A task spec resolves once and drives check, dry-run, apply, and dependencies, so status and diffs cannot disagree * **Plan, then execute** - `planTasks()` computes statuses, diffs, dependencies, and the backup set without writing; `executePlan()` replays one plan with one backup set and one run manifest * **Dry-run is exact** - The plan’s diffs are the content `executePlan()` writes * **Idempotency is non-negotiable** - Running twice produces no changes on second run * **Templates are parameterized** - All templates receive `ProjectProfile` and adapt accordingly * **One command session** - `CommandSession` owns open, plan, execute, and report; commands declare selection policy and output shape, and prompts are injected (clack in production, scripted in tests) * **Batch install failures surface** - A failed dependency install is reported in the apply result and exit code instead of being logged and ignored ## Development Workflow [Section titled “Development Workflow”](#development-workflow) * Setup ```bash # Install dependencies pnpm install ``` * Build ```bash # Build all packages pnpm build ``` * Test ```bash # Run tests vp test ``` * Check ```bash # Format and lint with Biome pnpm check # Type check separately (Turborepo) pnpm typecheck ``` * Develop ```bash # Start development (watch mode) pnpm dev ``` ## Toolchain [Section titled “Toolchain”](#toolchain) | Tool | Purpose | Command | | ------------------------------------------------------ | --------------------------------- | ------------------------------------------ | | [Vite Plus](https://viteplus.dev) | Build, test, pack, dev server | `vp build`, `vp test`, `vp pack`, `vp dev` | | [Turborepo](https://turbo.build/repo) | Monorepo task orchestration | `turbo run build`, `turbo run typecheck` | | [Biome](https://biomejs.dev/) | Linting and formatting | `biome lint .`, `biome check --write .` | | [pnpm](https://pnpm.io/) | Package management, workspaces | `pnpm install`, `catalog:` for shared deps | | [Changesets](https://github.com/changesets/changesets) | Version management and publishing | `changeset`, `changeset version` | ## References [Section titled “References”](#references) * [Vite Plus Documentation](https://viteplus.dev/guide/) - Unified toolchain for the web * [Turborepo Documentation](https://turbo.build/repo/docs) - Monorepo task orchestration * [pnpm Workspaces](https://pnpm.io/workspaces) - Workspace and monorepo management * [citty](https://github.com/unjs/citty) - Elegant CLI framework for Node.js * [@clack/prompts](https://github.com/natemoo-re/clack) - Interactive command-line prompts * [Astro](https://astro.build/) - Content-focused web framework * [Starlight](https://starlight.astro.build/) - Documentation framework for Astro * [defu](https://github.com/unjs/defu) - Deep merge utility * [magicast](https://github.com/unjs/magicast) - AST manipulation for JavaScript/TypeScript * [picocolors](https://github.com/alexeyraspopov/picocolors) - Tiny terminal colors library * [pkg-types](https://github.com/unjs/pkg-types) - Package.json type definitions and utilities [Explore project detection →](/xtarterize/contributing/core/detect/) # Contributors > People who contribute to xtarterize. Thanks to everyone who contributes to xtarterize. [![Agustinus Nathaniel](https://avatars.githubusercontent.com/u/17046154?v=4 "Agustinus Nathaniel")](https://agustinusnathaniel.com/) [Agustinus Nathaniel](https://agustinusnathaniel.com/) [💻 code📖 doc🎨 design🚇 infra🤔 ideas⚠️ test](https://agustinusnathaniel.com/) [![Bryan Primus](https://avatars.githubusercontent.com/u/46083126?v=4 "Bryan Primus")](https://github.com/bryanprimus) [Bryan Primus](https://github.com/bryanprimus) [💻 code](https://github.com/bryanprimus) # Apply Engine > How xtarterize plans and applies conformance tasks with backups and error handling. The apply engine is the final stage of the conformance pipeline. It plans a task set, backs up modified files, installs dependencies in one batch, runs the tasks, and reports errors. ## Plan and Execute [Section titled “Plan and Execute”](#plan-and-execute) The pipeline is split into a side-effect-free plan and an execution step, so previews are exact and `executePlan()` replays exactly what was planned. ### `planTasks(options)` [Section titled “planTasks(options)”](#plantasksoptions) [`planTasks`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/apply/plan.ts) computes an `ApplyPlan`: 1. **Check** - Resolves each task’s status, reusing statuses already computed during session open 2. **Dry-run** - Collects the diffs for tasks that are not skipped or conflicting 3. **Dependencies** - Asks each runnable task’s `getDeps()` for its packages 4. **Files** - Collects the unique filepaths from the diffs, which is also the backup set `planTasks()` performs no writes, no backups, and no installs: ```typescript import { planTasks } from '@xtarterize/core' const plan = await planTasks({ cwd: '/path/to/project', profile, statuses, // optional: reuse statuses from session open tasks, includeConflicts: true, // optional: allow conflicts }) console.log(plan.entries) // per-task status, diffs, and timing console.log(plan.dependencies) // collected packages to install console.log(plan.files) // files to back up, one manifest for the run ``` ### `executePlan(options)` [Section titled “executePlan(options)”](#executeplanoptions) [`executePlan`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/apply/execute.ts) runs the plan: 1. **Backup** - Backs up every file in the plan once and writes one run manifest 2. **Batch Install** - Installs the plan’s collected dependencies in a single call, grouped by dev/prod 3. **Apply** - Runs `task.apply()` sequentially for each planned task 4. **Report** - Returns `{ applied, skipped, errors, timing }` ```typescript import { executePlan } from '@xtarterize/core' const result = await executePlan({ cwd: '/path/to/project', plan, profile }) console.log(result.applied) // number of successfully applied tasks console.log(result.errors) // error messages for failed tasks and installs ``` ### Composing both [Section titled “Composing both”](#composing-both) Callers that need the plan before executing, such as the CLI’s diff preview and confirmation flow, run both steps directly: ```typescript import { executePlan, planTasks } from '@xtarterize/core' const plan = await planTasks({ cwd: '/path/to/project', profile, tasks }) const result = await executePlan({ cwd: '/path/to/project', plan, profile }) ``` ## Backup System [Section titled “Backup System”](#backup-system) Before any file is modified, the engine creates timestamped backups in `.xtarterize/backups/`: ```plaintext .xtarterize/backups/ ├── .index.json ├── biome.json.2026-04-30T17-36-00-000Z ├── tsconfig.json.2026-04-30T17-36-00-000Z └── ... ``` * Each unique filepath is backed up **once**, even if multiple tasks modify it * Backups are indexed in `.xtarterize/backups/.index.json` for the `restore` command * The `backupFile()` utility handles directory creation and timestamping * The `.xtarterize/` directory is automatically gitignored via ADR 026 - no manual `.gitignore` maintenance needed ## Error Handling [Section titled “Error Handling”](#error-handling) Errors are collected and reported without aborting the entire run: * **Check failures** - A throwing `check()` becomes a `conflict` with an error message and the task is skipped * **Dry-run failures** - Collected in the plan and reported; the file is not backed up and the task is skipped * **Batch install failures** - Recorded in `ApplyResult.errors`. Tasks whose `apply()` needs the missing packages fail individually, while file-only tasks still run * **Apply failures** - Logged with the task ID and error message; subsequent tasks continue Check, dry-run, install, and task-apply failures are collected in the result. Backup or manifest failures can reject the apply before task execution begins. ## References [Section titled “References”](#references) * [Task interface](/xtarterize/contributing/tasks/overview/) * [Task resolution](/xtarterize/contributing/core/resolve/) * [Preflight checks](/xtarterize/contributing/core/preflight/) * [Backup utilities](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/backup.ts) # Project Detection > How xtarterize detects your project's stack and builds a ProjectProfile. The `@xtarterize/core` package provides the `detectProject()` function - the foundation of xtarterize’s context-aware behavior. It analyzes your project directory to build a [`ProjectProfile`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts) that drives which conformance tasks are applicable. `detectProject()` is the orchestration layer in [`packages/core/src/detect.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts). It runs inline detection for framework, router, styling, runtime, and Vite+, and calls the helper modules in [`packages/core/src/detect/`](https://github.com/agustinusnathaniel/xtarterize/tree/main/packages/core/src/detect) for bundler, monorepo, and package-manager detection. The [detection registry](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/registry/index.ts) contributes the keyed detector entries behind the `existing` profile keys plus the inputs consumed by those helpers and by doctor checks (ADR 032). ## Overview [Section titled “Overview”](#overview) Project detection is the first step in every xtarterize command. It analyzes your project directory to build a `ProjectProfile` that drives which conformance tasks are applicable. ### Direct detection [Section titled “Direct detection”](#direct-detection) Detection runs directly on every invocation. There is no profile cache: `detectProject()` inspects the project directory (`package.json`, root config files, lockfiles, config directories, and ancestor markers) and computes a fresh `ProjectProfile` each time. Inline detection modules read most files directly; the registry supplies shared declarations for the keyed detector entries, bundler config extensions, monorepo markers, and lockfile checks. Earlier versions cached the profile in `.xtarterize/cache/profile-fingerprint.json`, keyed by a fingerprint of those inputs (ADR 021, superseded by ADR 034). The cache was removed because a warm cache hit measured about 2.2ms versus about 1.3ms for direct detection, so it added I/O and state without a measurable benefit. The registry does not declare every detector: framework, router, styling, runtime, Vite+, and Node version have no registry consumer and run inline in the detection modules; bundler, monorepo, and package manager run inline but consume registry inputs. The registry declares the keyed detector entries that produce the `existing` keys plus the inputs consumed by bundler config extension lookup, monorepo markers, and doctor lockfile checks. ## detectProject Function [Section titled “detectProject Function”](#detectproject-function) ```typescript import { detectProject } from '@xtarterize/core' const profile = await detectProject('/path/to/project') ``` ## ProjectProfile Schema [Section titled “ProjectProfile Schema”](#projectprofile-schema) The detection returns a `ProjectProfile` object: ```typescript interface ProjectProfile { // Framework framework: 'react' | 'react-native' | 'vue' | 'svelte' | 'solid' | 'node' | null frameworkVersion: string | null // Bundler bundler: 'vite' | 'nextjs' | 'tanstack-start' | 'expo' | 'webpack' | 'rspack' | 'none' | null // Router router: 'tanstack-router' | 'react-router' | 'next' | 'expo-router' | 'vue-router' | null // Styling styling: ('tailwind' | 'css-modules' | 'styled-components' | 'vanilla-extract' | 'nativewind' | 'vanilla')[] // Language & Runtime typescript: boolean runtime: 'browser' | 'node' | 'edge' | 'native' | 'universal' // Package manager packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' // Repo structure monorepo: boolean monorepoTool: 'turbo' | 'nx' | 'lerna' | null workspaceRoot: boolean // Git hasGitHub: boolean hasGit: boolean // Existing config presence existing: { biome: boolean oxlint: boolean oxfmt: boolean eslint: boolean tsconfig: boolean renovate: boolean commitlint: boolean knip: boolean plop: boolean turbo: boolean vscodeSettings: boolean agentsMd: boolean githubWorkflows: string[] viteConfig: boolean versionrc: boolean gitignore: boolean changeset: boolean } // Detected toolchain details nodeVersion: string vitePlus: boolean } ``` The `workspaceRoot` field is set to `true` when the current directory itself contains monorepo markers (`pnpm-workspace.yaml`, `turbo.json`, etc.). It is `false` when running from inside a workspace package discovered via parent-directory walk-up. In non-monorepos, `workspaceRoot` has the same value as `monorepo`. ## Detection Logic [Section titled “Detection Logic”](#detection-logic) ### Detection modules [Section titled “Detection modules”](#detection-modules) * [`detect.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts) - orchestration plus framework, runtime, router, styling, and Vite+ detection * [`registry/index.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/registry/index.ts) - declares the keyed detector entries and the inputs consumed by detection helpers and doctor checks (ADR 032) * [`bundler.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/bundler.ts) - bundler detection from dependencies and config files * [`package-manager.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/package-manager.ts) - package-manager and framework-version detection * [`monorepo.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/monorepo.ts) - workspace and monorepo detection * [`types.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect/types.ts) - shared detection types ## Detection Sources [Section titled “Detection Sources”](#detection-sources) * Dependencies | Signal | Source | | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Framework | [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) dependencies ([`react`](https://react.dev/), [`vue`](https://vuejs.org/), [`react-native`](https://reactnative.dev/), etc.) | | Bundler | [`vite`](https://vitejs.dev/), [`next`](https://nextjs.org/), [`expo`](https://expo.dev/), [`webpack`](https://webpack.js.org/), [`@rspack/core`](https://rspack.dev/) in deps | | Router | [`@tanstack/react-router`](https://tanstack.com/router/latest), [`react-router-dom`](https://reactrouter.com/), [`vue-router`](https://router.vuejs.org/) in deps | | Styling | [`tailwindcss`](https://tailwindcss.com/), [`styled-components`](https://styled-components.com/), [`nativewind`](https://www.nativewind.dev/) in deps | * Filesystem | Signal | Source | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TypeScript | [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) or `tsconfig.jsonc` existence, `typescript` in deps | | Package manager | Lockfile presence ([`pnpm-lock.yaml`](https://pnpm.io/), [`yarn.lock`](https://yarnpkg.com/), [`package-lock.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json), [`bun.lock`](https://bun.sh/docs/install/lockfile), `bun.lockb`) | | Monorepo | [`pnpm-workspace.yaml`](https://pnpm.io/workspaces), [`turbo.json`](https://turbo.build/repo/docs), [`nx.json`](https://nx.dev/reference/nx-json), [`lerna.json`](https://lerna.js.org/docs/configuration), or at least two of `packages/`, `apps/`, `services/` | | GitHub | [`.github/`](https://docs.github.com/en/actions) directory presence | ## Ambiguity Handling [Section titled “Ambiguity Handling”](#ambiguity-handling) Note When both `react` and `react-native` are present in dependencies, `detectProject()` returns `framework: null`. The CLI layer then prompts the user to clarify which describes the project. In `--quiet` mode, it defaults to `react`. ## Example [Section titled “Example”](#example) ```typescript const profile = await detectProject('/path/to/project') if (profile.bundler === 'vite' && profile.typescript) { // Vite plugin tasks will be applicable } if (profile.monorepo && profile.monorepoTool === 'turbo') { // Turbo task may be skip if already configured } ``` See the [configuration guide](/xtarterize/guide/config/overview/) for the user-facing detection summary and the source links above for implementation details. # Preflight & Diagnostics > How xtarterize validates projects before making changes and audits for issues. Before any conformance changes are applied, xtarterize runs a series of validation checks. After changes, it can also diagnose potential issues with your project’s tooling setup. ## Preflight Checks [Section titled “Preflight Checks”](#preflight-checks) Every command that targets a project (`init`, `sync`, `diff`, `check`, `add`, `list`, `query`, `restore`, `undo`, and `doctor`) runs preflight checks via `runPreflight(cwd)` before continuing. ### Validations [Section titled “Validations”](#validations) | Check | Requirement | Error Code | | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------- | | [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) exists | Project root must contain a `package.json` | `MISSING_PACKAGE_JSON` | | [`name`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#name) field present | `package.json` must have a `"name"` field | `INVALID_PACKAGE_JSON` | | [Git](https://git-scm.com/) repository | [`.git`](https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F) directory must exist | `MISSING_GIT` | ### Behavior [Section titled “Behavior”](#behavior) If preflight checks fail, the CLI exits with code `1` and displays all errors with hints: ```plaintext ✖ Preflight checks failed ✗ No package.json found Run xtarterize init from the root of a JS/TS project. ✗ No .git directory found Initialize a git repository with "git init" before running xtarterize. ``` Note A failed preflight prevents conformance tasks from running. The CLI may still maintain `.gitignore` so its internal `.xtarterize/` directory stays out of version control. ## Diagnostics [Section titled “Diagnostics”](#diagnostics) The `check` command runs additional diagnostics to surface potential issues: ### Conflict Checks [Section titled “Conflict Checks”](#conflict-checks) Detects incompatible or redundant tooling configurations: | Check | Condition | Status | | -------------------- | -------------------------------------------------------------------------------------------------------- | ------ | | Biome + ESLint | Both [`@biomejs/biome`](https://biomejs.dev/) and [`eslint`](https://eslint.org/) in dependencies | `warn` | | Biome + Prettier | Both [`@biomejs/biome`](https://biomejs.dev/) and [`prettier`](https://prettier.io/) in dependencies | `warn` | | Legacy ESLint config | [`.eslintrc.*`](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated) file exists | `warn` | | No conflicts | None of the above | `pass` | ### Tool Installation Checks [Section titled “Tool Installation Checks”](#tool-installation-checks) Verifies that tools listed in [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) [`dependencies`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#dependencies)/[`devDependencies`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#devdependencies) are actually installed in [`node_modules`](https://docs.npmjs.com/cli/v10/configuring-npm/folders#node-modules): | Tool | Dependency | Command Checked | | --------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | | [Biome](https://biomejs.dev/) | [`@biomejs/biome`](https://www.npmjs.com/package/@biomejs/biome) | [`biome --version`](https://biomejs.dev/reference/cli/) | | [ESLint](https://eslint.org/) | [`eslint`](https://www.npmjs.com/package/eslint) | [`eslint --version`](https://eslint.org/docs/latest/use/command-line-interface) | | [TypeScript](https://www.typescriptlang.org/) | [`typescript`](https://www.npmjs.com/package/typescript) | [`tsc --version`](https://www.typescriptlang.org/docs/handbook/compiler-options.html) | | [Commitlint](https://commitlint.js.org/) | [`@commitlint/cli`](https://www.npmjs.com/package/@commitlint/cli) | [`commitlint --version`](https://commitlint.js.org/reference/cli.html) | | [Knip](https://knip.dev/) | [`knip`](https://www.npmjs.com/package/knip) | [`knip --version`](https://knip.dev/reference/cli/) | ### Diagnostic Output [Section titled “Diagnostic Output”](#diagnostic-output) ```plaintext Diagnostics ✔ Biome installation - Biome is installed ~ ESLint installation - ESLint is in package.json but not installed (run install) ~ Conflicting tools - Both Biome and ESLint are configured. Consider using one as primary. ``` ## API Reference [Section titled “API Reference”](#api-reference) ### `runPreflight(cwd)` [Section titled “runPreflight(cwd)”](#runpreflightcwd) ```typescript import { runPreflight } from '@xtarterize/core' const result = await runPreflight('/path/to/project') if (!result.valid) { for (const error of result.errors) { console.log(error.code) // 'MISSING_PACKAGE_JSON' console.log(error.message) // 'No package.json found' console.log(error.hint) // 'Run xtarterize init from...' } } ``` ### `runDiagnostics(cwd, options)` [Section titled “runDiagnostics(cwd, options)”](#rundiagnosticscwd-options) ```typescript import { runDiagnostics } from '@xtarterize/core' const { groups, summary } = await runDiagnostics('/path/to/project', { groups: ['tools', 'configuration'], }) for (const group of groups) { console.log(group.title) // 'Tools' for (const check of group.checks) { console.log(check.name) // 'Biome installation' console.log(check.status) // 'pass' | 'warn' | 'fail' console.log(check.message) // 'Biome is installed' } } console.log(summary) // { pass, warn, fail, total } ``` `options.groups` selects a subset of `'environment' | 'tools' | 'project' | 'configuration'` (defaults to all four); `options.verbose` prepends a `System` group with host platform information. A group whose checks throw is replaced by a single failure check, so one broken check never hides the others. ## References [Section titled “References”](#references) * [Biome Documentation](https://biomejs.dev/) - Fast linter and formatter * [ESLint Documentation](https://eslint.org/docs/latest/) - Pluggable JavaScript linter * [Prettier Documentation](https://prettier.io/docs/en/) - Opinionated code formatter * [ESLint Configuration Files (Deprecated)](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated) - Legacy `.eslintrc` format * [TypeScript Documentation](https://www.typescriptlang.org/docs/) - Typed JavaScript * [Commitlint Documentation](https://commitlint.js.org/) - Lint commit messages * [Knip Documentation](https://knip.dev/) - Find unused files and dependencies ## CI Mode [Section titled “CI Mode”](#ci-mode) In CI environments (`CI=true` or `CI=1`), the `--quiet` flag is automatically enabled for all commands, suppressing interactive prompts and verbose output. # Task Resolution > How xtarterize filters tasks by applicability and computes statuses. After project detection builds a [`ProjectProfile`](/xtarterize/contributing/core/detect/), xtarterize resolves which tasks are relevant and what their current status is. ## Resolution Pipeline [Section titled “Resolution Pipeline”](#resolution-pipeline) ```plaintext ProjectProfile → resolveTasks() → applicable tasks → resolveTaskStatuses() → status map ``` ### `resolveTasks(profile, allTasks)` [Section titled “resolveTasks(profile, allTasks)”](#resolvetasksprofile-alltasks) Filters the full task registry to only those where `task.applicable(profile)` returns `true`. This is a pure synchronous filter - no I/O, no side effects. ```typescript import { resolveTasks } from '@xtarterize/core' const applicable = resolveTasks(profile, getAllTasks()) // → only tasks whose conditions are met ``` ### Scope filtering [Section titled “Scope filtering”](#scope-filtering) In addition to `applicable()`, `resolveTasks()` applies a **scope filter** when the project is a monorepo. Each task can declare a `scope` field: ```typescript type TaskScope = 'root' | 'package' | 'both' ``` The scope filter checks the task’s scope against the monorepo position: ```plaintext profile.monorepo === true ├─ profile.workspaceRoot === true → exclude tasks with scope: 'package' └─ profile.workspaceRoot === false → exclude tasks with scope: 'root' ``` In non-monorepo projects, scope filtering is skipped entirely. Tasks without an explicit scope default to `'both'` (included everywhere), preserving backward compatibility for external plugins. ### `resolveTaskStatuses(tasks, cwd, profile)` [Section titled “resolveTaskStatuses(tasks, cwd, profile)”](#resolvetaskstatusestasks-cwd-profile) Runs `task.check()` for each applicable task in parallel and returns a `Map`. Each task determines its own status by inspecting the filesystem. ```typescript import { resolveTaskStatuses } from '@xtarterize/core' const statuses = await resolveTaskStatuses(applicable, cwd, profile) // → Map ``` The four statuses drive which tasks appear as actionable: | Status | Meaning | Actionable for `init` | Actionable for `sync` | | ---------- | ----------------------------- | --------------------------- | --------------------------- | | `new` | Config doesn’t exist yet | Yes | No | | `patch` | Config exists, can be updated | Yes | Yes | | `skip` | Already conformant | No | No | | `conflict` | Incompatible changes needed | Only if explicitly selected | Only if explicitly selected | ## Task Gating Logic [Section titled “Task Gating Logic”](#task-gating-logic) Each task’s `applicable()` method checks `ProjectProfile` properties: ```typescript // TypeScript tasks: only if project uses TS applicable: (profile) => profile.typescript // Vite plugin tasks: only for browser Vite projects applicable: (profile) => profile.bundler === 'vite' && profile.runtime !== 'node' // CI tasks: only if GitHub detected applicable: (profile) => profile.hasGitHub // Turbo task: only if monorepo uses Turborepo applicable: (profile) => profile.monorepoTool === 'turbo' ``` Task statuses are evaluated in parallel with `mapWithConcurrency` (at most 8 checks in flight), making resolution efficient even with many tasks. ## References [Section titled “References”](#references) * [Task interface](/xtarterize/contributing/tasks/overview/) * [Project detection](/xtarterize/contributing/core/detect/) * [Task spec](/xtarterize/contributing/tasks/overview/#task-spec) # JSON Merge > How the JSON merge patcher safely combines configuration objects. The `mergeJson` function performs a deep merge of two JavaScript objects using the [`defu`](https://github.com/unjs/defu) library. It’s used whenever xtarterize needs to modify JSON configuration files like [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/), [`biome.json`](https://biomejs.dev/reference/configuration/), or [`.vscode/settings.json`](https://code.visualstudio.com/docs/getstarted/settings). ## Usage [Section titled “Usage”](#usage) ```typescript import { mergeJson } from '@xtarterize/patchers' const existing = { compilerOptions: { strict: true, target: "ES2022" } } const incoming = { compilerOptions: { incremental: true } } const merged = mergeJson(existing, incoming) // { compilerOptions: { strict: true, target: "ES2022", incremental: true } } ``` ## Parameters [Section titled “Parameters”](#parameters) | Parameter | Type | Description | | ---------- | -------- | ---------------------------------------------- | | `existing` | `object` | The current configuration (takes precedence) | | `incoming` | `object` | The new configuration to merge in (fills gaps) | ## Return Value [Section titled “Return Value”](#return-value) Returns the merged `object`. Existing keys always take precedence over incoming keys. ## Deep Merge Behavior [Section titled “Deep Merge Behavior”](#deep-merge-behavior) Nested objects are merged recursively. Existing keys take precedence, missing keys are filled from incoming: ```typescript const existing = { compilerOptions: { strict: true, // https://www.typescriptlang.org/tsconfig/#strict target: "ES2022" // https://www.typescriptlang.org/tsconfig/#target } } const incoming = { compilerOptions: { incremental: true, // https://www.typescriptlang.org/tsconfig/#incremental tsBuildInfoFile: ".tsbuildinfo" // https://www.typescriptlang.org/tsconfig/#tsBuildInfoFile } } const merged = mergeJson(existing, incoming) // { // compilerOptions: { // strict: true, // preserved from existing // target: "ES2022", // preserved from existing // incremental: true, // added from incoming // tsBuildInfoFile: ".tsbuildinfo" // added from incoming // } // } ``` ### Object vs Array Merge [Section titled “Object vs Array Merge”](#object-vs-array-merge) | Type | Behavior | Example | | ----------- | ----------------------------- | --------------------------------------------------------------- | | **Objects** | Deep merge, existing keys win | `{ a: { b: 1 } }` + `{ a: { c: 2 } }` → `{ a: { b: 1, c: 2 } }` | | **Arrays** | Replace entirely | `{ rules: ["a"] }` + `{ rules: ["b"] }` → `{ rules: ["b"] }` | Tasks that need to combine arrays, such as VS Code extension recommendations, use a custom merge function instead of `mergeJson`. ## `patchJson`: Surgical Text Editing [Section titled “patchJson: Surgical Text Editing”](#patchjson-surgical-text-editing) While `mergeJson` operates on objects, `patchJson` edits JSON text directly using [`jsonc-parser`](https://github.com/microsoft/node-jsonc-parser). It preserves: * Existing comments (`// inline` and `/* block */`) * Key ordering * Whitespace and indentation style * Trailing commas (in JSONC) ### Usage [Section titled “Usage”](#usage-1) ```typescript import { patchJson } from '@xtarterize/patchers' const existing = `{ // Keep this comment "strict": true, "target": "ES2022" }` const incoming = { compilerOptions: { incremental: true } } const result = patchJson(existing, incoming) // { // // Keep this comment // "strict": true, // "target": "ES2022", // "incremental": true // } ``` ### When to Use Each [Section titled “When to Use Each”](#when-to-use-each) | Function | Use When | Preservation | | ----------- | -------------------------------- | ------------------------------- | | `mergeJson` | Object-level logic, deep merging | None (returns new object) | | `patchJson` | Writing changes back to a file | Comments, formatting, key order | `jsonMerge` targets in `@xtarterize/tasks` use both functions: `mergeJson` computes the target state, then `patchJson` applies it surgically to the original text. This shared behavior lives in [`factory/targets.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/factory/targets.ts). # Patchers Overview > How xtarterize safely modifies configuration files. The `@xtarterize/patchers` package provides utilities for safely modifying configuration files without overwriting existing customizations. ## Available Patchers [Section titled “Available Patchers”](#available-patchers) | Patcher | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------- | | `mergeJson` | Deep merge JSON objects using [`defu`](https://github.com/unjs/defu) - existing keys take precedence | | `injectVitePluginIntoCode` | AST-based plugin injection into Vite config source using [`magicast`](https://github.com/unjs/magicast) | ## Architecture [Section titled “Architecture”](#architecture) ``` flowchart TD Task["Conformance Task"] --> P{"Which patcher?"} P -->|"JSON config"| MJ["mergeJson
defu deep merge"] P -->|"Vite config"| AP["injectVitePluginIntoCode
magicast AST"] MJ --> W["Caller writes file"] AP --> W style Task fill:#6366f1,color:#fff style MJ fill:#22c55e,color:#fff style AP fill:#22c55e,color:#fff ``` ## JSON Merge [Section titled “JSON Merge”](#json-merge) ```typescript import { mergeJson } from '@xtarterize/patchers' const existing = { compilerOptions: { strict: true, target: "ES2022" } } const incoming = { compilerOptions: { incremental: true, strict: true } } const merged = mergeJson(existing, incoming) // { compilerOptions: { strict: true, target: "ES2022", incremental: true } } ``` Tip The [`defu`](https://github.com/unjs/defu) library ensures that existing user configuration is never overwritten - incoming values only fill gaps. Learn more in the [JSON Merge](/xtarterize/contributing/patchers/json-merge/) reference. ## AST Patching (Vite Plugins) [Section titled “AST Patching (Vite Plugins)”](#ast-patching-vite-plugins) ```typescript import { injectVitePluginIntoCode } from '@xtarterize/patchers' const result = injectVitePluginIntoCode(source, { configPath: '/path/to/vite.config.ts', importPath: 'vite-plugin-checker', importName: 'checker', pluginExpression: 'checker({ typescript: true })', }) if (!result.success) { console.log(result.fallback) // Manual instructions if AST structure is unsupported } // On success, result.generatedCode holds the transformed source: the caller writes it ``` 1. **Parse** - Parses the Vite config source using `magicast` 2. **Check** - Checks if the plugin is already imported (idempotent) 3. **Insert import** - Inserts the import at the top of the file 4. **Append plugin** - Appends the plugin call to the `plugins` array 5. **Return** - Returns the generated source; the caller decides whether to write it Note If the config structure is non-standard (factory functions, conditional exports), the AST patcher falls back to returning manual instructions rather than corrupting the file. ## References [Section titled “References”](#references) * [defu](https://github.com/unjs/defu) - Deep merge utility for JavaScript objects * [magicast](https://github.com/unjs/magicast) - AST manipulation library for JavaScript/TypeScript * [Vite Plugin API](https://vitejs.dev/guide/api-plugin.html) - How Vite plugins work # Conformance Task Architecture > How tasks are structured, implemented, and contributed to xtarterize. xtarterize applies conformance configuration through discrete, independently applicable tasks. This page covers the architecture and how to contribute new tasks. ## Task Interface [Section titled “Task Interface”](#task-interface) All tasks implement the [`Task`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/_base.ts) interface from `@xtarterize/core`: ```typescript interface Task { id: string label: string group: string scope?: TaskScope // 'root' | 'package' | 'both' applicable: (profile: ProjectProfile) => boolean check: (cwd: string, profile: ProjectProfile) => Promise dryRun: (cwd: string, profile: ProjectProfile) => Promise apply: (cwd: string, profile: ProjectProfile) => Promise getDeps?: ( cwd: string, profile: ProjectProfile ) => Promise> } ``` * **`scope`** - Controls where the task is offered in monorepos: `'root'` (monorepo root only), `'package'` (workspace packages only), or `'both'` (everywhere). Defaults to `'both'` when omitted. Ignored in non-monorepo projects. * **`getDeps`** - Optional dependency declaration. The apply plan collects these across the selected tasks and installs them in one batch before any `apply()` runs. ## Task Architecture [Section titled “Task Architecture”](#task-architecture) ``` classDiagram class Task { +string id +string label +string group +applicable(profile) boolean +check(cwd, profile) TaskStatus +dryRun(cwd, profile) FileDiff[] +apply(cwd, profile) void +getDeps(cwd, profile) TaskDep[] } class TaskStatus { <> new patch skip conflict } class FileDiff { +string filepath +string before +string after } class ProjectProfile { +Framework framework +Bundler bundler +PackageManager packageManager +boolean typescript +boolean monorepo +boolean hasGitHub } Task --> TaskStatus Task --> FileDiff Task --> ProjectProfile ``` ## Task Spec [Section titled “Task Spec”](#task-spec) Most tasks are declared with `defineTask()` in [`factory/define-task.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/factory/define-task.ts) instead of hand-writing the interface. A spec declares metadata, applicability, targets and actions, and dependencies: ```typescript export interface TaskSpec { id: string label: string group: string scope?: TaskScope applicable: (profile: ProjectProfile) => boolean targets?: Array | TargetResolver actions?: Array deps?: DepsDeclaration searchMeta?: SpecSearchMeta } ``` `defineTask()` resolves the spec once per call, so `check`, `dryRun`, `apply`, and `getDeps` all project from the same resolution. Status is a projection of the resolution, not a separate `check` implementation, which is why a task can no longer report `skip` while its diffs would change. ### Target kinds [Section titled “Target kinds”](#target-kinds) A target is one file the task claims, plus how its content is computed: | Kind | Computes | Default status projection | | ------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------- | | `text` | Rendered content with `render(profile, existing)` | absent is `new`, differing content is `conflict`, equal content is `skip` | | `jsonMerge` | Incoming object merged into the existing JSON and patched back | absent is `new`, a real change is `patch`, no change is `skip` | | `packageJson` | A change applied through the package.json owner | same as `jsonMerge`, plus `new` when the file is absent | | `transform` | Content-in, content-out on a discovered file (for example a Vite config) | absent is `new` with no diff, a real change is `patch`, no change is `skip` | Each target accepts an optional `policy` hook. It sees the same `before` and `after` pair the diff was computed from and may override the projected status, for example to force `conflict` when a user set `strict: false`. ### Actions [Section titled “Actions”](#actions) An action has a status probe and a run effect and produces no file diff. `agent/skills-install` is the built-in example: it reports whether the skills are installed and runs the install without pretending a log file is a config target. ### Dependencies [Section titled “Dependencies”](#dependencies) Dependencies are part of the resolution. A `deps` declaration is either a static `TaskDep[]` or a resolver that receives the resolved status and diffs, so a task can request a package only when the resolution will actually need it. `getDeps` is derived from that resolution. ### package.json owner [Section titled “package.json owner”](#packagejson-owner) [`factory/package-json.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/factory/package-json.ts) is the only xtarterize writer of `package.json`. It applies a patch against the current file text, which keeps comments, indentation, and key order intact, and it recomputes the change at apply time so entries added by the package manager or by another task survive. ## Task Directory Structure [Section titled “Task Directory Structure”](#task-directory-structure) * packages/tasks/src/ * agent/ * catalog.ts * skills-install.ts * ci/ * auto-update.ts * ci.ts * release.ts * codegen/ * plop.ts * deps/ * renovate.ts * editor/ * vscode.ts * factory/ * define-task.ts * targets.ts * package-json.ts * package-scripts.ts * equivalence.ts * ops.ts * utils.ts * index.ts * lint/ * biome.ts * oxlint.ts * monorepo/ * turbo.ts * npmrc.ts * quality/ * knip.ts * lint-staged.ts * release/ * cat-version.ts * commitlint.ts * czg.ts * git-hooks.ts * templates/ * agents-md.ts * workflows/ * … * ts/ * strict.ts * paths.ts * incremental.ts * gitignore-tsbuildinfo.ts * vite/ * checker.ts * visualizer.ts ## Adding New Tasks [Section titled “Adding New Tasks”](#adding-new-tasks) 1. Declare the task with `defineTask()` from `packages/tasks/src/factory/define-task.ts` 2. Create your task file in `packages/tasks/src//.ts` 3. Export it from `packages/tasks/src/index.ts` and register it in `getAllTasks()` 4. Add or update tests only when they provide meaningful regression protection. Extend the nearest existing suite when possible; see the repository [`docs/TESTING.md`](https://github.com/agustinusnathaniel/xtarterize/blob/main/docs/TESTING.md) A minimal spec looks like this: ```typescript import { defineTask } from '@/factory/define-task.js' export const myTask = defineTask({ applicable: (profile) => profile.typescript, group: 'TypeScript', id: 'ts/example', label: 'Example TypeScript config', targets: [ { filepath: 'tsconfig.json', kind: 'jsonMerge', incoming: () => ({ compilerOptions: { noUncheckedIndexedAccess: true } }), }, ], }) ``` ## Helper Functions [Section titled “Helper Functions”](#helper-functions) The task layer provides shared helpers for robust equivalence detection: | Helper | Purpose | Location | | ------------------------------ | ----------------------------------------------------------------------- | ------------------------ | | `normalizeLineEndings` | Convert `\r\n` to `\n` before comparison | `factory/utils.ts` | | `resolveTaskFile` | Find a config file across declared extensions | `factory/utils.ts` | | `hasScriptWithEquivalentValue` | Check if an equivalent command already exists under another script name | `factory/equivalence.ts` | ## Conflict Detection Pattern [Section titled “Conflict Detection Pattern”](#conflict-detection-pattern) Targets that patch JSON config files project a **tristate** status to avoid permanent patch loops: | State | Condition | Status | Behavior | | ------------ | ------------------------------- | ---------- | --------------------------- | | **Missing** | Key does not exist | `new` | Add the key | | **Match** | Key exists with expected value | `skip` | No changes | | **Mismatch** | Key exists with different value | `conflict` | Alert user, don’t overwrite | For mismatches that must never be overwritten (for example `strict: false` in tsconfig), the target’s `policy` hook forces `conflict` explicitly. This prevents infinite loops when a user deliberately sets a value that differs from xtarterize’s recommendation. ## References [Section titled “References”](#references) * [defu](https://github.com/unjs/defu) - Deep merge utility used by JSON merge targets * [magicast](https://github.com/unjs/magicast) - AST manipulation for Vite plugin injection * [TypeScript tsconfig](https://www.typescriptlang.org/tsconfig/) - Compiler configuration reference * [Biome Configuration](https://biomejs.dev/reference/configuration/) - `biome.json` schema * [Turborepo Configuration](https://turbo.build/repo/docs/reference/configuration) - `turbo.json` schema * [commitlint Rules](https://commitlint.js.org/reference/rules.html) - Commit message validation rules * [czg Documentation](https://cz-git.qbb.sh/cli/) - Interactive commit helper * [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) - Automated versioning * [Knip Documentation](https://knip.dev/) - Unused code detection * [Plop Documentation](https://plopjs.com/documentation/) - Code scaffolding * [VS Code Settings](https://code.visualstudio.com/docs/getstarted/settings) - Editor configuration [Learn about the overall architecture →](/xtarterize/contributing/architecture/overview/) # Initialization > Initialize conformance configuration for a project with xtarterize. ## Initialize a Project [Section titled “Initialize a Project”](#initialize-a-project) To apply conformance configuration to a project: * npm ```sh npx xtarterize@latest init ``` * pnpm ```sh pnpm xtarterize@latest init ``` * yarn ```sh yarn xtarterize@latest init ``` * bun ```sh bunx xtarterize@latest init ``` * deno ```sh deno x xtarterize@latest init ``` * ni ```sh nlx xtarterize@latest init ``` 1. **Scan** your project directory to detect framework, bundler, package manager, monorepo status, and existing configs 2. **Resolve** which conformance tasks are applicable for your stack 3. **Check** each task’s current status (`new`, `patch`, `skip`, or `conflict`) 4. **Display** a conformance plan table showing what will change 5. **Prompt** you to apply all, select specific tasks, dry-run, or quit ## Example Output [Section titled “Example Output”](#example-output) ```plaintext ✦ Scanning project... Detected: Framework: React 18 Bundler: Vite 5 Package Manager: pnpm Conformance plan: ✔ Biome (lint + format) lint/biome [new] ✔ vite-plugin-checker vite/checker [new] ~ tsconfig - incremental: true ts/incremental [patch] = Turbo monorepo/turbo [skip - no monorepo] [A] Apply all [S] Select items [D] Dry-run [Q] Quit ``` ## Options [Section titled “Options”](#options) | Flag | Description | | ------------------ | ------------------------------------------------------- | | `--dry-run` | Preview all changes without applying anything | | `--yes` | Skip all confirmations, apply all changes automatically | | `--skip ` | Exclude a specific task (comma-separated) | | `--only ` | Apply only a specific task (comma-separated) | | `--quiet` | Suppress interactive prompts and verbose output | ## Examples [Section titled “Examples”](#examples) * npm Preview ```sh npx xtarterize@latest init --dry-run ``` * pnpm Preview ```sh pnpm xtarterize@latest init --dry-run ``` * yarn Preview ```sh yarn xtarterize@latest init --dry-run ``` * bun Preview ```sh bunx xtarterize@latest init --dry-run ``` * deno Preview ```sh deno x xtarterize@latest init --dry-run ``` * ni Preview ```sh nlx xtarterize@latest init --dry-run ``` - npm Apply all ```sh npx xtarterize@latest init --yes ``` - pnpm Apply all ```sh pnpm xtarterize@latest init --yes ``` - yarn Apply all ```sh yarn xtarterize@latest init --yes ``` - bun Apply all ```sh bunx xtarterize@latest init --yes ``` - deno Apply all ```sh deno x xtarterize@latest init --yes ``` - ni Apply all ```sh nlx xtarterize@latest init --yes ``` * npm Skip tasks ```sh npx xtarterize@latest init --skip codegen/plop,agent/skills-install ``` * pnpm Skip tasks ```sh pnpm xtarterize@latest init --skip codegen/plop,agent/skills-install ``` * yarn Skip tasks ```sh yarn xtarterize@latest init --skip codegen/plop,agent/skills-install ``` * bun Skip tasks ```sh bunx xtarterize@latest init --skip codegen/plop,agent/skills-install ``` * deno Skip tasks ```sh deno x xtarterize@latest init --skip codegen/plop,agent/skills-install ``` * ni Skip tasks ```sh nlx xtarterize@latest init --skip codegen/plop,agent/skills-install ``` - npm Only specific ```sh npx xtarterize@latest init --only lint/biome ``` - pnpm Only specific ```sh pnpm xtarterize@latest init --only lint/biome ``` - yarn Only specific ```sh yarn xtarterize@latest init --only lint/biome ``` - bun Only specific ```sh bunx xtarterize@latest init --only lint/biome ``` - deno Only specific ```sh deno x xtarterize@latest init --only lint/biome ``` - ni Only specific ```sh nlx xtarterize@latest init --only lint/biome ``` ## Monorepo projects [Section titled “Monorepo projects”](#monorepo-projects) When you run `xtarterize init` in a monorepo, the set of offered tasks depends on where you run it: * **At the monorepo root** - You’ll see root-level tasks: CI/CD workflows, release tooling (commitlint, czg, git hooks), turbo configuration, editor settings, and root package scripts. Package-level tasks (Vite plugin configuration, tsconfig path aliases) are excluded. * **Inside a workspace package** - You’ll see package-level tasks: Vite plugin configuration, tsconfig path aliases, and other per-package tooling. Root-level tasks (CI/CD, release tooling, turbo) are excluded. This ensures you always see tasks relevant to your current position in the monorepo, without being offered tasks that belong at a different level. See the [Monorepo guide](/xtarterize/guide/monorepo) for a complete reference of which tasks are scoped to which level. ## What it can apply [Section titled “What it can apply”](#what-it-can-apply) `init` applies only the tasks that match the detected project. The task catalog contains the full configuration and applicability details. | Group | What it can add or update | Main condition | | ---------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | | Linting and formatting | Biome for non-Vite+ projects, or Oxlint and Oxfmt for Vite+ projects. Each lint tool uses Ultracite presets. | No conflicting linter configuration | | TypeScript | Strict compiler options, path aliases, incremental builds, and `tsbuildinfo` entries in `.gitignore`. | TypeScript detected | | Vite plugins | `vite-plugin-checker` and `rollup-plugin-visualizer` in `vite.config.*`. | Browser Vite project detected | | CI/CD | GitHub Actions for CI, releases, and scheduled dependency updates. pnpm workflows use `pnpm/setup@v1`. | `.github/` detected | | Dependencies | Renovate configuration. | GitHub detected | | Release | Commitlint, czg, commit-and-tag-version, Git hooks, and changelog configuration. | Always, at the project root | | Quality | Knip and `devEngines`; lint-staged for non-Vite+ projects. | Always, with lint-staged excluded for Vite+ | | Code generation | Framework-specific Plop generators. | Framework detected | | Monorepo and workspace | Turborepo configuration and, for pnpm projects, `pnpm-workspace.yaml`. | Matching monorepo or package-manager signal | | Editor and agent setup | VS Code settings and extensions, `AGENTS.md`, and relevant agent skills. | Editor task is root-scoped; skills require TypeScript | | Package scripts | Standard lint, format, typecheck, test, and package-manager settings. | Always | See the [conformance task catalog](/xtarterize/guide/tasks/overview/) for task IDs, generated files, and detailed conditions. Note Each task checks if it’s already applied and skips if conformant. Running `init` twice produces no changes on the second run. ## Ultracite [Section titled “Ultracite”](#ultracite) [Ultracite](https://ultracite.ai/) is installed automatically alongside any lint tool (Biome, Oxlint, or Oxfmt). The generated configs extend or import Ultracite presets by default - no separate `ultracite init` step needed. xtarterize overlays its own conventions on top of Ultracite defaults where they differ (e.g., kebab-case filenames, single quotes, generic array types). You can further customize by editing the generated config files directly. # Installation > Install and set up xtarterize. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * [Node.js](https://nodejs.org/) 24 or later * A [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)/[TypeScript](https://www.typescriptlang.org/) project (or starting fresh) Note xtarterize requires a [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) with a `name` field and an initialized [Git](https://git-scm.com/) repository. These are validated by the preflight checks before any changes are made. ## Run Without Installing [Section titled “Run Without Installing”](#run-without-installing) You can use xtarterize without installing it globally by using `npx`: * npm ```sh npx xtarterize@latest init ``` * pnpm ```sh pnpm xtarterize@latest init ``` * yarn ```sh yarn xtarterize@latest init ``` * bun ```sh bunx xtarterize@latest init ``` * deno ```sh deno x xtarterize@latest init ``` * ni ```sh nlx xtarterize@latest init ``` This is the recommended approach - you always get the latest version. ## Verify It Works [Section titled “Verify It Works”](#verify-it-works) * npm ```sh npx xtarterize@latest --version ``` * pnpm ```sh pnpm xtarterize@latest --version ``` * yarn ```sh yarn xtarterize@latest --version ``` * bun ```sh bunx xtarterize@latest --version ``` * deno ```sh deno x xtarterize@latest --version ``` * ni ```sh nlx xtarterize@latest --version ``` - npm ```sh npx xtarterize@latest --help ``` - pnpm ```sh pnpm xtarterize@latest --help ``` - yarn ```sh yarn xtarterize@latest --help ``` - bun ```sh bunx xtarterize@latest --help ``` - deno ```sh deno x xtarterize@latest --help ``` - ni ```sh nlx xtarterize@latest --help ``` ## Next Steps [Section titled “Next Steps”](#next-steps) 1. **Initialize a project** - Run `init` to detect and apply conformance. [Learn more →](/xtarterize/getting-started/initialization/) 2. **Check status** - Run `check` to audit current conformance. [CLI Reference →](/xtarterize/guide/cli/overview/) 3. **Explore tasks** - See what conformance tasks are available. [Tasks Guide →](/xtarterize/guide/tasks/overview/) ## References [Section titled “References”](#references) * [Node.js Downloads](https://nodejs.org/) - Download the latest LTS version * [npm npx Documentation](https://docs.npmjs.com/cli/v10/commands/npx) - Using npx to run packages without installing * [Git Documentation](https://git-scm.com/doc) - Getting started with Git version control [Initialize your project →](/xtarterize/getting-started/initialization/) # Introduction > Learn what xtarterize is and how it automates conformance configuration for JS/TS projects. Current focus: Vite + React + TypeScript The deepest task coverage is for projects using **Vite**, **React**, and **TypeScript**. Other stacks (Vue, Svelte, Solid, Node CLI, Bun, etc.) are detected and partially supported, but their conformance tasks are **experimental** - fewer tasks may apply and coverage is less mature. xtarterize scans [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)/[TypeScript](https://www.typescriptlang.org/) projects, selects the conformance tasks that apply, previews the resulting changes, and applies approved updates. ## Why xtarterize? [Section titled “Why xtarterize?”](#why-xtarterize) Modern JS/TS projects often need several kinds of tooling configuration: [linters](https://biomejs.dev/), [formatters](https://biomejs.dev/), [bundler plugins](https://vitejs.dev/guide/using-plugins.html), [TypeScript settings](https://www.typescriptlang.org/tsconfig/), [CI/CD workflows](https://docs.github.com/en/actions), [release automation](https://github.com/absolute-version/commit-and-tag-version), [dependency management](https://docs.renovatebot.com/), [editor settings](https://code.visualstudio.com/docs/getstarted/settings), and [AI agent skills](https://skills.sh). Setting them up consistently is: * **Repetitive** - the same configs are rewritten or copy-pasted project to project * **Error-prone** - manual patching of [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json), [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/), or [`vite.config.ts`](https://vitejs.dev/config/) often misses edge cases * **Inconsistent** - configs diverge between projects over time as standards evolve * **Context-blind** - a [React](https://react.dev/) project needs different config than a [React Native](https://reactnative.dev/) or [Vue](https://vuejs.org/) project xtarterize detects the project before selecting tasks, preserves existing values by default, reports conflicts instead of overwriting them, and makes repeat runs idempotent. ## How it works [Section titled “How it works”](#how-it-works) 1. **Detect** - Scans your project to build a full [`ProjectProfile`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/core/src/detect.ts) (framework, bundler, styling, package manager, monorepo status, existing configs) 2. **Resolve** - Maps the profile to applicable conformance tasks (e.g., [Vite](https://vitejs.dev/) tasks only for Vite projects) 3. **Check** - Determines each task’s status: `new` (file doesn’t exist), `patch` (needs merging), `skip` (already conformant), or `conflict` (incompatible) 4. **Plan** - Displays a conformance plan table for review 5. **Apply** - Backs up files, then applies changes using [deep merge](https://github.com/unjs/defu) or [AST manipulation](https://github.com/unjs/magicast) ## Starting a new project [Section titled “Starting a new project”](#starting-a-new-project) If you’re bootstrapping a fresh project, consider using [**create-xtarter-app**](https://github.com/agustinusnathaniel/create-xtarter-app) first. It scaffolds curated starter templates (Next.js/Vite + Chakra/Tailwind/Hero UI) in seconds, then you can run `xtarterize init` to layer on additional conformance configs. ### 1. Scaffold a new project [Section titled “1. Scaffold a new project”](#1-scaffold-a-new-project) * npm ```sh npm create xtarter-app@latest -- my-app ``` * pnpm ```sh pnpm create xtarter-app@latest my-app ``` * yarn ```sh yarn create xtarter-app my-app ``` * bun ```sh bun create xtarter-app@latest my-app ``` ### 2. Apply additional conformance [Section titled “2. Apply additional conformance”](#2-apply-additional-conformance) ```bash cd my-app ``` * npm ```sh npx xtarterize@latest init ``` * pnpm ```sh pnpm xtarterize@latest init ``` * yarn ```sh yarn xtarterize@latest init ``` * bun ```sh bunx xtarterize@latest init ``` * deno ```sh deno x xtarterize@latest init ``` * ni ```sh nlx xtarterize@latest init ``` ## See also [Section titled “See also”](#see-also) * [Installation](/xtarterize/getting-started/installation/) * [CLI reference](/xtarterize/guide/cli/overview/) * [Conformance tasks](/xtarterize/guide/tasks/overview/) [Install xtarterize →](/xtarterize/getting-started/installation/) # AI Agent Skills > Install the xtarterize skill for guidance on CLI commands, JSON output, tasks, and conformance workflows. Install the xtarterize skill in a compatible AI tool to provide guidance for the CLI, its JSON output, tasks, and conformance workflows. When installed, your AI assistant knows how to use `--json`, parse task statuses, follow agent workflows, and avoid common mistakes. ## Install [Section titled “Install”](#install) ```bash npx skills add agustinusnathaniel/xtarter ``` ## How it works [Section titled “How it works”](#how-it-works) The skill activates when you ask about conformance, linting, CI, or any xtarterize task: | You ask… | The agent… | | --------------------------------- | ----------------------------------------------------------------------------- | | “Set up linting for this project” | Runs `check --json`, parses task statuses, applies `init` or `add lint/biome` | | “Check our conformance status” | Runs `check --json`, reports which tasks are `skip` vs `new`/`patch` | | “Add TypeScript strict mode” | Loads the task catalog, runs `add ts/strict --json` | | “What would change if I init?” | Runs `diff --json`, presents structured file diffs | | “Run diagnostics” | Runs `doctor --json`, reports any `fail` diagnostics | | “Restore a backup” | Uses `restore` to recover from `.xtarterize/backups/` | Tip The skill teaches agents to use `–json` for every command and parse the structured output rather than terminal text. ## What’s included [Section titled “What’s included”](#whats-included) * All 10 CLI commands (`init`, `sync`, `diff`, `check`, `add`, `list`, `query`, `restore`, `undo`, `doctor`) * JSON output shapes for every command * Parsing patterns - which JSON fields to inspect to decide the next action * The 4 task statuses (`new`, `patch`, `skip`, `conflict`) and how to handle each * Agent workflows for initialization, single tasks, diagnostics, and backups * Anti-patterns - common mistakes agents should avoid ## Resources [Section titled “Resources”](#resources) * [CLI Reference](/xtarterize/guide/cli/overview/) - Full command reference * [Conformance Tasks](/xtarterize/guide/tasks/overview/) - Task catalog * [skills.sh](https://skills.sh) - Learn more about AI skills [View CLI Reference →](/xtarterize/guide/cli/overview/) # CLI Overview > Complete reference for the xtarterize command-line interface. The xtarterize CLI provides commands to detect, apply, and maintain conformance configuration for [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)/[TypeScript](https://www.typescriptlang.org/) projects. ## Options [Section titled “Options”](#options) Flags are declared per command and must be passed after the command name. The entry command declares no options of its own, so `xtarterize --json check` is rejected with an actionable error; use `xtarterize check --json` instead. | Option | Commands | Description | | -------------- | ------------------ | ----------------------------------------------------- | | `--cwd ` | all | Target directory (default: current working directory) | | `--json` | all | Output machine-readable JSON | | `--quiet` | all except `query` | Suppress interactive prompts and verbose output | | `--help` | all | Show help for a command | | `--version` | entry | Show version number | ## Available Commands [Section titled “Available Commands”](#available-commands) | Command | Description | | --------------------------------------- | ----------------------------------------------- | | [`xtarterize init`](#init) | Full conformance setup - detect, plan, apply | | [`xtarterize sync`](#sync) | Update existing configs to latest templates | | [`xtarterize diff`](#diff) | Show pending changes without applying | | [`xtarterize check`](#check) | Audit current conformance status | | [`xtarterize doctor`](#doctor) | Run environment, tools, and project diagnostics | | [`xtarterize add [task-id]`](#add) | Apply a single task, or pick interactively | | [`xtarterize undo`](#undo) | Undo the last run by restoring backed-up files | | [`xtarterize restore `](#restore) | Restore a file from backup | | [`xtarterize list`](#list) | List all available tasks with status | | [`xtarterize query`](#query) | Search tasks by natural language query | ## Exit Codes [Section titled “Exit Codes”](#exit-codes) The CLI follows the Unix convention: exit code `0` means success, `1` means the command found something that needs attention. This makes `xtarterize` usable as a CI gate. | Command | Exit 0 | Exit 1 | | -------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------- | | `check` | Fully conformant, no failing diagnostics | Pending changes or failing diagnostics | | `diff` | No pending changes, all dry runs succeed | At least one pending change, or a task failed to dry-run | | `doctor` | All diagnostics pass | At least one diagnostic fails | | `add` | All requested tasks applied | Task not found, or at least one task failed to apply | | `init` / `sync` | All updates applied | At least one task failed to apply | | `init` / `sync` with `--dry-run` | No pending changes, all dry runs succeed | At least one pending change (same contract as `diff`), or a task failed to dry-run | | `undo` | All files restored | Nothing to undo, or at least one file failed to restore | | `restore` | File restored | No backup found, or restore failed | ```bash # Fail CI when the project is not conformant npx xtarterize check --quiet || exit 1 ``` Invalid invocations also exit `1` before any command runs: unknown commands and unknown options print an actionable line on stderr with a suggested correction when one is close (for example, `Unknown option --jsn for "xtarterize check". Did you mean --json?`), so a typo never silently changes behavior. In GitHub Actions, `check` also emits native workflow command annotations - one `::error` per non-conformant task (linked to the config file it would modify) and one per failing diagnostic - so failures appear inline on the PR. Annotations are written to stderr, so `--json` and `--badge -` output stays machine-readable: * npm CI annotations ```sh npx xtarterize@latest check --annotations ``` * pnpm CI annotations ```sh pnpm xtarterize@latest check --annotations ``` * yarn CI annotations ```sh yarn xtarterize@latest check --annotations ``` * bun CI annotations ```sh bunx xtarterize@latest check --annotations ``` * deno CI annotations ```sh deno x xtarterize@latest check --annotations ``` * ni CI annotations ```sh nlx xtarterize@latest check --annotations ``` ## `doctor` [Section titled “doctor”](#doctor) Run comprehensive project diagnostics. Checks are grouped into four categories: | Group | Checks | | ----------------- | -------------------------------------------------------------------- | | **Environment** | Node.js version against `engines.node`, Git installation | | **Tools** | Required tools from `package.json` are installed (with version info) | | **Project** | Lockfile, `tsconfig.json`, `README.md`, `.gitignore` | | **Configuration** | Conflicting tool detection (e.g., Biome + ESLint/Prettier) | ### Options [Section titled “Options”](#options-1) | Option | Description | | ----------- | ---------------------------------------------------------- | | `--verbose` | Show system information (OS, architecture, CPU count, RAM) | | `--quiet` | Suppress detailed output, show summary only | | `--json` | Output machine-readable JSON diagnostics | * npm ```sh npx xtarterize@latest doctor ``` * pnpm ```sh pnpm xtarterize@latest doctor ``` * yarn ```sh yarn xtarterize@latest doctor ``` * bun ```sh bunx xtarterize@latest doctor ``` * deno ```sh deno x xtarterize@latest doctor ``` * ni ```sh nlx xtarterize@latest doctor ``` - npm Verbose ```sh npx xtarterize@latest doctor --verbose ``` - pnpm Verbose ```sh pnpm xtarterize@latest doctor --verbose ``` - yarn Verbose ```sh yarn xtarterize@latest doctor --verbose ``` - bun Verbose ```sh bunx xtarterize@latest doctor --verbose ``` - deno Verbose ```sh deno x xtarterize@latest doctor --verbose ``` - ni Verbose ```sh nlx xtarterize@latest doctor --verbose ``` With `--verbose`, a **System** group adds platform, OS release, architecture, CPU count, and RAM. Diagnostics also support `--json`. ## `init` [Section titled “init”](#init) Full conformance setup. Detects your project stack, shows a plan, and applies changes. ### Options [Section titled “Options”](#options-2) | Option | Description | | --------------------- | ------------------------------------------------------------- | | `--dry-run` | Preview all changes without applying | | `--yes` | Skip all confirmations, apply all changes automatically | | `--compose ` | Rank tasks by relevance to a natural language query | | `--threshold ` | Minimum relevance score for `--compose` (0-1, default: `0.1`) | | `--skip ` | Exclude a specific task (comma-separated) | | `--only ` | Apply only a specific task (comma-separated) | | `--quiet` | Suppress interactive prompts and verbose output | | `--include-conflicts` | Include conflicting tasks when applying (default: false) | | `--format ` | Output format (`terminal` or `json`) | | `--timing` | Show detailed per-task timing breakdown | * npm Basic ```sh npx xtarterize@latest init ``` * pnpm Basic ```sh pnpm xtarterize@latest init ``` * yarn Basic ```sh yarn xtarterize@latest init ``` * bun Basic ```sh bunx xtarterize@latest init ``` * deno Basic ```sh deno x xtarterize@latest init ``` * ni Basic ```sh nlx xtarterize@latest init ``` - npm Dry run ```sh npx xtarterize@latest init --dry-run ``` - pnpm Dry run ```sh pnpm xtarterize@latest init --dry-run ``` - yarn Dry run ```sh yarn xtarterize@latest init --dry-run ``` - bun Dry run ```sh bunx xtarterize@latest init --dry-run ``` - deno Dry run ```sh deno x xtarterize@latest init --dry-run ``` - ni Dry run ```sh nlx xtarterize@latest init --dry-run ``` * npm Auto-apply ```sh npx xtarterize@latest init --yes ``` * pnpm Auto-apply ```sh pnpm xtarterize@latest init --yes ``` * yarn Auto-apply ```sh yarn xtarterize@latest init --yes ``` * bun Auto-apply ```sh bunx xtarterize@latest init --yes ``` * deno Auto-apply ```sh deno x xtarterize@latest init --yes ``` * ni Auto-apply ```sh nlx xtarterize@latest init --yes ``` - npm Skip tasks ```sh npx xtarterize@latest init --skip lint/oxlint ``` - pnpm Skip tasks ```sh pnpm xtarterize@latest init --skip lint/oxlint ``` - yarn Skip tasks ```sh yarn xtarterize@latest init --skip lint/oxlint ``` - bun Skip tasks ```sh bunx xtarterize@latest init --skip lint/oxlint ``` - deno Skip tasks ```sh deno x xtarterize@latest init --skip lint/oxlint ``` - ni Skip tasks ```sh nlx xtarterize@latest init --skip lint/oxlint ``` * npm Only specific ```sh npx xtarterize@latest init --only lint/biome,ts/incremental ``` * pnpm Only specific ```sh pnpm xtarterize@latest init --only lint/biome,ts/incremental ``` * yarn Only specific ```sh yarn xtarterize@latest init --only lint/biome,ts/incremental ``` * bun Only specific ```sh bunx xtarterize@latest init --only lint/biome,ts/incremental ``` * deno Only specific ```sh deno x xtarterize@latest init --only lint/biome,ts/incremental ``` * ni Only specific ```sh nlx xtarterize@latest init --only lint/biome,ts/incremental ``` ## `sync` [Section titled “sync”](#sync) Update existing project configs to match the latest conformance templates. Only shows tasks with `patch` or `conflict` status. ### Options [Section titled “Options”](#options-3) | Option | Description | | --------------------- | -------------------------------------------------------- | | `--dry-run` | Preview changes without applying | | `--yes` | Skip all confirmations, apply all updates automatically | | `--skip ` | Exclude a specific task (comma-separated) | | `--only ` | Apply only a specific task (comma-separated) | | `--quiet` | Suppress interactive prompts and verbose output | | `--include-conflicts` | Include conflicting tasks when applying (default: false) | | `--format ` | Output format (`terminal` or `json`) | | `--timing` | Show detailed per-task timing breakdown | * npm ```sh npx xtarterize@latest sync ``` * pnpm ```sh pnpm xtarterize@latest sync ``` * yarn ```sh yarn xtarterize@latest sync ``` * bun ```sh bunx xtarterize@latest sync ``` * deno ```sh deno x xtarterize@latest sync ``` * ni ```sh nlx xtarterize@latest sync ``` - npm Dry run ```sh npx xtarterize@latest sync --dry-run ``` - pnpm Dry run ```sh pnpm xtarterize@latest sync --dry-run ``` - yarn Dry run ```sh yarn xtarterize@latest sync --dry-run ``` - bun Dry run ```sh bunx xtarterize@latest sync --dry-run ``` - deno Dry run ```sh deno x xtarterize@latest sync --dry-run ``` - ni Dry run ```sh nlx xtarterize@latest sync --dry-run ``` * npm Auto-apply ```sh npx xtarterize@latest sync --yes ``` * pnpm Auto-apply ```sh pnpm xtarterize@latest sync --yes ``` * yarn Auto-apply ```sh yarn xtarterize@latest sync --yes ``` * bun Auto-apply ```sh bunx xtarterize@latest sync --yes ``` * deno Auto-apply ```sh deno x xtarterize@latest sync --yes ``` * ni Auto-apply ```sh nlx xtarterize@latest sync --yes ``` Note Unlike `init`, `sync` only targets tasks with `patch` or `conflict` status. It won’t re-apply already conformant configs. ## `diff` [Section titled “diff”](#diff) Show pending changes for all tasks with `new`, `patch`, or `conflict` status, without applying anything. Read-only. Uses [unified diffs](https://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html) for patch comparisons. ### Options [Section titled “Options”](#options-4) | Option | Description | | ------------------- | ------------------------------------ | | `--quiet` | Suppress verbose output | | `--format ` | Output format (`terminal` or `json`) | * npm ```sh npx xtarterize@latest diff ``` * pnpm ```sh pnpm xtarterize@latest diff ``` * yarn ```sh yarn xtarterize@latest diff ``` * bun ```sh bunx xtarterize@latest diff ``` * deno ```sh deno x xtarterize@latest diff ``` * ni ```sh nlx xtarterize@latest diff ``` Tip The `diff` command shows full file contents for `new` tasks (files that don’t exist yet) and [unified diffs](https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html) for `patch` tasks (existing files that need updates). Note When multiple tasks modify the same JSON file (e.g., `tsconfig.json`), `diff` merges their changes into a single unified diff so you see the complete intended state rather than overlapping individual patches. ## `check` [Section titled “check”](#check) Audit which tasks are conformant and which need attention. Also runs diagnostics for conflicting tools and missing installations. ### Options [Section titled “Options”](#options-5) | Option | Description | | ---------------- | --------------------------------------------------------------------- | | `--quiet` | Suppress verbose output | | `--badge ` | Generate a conformance badge SVG (use `-` for stdout) | | `--annotations` | Emit GitHub Actions workflow command annotations (auto-enabled in CI) | * npm ```sh npx xtarterize@latest check ``` * pnpm ```sh pnpm xtarterize@latest check ``` * yarn ```sh yarn xtarterize@latest check ``` * bun ```sh bunx xtarterize@latest check ``` * deno ```sh deno x xtarterize@latest check ``` * ni ```sh nlx xtarterize@latest check ``` - npm Badge ```sh npx xtarterize@latest check --badge conformance.svg ``` - pnpm Badge ```sh pnpm xtarterize@latest check --badge conformance.svg ``` - yarn Badge ```sh yarn xtarterize@latest check --badge conformance.svg ``` - bun Badge ```sh bunx xtarterize@latest check --badge conformance.svg ``` - deno Badge ```sh deno x xtarterize@latest check --badge conformance.svg ``` - ni Badge ```sh nlx xtarterize@latest check --badge conformance.svg ``` Output shows: | Icon | Status | Meaning | | ---- | ---------- | --------------------------------------------- | | ✔ | `skip` | Conformant - no action needed | | \~ | `patch` | Needs update - will be patched | | ✗ | `new` | Missing entirely - will be created | | ⚠ | `conflict` | Incompatible config - needs manual resolution | `check` also displays diagnostics for: * **Conflicting tools** - Biome + ESLint/Prettier detected together * **Legacy configs** - ESLint flat config migration recommendations * **Tool installations** - Tools in package.json but not installed locally ## `add` [Section titled “add”](#add) Apply a single conformance task, or pick interactively from a grouped menu. When called **with a task ID**, applies that specific task after showing a diff preview and confirmation. When called **without a task ID**, shows a grouped multi-select menu of all applicable tasks with their current status. ### Options [Section titled “Options”](#options-6) | Option | Description | | --------------------- | ------------------------------------------------------------ | | `--quiet` | Suppress interactive prompts | | `--format ` | Output format (`terminal` or `json`) | | `--timing` | Show detailed per-task timing breakdown | | `--all` | Apply all applicable new and patch tasks without interaction | | `--include-conflicts` | Include conflicting tasks when applying (default: false) | * npm Specific task ```sh npx xtarterize@latest add lint/biome ``` * pnpm Specific task ```sh pnpm xtarterize@latest add lint/biome ``` * yarn Specific task ```sh yarn xtarterize@latest add lint/biome ``` * bun Specific task ```sh bunx xtarterize@latest add lint/biome ``` * deno Specific task ```sh deno x xtarterize@latest add lint/biome ``` * ni Specific task ```sh nlx xtarterize@latest add lint/biome ``` - npm Interactive ```sh npx xtarterize@latest add ``` - pnpm Interactive ```sh pnpm xtarterize@latest add ``` - yarn Interactive ```sh yarn xtarterize@latest add ``` - bun Interactive ```sh bunx xtarterize@latest add ``` - deno Interactive ```sh deno x xtarterize@latest add ``` - ni Interactive ```sh nlx xtarterize@latest add ``` Browse tasks by category, select multiple, and apply with per-task confirmation. * npm All tasks ```sh npx xtarterize@latest add --all ``` * pnpm All tasks ```sh pnpm xtarterize@latest add --all ``` * yarn All tasks ```sh yarn xtarterize@latest add --all ``` * bun All tasks ```sh bunx xtarterize@latest add --all ``` * deno All tasks ```sh deno x xtarterize@latest add --all ``` * ni All tasks ```sh nlx xtarterize@latest add --all ``` Apply all applicable new and patch tasks in one pass with no interaction. ## `undo` [Section titled “undo”](#undo) Undo the last `init`, `sync`, or `add` run by restoring all files that were backed up. Reads the run manifest (`.xtarterize/backups/last-run.json`) written during apply to identify which files to restore. ### Options [Section titled “Options”](#options-7) | Option | Description | | ------------------- | ------------------------------------ | | `--quiet` | Skip confirmation prompt | | `--json` | Output machine-readable JSON | | `--format ` | Output format (`terminal` or `json`) | * npm ```sh npx xtarterize@latest undo ``` * pnpm ```sh pnpm xtarterize@latest undo ``` * yarn ```sh yarn xtarterize@latest undo ``` * bun ```sh bunx xtarterize@latest undo ``` * deno ```sh deno x xtarterize@latest undo ``` * ni ```sh nlx xtarterize@latest undo ``` - npm JSON output ```sh npx xtarterize@latest undo --json ``` - pnpm JSON output ```sh pnpm xtarterize@latest undo --json ``` - yarn JSON output ```sh yarn xtarterize@latest undo --json ``` - bun JSON output ```sh bunx xtarterize@latest undo --json ``` - deno JSON output ```sh deno x xtarterize@latest undo --json ``` - ni JSON output ```sh nlx xtarterize@latest undo --json ``` ```bash $ npx xtarterize undo --json {"ok":true,"timestamp":"2026-08-22T12:00:00.000Z","restored":2,"total":2,"files":["biome.json","tsconfig.json"],"errors":[],"removed":1} ``` `removed` appears only when the run created files that had no backup to restore from — undo deletes them to return the project to its pre-run state. Tip The `undo` command restores all files from the most recent run in one step. For single-file restores, use `xtarterize restore ` instead. ## `restore` [Section titled “restore”](#restore) Restore a file from a previous backup. If multiple backups exist, you’ll be prompted to select one. Use `--yes` to automatically restore the latest backup without prompting. ### Arguments [Section titled “Arguments”](#arguments) | Argument | Required | Description | | ---------- | -------- | --------------------------- | | `filepath` | Yes | Path to the file to restore | ### Options [Section titled “Options”](#options-8) | Option | Description | | ------------------- | ------------------------------------------------------------ | | `--yes` | Skip confirmation, restore latest backup when multiple exist | | `--quiet` | Suppress verbose output | | `--json` | Output machine-readable JSON | | `--format ` | Output format (`terminal` or `json`) | * npm ```sh npx xtarterize@latest restore tsconfig.json ``` * pnpm ```sh pnpm xtarterize@latest restore tsconfig.json ``` * yarn ```sh yarn xtarterize@latest restore tsconfig.json ``` * bun ```sh bunx xtarterize@latest restore tsconfig.json ``` * deno ```sh deno x xtarterize@latest restore tsconfig.json ``` * ni ```sh nlx xtarterize@latest restore tsconfig.json ``` - npm Auto-restore ```sh npx xtarterize@latest restore biome.json --yes ``` - pnpm Auto-restore ```sh pnpm xtarterize@latest restore biome.json --yes ``` - yarn Auto-restore ```sh yarn xtarterize@latest restore biome.json --yes ``` - bun Auto-restore ```sh bunx xtarterize@latest restore biome.json --yes ``` - deno Auto-restore ```sh deno x xtarterize@latest restore biome.json --yes ``` - ni Auto-restore ```sh nlx xtarterize@latest restore biome.json --yes ``` * npm Quiet ```sh npx xtarterize@latest restore tsconfig.json --quiet ``` * pnpm Quiet ```sh pnpm xtarterize@latest restore tsconfig.json --quiet ``` * yarn Quiet ```sh yarn xtarterize@latest restore tsconfig.json --quiet ``` * bun Quiet ```sh bunx xtarterize@latest restore tsconfig.json --quiet ``` * deno Quiet ```sh deno x xtarterize@latest restore tsconfig.json --quiet ``` * ni Quiet ```sh nlx xtarterize@latest restore tsconfig.json --quiet ``` - npm JSON output ```sh npx xtarterize@latest restore tsconfig.json --json ``` - pnpm JSON output ```sh pnpm xtarterize@latest restore tsconfig.json --json ``` - yarn JSON output ```sh yarn xtarterize@latest restore tsconfig.json --json ``` - bun JSON output ```sh bunx xtarterize@latest restore tsconfig.json --json ``` - deno JSON output ```sh deno x xtarterize@latest restore tsconfig.json --json ``` - ni JSON output ```sh nlx xtarterize@latest restore tsconfig.json --json ``` ```bash $ npx xtarterize restore tsconfig.json --json {"ok":true,"filepath":"tsconfig.json","restoredFrom":".xtarterize/backups/tsconfig.json.2026-08-22T12-00-00-000Z","timestamp":"2026-08-22T12-00-00-000Z"} ``` ## `list` [Section titled “list”](#list) List all registered tasks grouped by category, with current status. ### Options [Section titled “Options”](#options-9) | Option | Description | | --------- | ---------------------------- | | `--quiet` | Suppress verbose output | | `--json` | Output machine-readable JSON | * npm ```sh npx xtarterize@latest list ``` * pnpm ```sh pnpm xtarterize@latest list ``` * yarn ```sh yarn xtarterize@latest list ``` * bun ```sh bunx xtarterize@latest list ``` * deno ```sh deno x xtarterize@latest list ``` * ni ```sh nlx xtarterize@latest list ``` ## `query` [Section titled “query”](#query) Search tasks by natural language query. No need to remember exact task IDs - just describe what you’re looking for. ### Options [Section titled “Options”](#options-10) | Option | Description | Default | | ----------------- | --------------------------------- | ------- | | `--limit ` | Maximum number of results to show | `20` | | `--threshold ` | Minimum relevance score (0-1) | `0.1` | | `--json` | Output machine-readable JSON | `false` | * npm ```sh npx xtarterize@latest query "strict typescript" ``` * pnpm ```sh pnpm xtarterize@latest query "strict typescript" ``` * yarn ```sh yarn xtarterize@latest query "strict typescript" ``` * bun ```sh bunx xtarterize@latest query "strict typescript" ``` * deno ```sh deno x xtarterize@latest query "strict typescript" ``` * ni ```sh nlx xtarterize@latest query "strict typescript" ``` - npm JSON output ```sh npx xtarterize@latest query "ci pipeline" --json ``` - pnpm JSON output ```sh pnpm xtarterize@latest query "ci pipeline" --json ``` - yarn JSON output ```sh yarn xtarterize@latest query "ci pipeline" --json ``` - bun JSON output ```sh bunx xtarterize@latest query "ci pipeline" --json ``` - deno JSON output ```sh deno x xtarterize@latest query "ci pipeline" --json ``` - ni JSON output ```sh nlx xtarterize@latest query "ci pipeline" --json ``` * npm Limit results ```sh npx xtarterize@latest query "linting and formatting tool" --limit 5 ``` * pnpm Limit results ```sh pnpm xtarterize@latest query "linting and formatting tool" --limit 5 ``` * yarn Limit results ```sh yarn xtarterize@latest query "linting and formatting tool" --limit 5 ``` * bun Limit results ```sh bunx xtarterize@latest query "linting and formatting tool" --limit 5 ``` * deno Limit results ```sh deno x xtarterize@latest query "linting and formatting tool" --limit 5 ``` * ni Limit results ```sh nlx xtarterize@latest query "linting and formatting tool" --limit 5 ``` Tip For a full reference, see the [query command page](/xtarterize/guide/cli/query/). ## Task Status Values [Section titled “Task Status Values”](#task-status-values) Each task reports one of four statuses: | Status | Meaning | | ---------- | -------------------------------------------------- | | `new` | File/config doesn’t exist yet | | `patch` | File exists but needs additions/updates | | `skip` | Already conformant, nothing to do | | `conflict` | Existing config is incompatible; requires decision | ## Backup System [Section titled “Backup System”](#backup-system) Before any file is modified, xtarterize creates a timestamped backup in `.xtarterize/backups/`. A run manifest (`last-run.json`) is also written so `undo` can restore all files from a run in one step. The `.xtarterize/` directory is automatically added to your project’s `.gitignore`, keeping internal artifacts out of version control. Tip Backups are stored with timestamps in `.xtarterize/backups/` and indexed in `.xtarterize/backups/.index.json`. Use `xtarterize undo` to revert an entire run, or `xtarterize restore ` to revert a single file. [Explore conformance tasks →](/xtarterize/guide/tasks/overview/) # query > Search and discover xtarterize tasks using natural language queries. The `query` command lets you search xtarterize tasks using natural language - no need to remember exact task IDs. It uses a pure algorithmic scoring engine (no AI) to rank tasks by relevance to your query. ## Usage [Section titled “Usage”](#usage) ```bash xtarterize query "" [options] ``` A query is any natural language description of the tooling setup you’re looking for. ### Options [Section titled “Options”](#options) | Option | Description | Default | | ----------------- | --------------------------------- | ----------------- | | `--json` | Output machine-readable JSON | `false` | | `--limit ` | Maximum number of results to show | `20` | | `--threshold ` | Minimum relevance score (0-1) | `0.1` | | `--cwd ` | Target directory | current directory | ### Other options [Section titled “Other options”](#other-options) This command does not support the shared formatting or output flags (`--quiet`, `--format`). Use `--json` for machine-readable output. ## Examples [Section titled “Examples”](#examples) ### Find tasks by description [Section titled “Find tasks by description”](#find-tasks-by-description) * npm ```sh npx xtarterize@latest query "strict typescript" ``` * pnpm ```sh pnpm xtarterize@latest query "strict typescript" ``` * yarn ```sh yarn xtarterize@latest query "strict typescript" ``` * bun ```sh bunx xtarterize@latest query "strict typescript" ``` * deno ```sh deno x xtarterize@latest query "strict typescript" ``` * ni ```sh nlx xtarterize@latest query "strict typescript" ``` Outputs tasks grouped by domain bundle with per-group actionable add commands: ```plaintext ✻ xtarterize query "strict typescript" - 2 groups · 4 tasks TypeScript ts/strict 80% tsconfig - strict: true tsconfig.json ts/paths 52% tsconfig - path aliases tsconfig.json ts/incremental 24% tsconfig - incremental: true tsconfig.json gitignore/tsbuildinfo 14% .gitignore - tsbuildinfo .gitignore xtarterize add ts/strict ts/paths ts/incremental gitignore/tsbuildinfo xtarterize add scripts/package-scripts ``` ### Search for linting and formatting [Section titled “Search for linting and formatting”](#search-for-linting-and-formatting) * npm ```sh npx xtarterize@latest query "linting and formatting tool" --limit 5 ``` * pnpm ```sh pnpm xtarterize@latest query "linting and formatting tool" --limit 5 ``` * yarn ```sh yarn xtarterize@latest query "linting and formatting tool" --limit 5 ``` * bun ```sh bunx xtarterize@latest query "linting and formatting tool" --limit 5 ``` * deno ```sh deno x xtarterize@latest query "linting and formatting tool" --limit 5 ``` * ni ```sh nlx xtarterize@latest query "linting and formatting tool" --limit 5 ``` ### Machine-readable output [Section titled “Machine-readable output”](#machine-readable-output) * npm ```sh npx xtarterize@latest query "ci pipeline" --json ``` * pnpm ```sh pnpm xtarterize@latest query "ci pipeline" --json ``` * yarn ```sh yarn xtarterize@latest query "ci pipeline" --json ``` * bun ```sh bunx xtarterize@latest query "ci pipeline" --json ``` * deno ```sh deno x xtarterize@latest query "ci pipeline" --json ``` * ni ```sh nlx xtarterize@latest query "ci pipeline" --json ``` ```json { "type": "query", "query": "ci pipeline", "count": 3, "results": [ { "taskId": "ci/ci", "label": "GitHub CI workflow", "group": "CI/CD", "relevance": 0.85, "signals": [ { "name": "label", "score": 1.0 }, { "name": "id", "score": 0.85 }, { "name": "keywords", "score": 0.9 }, { "name": "config", "score": 1.0 }, { "name": "group", "score": 1.0 } ] } ] } ``` ### Compose an init plan [Section titled “Compose an init plan”](#compose-an-init-plan) Combine query with the init workflow to get a ranked task plan: * npm ```sh npx xtarterize@latest init --compose "react project with ci and linting" ``` * pnpm ```sh pnpm xtarterize@latest init --compose "react project with ci and linting" ``` * yarn ```sh yarn xtarterize@latest init --compose "react project with ci and linting" ``` * bun ```sh bunx xtarterize@latest init --compose "react project with ci and linting" ``` * deno ```sh deno x xtarterize@latest init --compose "react project with ci and linting" ``` * ni ```sh nlx xtarterize@latest init --compose "react project with ci and linting" ``` This reorders tasks so the most relevant ones appear first in the interactive plan, without excluding any applicable tasks. ## How It Works [Section titled “How It Works”](#how-it-works) The scoring engine operates in five steps: 1. **Tokenize** - The query is split into words; stopwords (a, the, want, need, project, etc.) and short words are filtered out 2. **Expand** - Content words are expanded through a domain-specific synonym map with bidirectional transitive reverse-lookup (e.g. “lint” → “linter”, “static-analysis”, “check”; “typescript” → “ts”, “type-safe”, “strict”) 3. **Score** - For each original token, find the best match across all 5 signals (label, id, group, keywords, config targets) using the highest signal score among all terms (original + expanded synonyms). Uses tiered match levels: exact (1.0), stem-match (0.95), fuzzy (0.85), prefix (0.75), substring (0.55) 4. **Aggregate** - Signal scores are weighted and averaged; multi-token queries receive a coverage bonus that increases with the proportion of tokens matched 5. **Group** - Results are organized by task group/domain bundle, with per-group actionable `xtarterize add` commands Note The scoring engine is entirely algorithmic - zero AI model calls, zero API dependencies. It runs offline and completes in milliseconds. ## See Also [Section titled “See Also”](#see-also) * [CLI Overview](/xtarterize/guide/cli/overview/) - full command reference * [Tasks Overview](/xtarterize/guide/tasks/overview/) - understanding tasks and their metadata # Configuration > How xtarterize detects and adapts to your project. xtarterize doesn’t require a config file. It detects your project’s stack automatically and applies only what’s appropriate. ## Detection [Section titled “Detection”](#detection) When you run `init`, xtarterize scans your project to build a `ProjectProfile`: * **Framework** - [React](https://react.dev/), [Vue](https://vuejs.org/), [Svelte](https://svelte.dev/), [Solid](https://www.solidjs.com/), [React Native](https://reactnative.dev/), or [Node](https://nodejs.org/) (from `package.json` deps) * **Bundler** - [Vite](https://vitejs.dev/), [Next.js](https://nextjs.org/), [TanStack Start](https://tanstack.com/start/latest), [Expo](https://expo.dev/), [Webpack](https://webpack.js.org/), [Rspack](https://rspack.dev/), or none * **Router** - [TanStack Router](https://tanstack.com/router/latest), [React Router](https://reactrouter.com/), [Vue Router](https://router.vuejs.org/), [Expo Router](https://docs.expo.dev/router/introduction/), or none * **Styling** - [Tailwind CSS](https://tailwindcss.com/), [CSS Modules](https://github.com/css-modules/css-modules), [Styled Components](https://styled-components.com/), [Vanilla Extract](https://vanilla-extract.style/), [NativeWind](https://www.nativewind.dev/), or Vanilla * **Package Manager** - [pnpm](https://pnpm.io/), [npm](https://www.npmjs.com/), [yarn](https://yarnpkg.com/), or [bun](https://bun.sh/) (from lockfiles or `packageManager` field) * **Monorepo** - Detected via [`pnpm-workspace.yaml`](https://pnpm.io/pnpm-workspace_yaml), [`turbo.json`](https://turbo.build/repo/docs/reference/configuration), [`nx.json`](https://nx.dev/reference/nx-json), [`lerna.json`](https://lerna.js.org/docs/configuration), or at least two of the `packages/`, `apps/`, `services/` directories * **GitHub** - [`.github/`](https://docs.github.com/en/actions/using-workflows/about-workflows) directory presence * **Existing Configs** - Checks for [`biome.json`](https://biomejs.dev/reference/configuration/), [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/), [`renovate.json`](https://docs.renovatebot.com/configuration-options/), [`vite.config.*`](https://vitejs.dev/config/), [`.versionrc`](https://github.com/absolute-version/commit-and-tag-version#configuration), [`.gitignore`](https://git-scm.com/docs/gitignore), etc. ## Detection Flow [Section titled “Detection Flow”](#detection-flow) ``` flowchart TD A[read package.json] --> B[detectFramework] A --> C[detectBundler] A --> D[detectStyling] A --> E[detectVitePlus] B --> F[detectRouter] C --> F B --> G[detectRuntime] C --> G A --> H[detectPackageManager] A --> I[detectMonorepo] A --> J[detectGitHubWorkflows] A --> K[detectExistingConfigs] G --> L[ProjectProfile] F --> L D --> L E --> L H --> L I --> L J --> L K --> L style A fill:#6366f1,color:#fff style L fill:#22c55e,color:#fff ``` ## Detection Sources [Section titled “Detection Sources”](#detection-sources) * package.json Framework, bundler, router, styling, and TypeScript are all detected from [`dependencies`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#dependencies) and [`devDependencies`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#devdependencies). * Lock files Package manager is detected from lock file presence: [`pnpm-lock.yaml`](https://pnpm.io/), [`yarn.lock`](https://yarnpkg.com/features/zero-installs), [`package-lock.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json), [`bun.lock`](https://bun.sh/docs/install/lockfile), or `bun.lockb`. * File system Monorepo status, GitHub, and existing configs are detected by checking for specific files and directories. ## Ambiguity Resolution [Section titled “Ambiguity Resolution”](#ambiguity-resolution) Note If both `react` and `react-native` are detected, xtarterize prompts you to clarify which describes the project. In CI mode (`--quiet`), it defaults to `react`. ## Task Gating [Section titled “Task Gating”](#task-gating) Tasks are gated on the detected profile: * Vite plugin tasks only run when `bundler === 'vite'` * Monorepo tasks only run when `monorepo === true` * CI tasks only run when `hasGitHub === true` * TypeScript tasks only run when `typescript === true` ### Monorepo scope filtering [Section titled “Monorepo scope filtering”](#monorepo-scope-filtering) When running inside a monorepo, xtarterize further filters tasks based on their **scope**. Each task declares one of three scopes: * **`root`** - The task applies only at the monorepo root. * **`package`** - The task applies only inside a workspace package. * **`both`** (default) - The task applies everywhere. At the monorepo root (`workspaceRoot: true`), package-scoped tasks are hidden. Inside a workspace package (`workspaceRoot: false`), root-scoped tasks are hidden. Tasks without an explicit scope (or with `scope: 'both'`) are visible in both positions. In non-monorepo projects, scope filtering is disabled - all tasks that pass the `applicable()` check are shown regardless of their declared scope. ## Parameterized Templates [Section titled “Parameterized Templates”](#parameterized-templates) All templates adapt to the detected profile: * GitHub workflows use the detected package manager for install commands * Knip entry points are inferred from the bundler/framework * Plop generators vary by framework (React gets component+hook, Vue gets component+composable, etc.) * VS Code extensions include framework-specific recommendations * AGENTS.md includes framework-specific instructions ## Backup System [Section titled “Backup System”](#backup-system) Before any file is modified, xtarterize creates a timestamped backup in `.xtarterize/backups/`. An index file tracks all backups for easy restoration. * .xtarterize/ * backups/ * .index.json * tsconfig.json.2024-01-15T10-30-00-000Z * biome.json.2024-01-15T10-30-00-000Z The `.xtarterize/` directory is automatically added to your project’s `.gitignore` when you run any `xtarterize` command. You won’t see these internal artifacts in `git status`. Restore with: * npm ```sh npx xtarterize@latest restore tsconfig.json ``` * pnpm ```sh pnpm xtarterize@latest restore tsconfig.json ``` * yarn ```sh yarn xtarterize@latest restore tsconfig.json ``` * bun ```sh bunx xtarterize@latest restore tsconfig.json ``` * deno ```sh deno x xtarterize@latest restore tsconfig.json ``` * ni ```sh nlx xtarterize@latest restore tsconfig.json ``` ## Task selection [Section titled “Task selection”](#task-selection) `.xtarterizerc` accepts `skip` and `only` arrays alongside `plugins` so repeat runs apply the same filter without CLI flags. The same fields work in the `"xtarterize"` key of `package.json`. ```json { "plugins": ["@acme/xtarterize-tasks"], "skip": ["agent/skills-install"], "only": ["ts/strict", "lint/biome"] } ``` Precedence rules: * CLI `--only` overrides the config `only` list when provided * CLI `--skip` extends the config `skip` list * A task in both `skip` and `only` is excluded - skip wins * An empty or absent `only` list means no restriction, not “apply nothing” For command behavior, see the [CLI reference](/xtarterize/guide/cli/overview/). For generated files, see the [task catalog](/xtarterize/guide/tasks/overview/). # Monorepo support > How xtarterize handles monorepo projects xtarterize has built-in support for monorepos. When you run commands inside a monorepo, tasks are automatically filtered based on their scope - root-level tasks vs package-level tasks - so you always see what’s relevant to your current position. ## Monorepo detection [Section titled “Monorepo detection”](#monorepo-detection) xtarterize detects monorepos by checking for these markers at or above the current directory: * `pnpm-workspace.yaml` * `turbo.json` * `nx.json` * `lerna.json` * At least two of the `packages/`, `apps/`, or `services/` directories If no marker is found at the current directory, xtarterize walks up the directory tree looking for one. If it finds a marker inside a `packages/`, `apps/`, or `services/` directory, it knows you’re inside a workspace package. ## Task scopes [Section titled “Task scopes”](#task-scopes) Every task in xtarterize has a **scope** that determines where it applies: | Scope | Applies at | Examples | | --------- | ------------------------------- | -------------------------------------------------------------------- | | `root` | Monorepo root only | CI/CD workflows, release tooling, turbo.json, editor settings, npmrc | | `package` | Inside a workspace package only | Vite plugin config, tsconfig path aliases | | `both` | Everywhere | Biome config, TypeScript strict mode, Knip, Plop | ## Running at the monorepo root [Section titled “Running at the monorepo root”](#running-at-the-monorepo-root) When you run `xtarterize init` at the monorepo root (the directory containing `pnpm-workspace.yaml`, `turbo.json`, or similar), you’ll see: * CI/CD workflows (CI, release, auto-update) * Release tooling (commitlint, czg, commit-and-tag-version, git hooks) * Monorepo configuration (turbo.json) * Dependency management (Renovate config) * Editor configuration (.vscode/settings.json, extensions.json) * Root-level scripts (package.json scripts, .npmrc) * Cross-cutting tooling (Biome, TypeScript strict mode, Knip, Plop) Package-level tasks like Vite plugin configuration and tsconfig path aliases are hidden - those belong inside individual workspace packages. ## Running inside a workspace package [Section titled “Running inside a workspace package”](#running-inside-a-workspace-package) When you run `xtarterize init` inside a workspace package (a directory under `packages/`, `apps/`, or `services/`), you’ll see: * Vite plugin configuration (vite-plugin-checker, rollup-plugin-visualizer) * TypeScript path aliases * Cross-cutting tooling (Biome, TypeScript strict mode, Knip, Plop) Root-level tasks like CI/CD workflows, release tooling, and turbo configuration are hidden - those are configured once at the root. ## Non-monorepo projects [Section titled “Non-monorepo projects”](#non-monorepo-projects) In single-package projects (not detected as a monorepo), the scope system is disabled. All tasks that pass the `applicable()` check are offered regardless of their declared scope. ## Task reference [Section titled “Task reference”](#task-reference) ### Root-scoped tasks [Section titled “Root-scoped tasks”](#root-scoped-tasks) | Task | ID | Group | | ---------------------------- | -------------------------- | ------------ | | GitHub CI workflow | `ci/ci` | CI/CD | | GitHub release workflow | `ci/release` | CI/CD | | GitHub auto-update workflow | `ci/auto-update` | CI/CD | | Renovate config | `deps/renovate` | Dependencies | | VSCode settings + extensions | `editor/vscode` | Editor | | devEngines in package.json | `quality/package-engines` | Quality | | Turbo | `monorepo/turbo` | Monorepo | | Commitlint config | `release/commitlint` | Release | | czg (commitizen) | `release/czg` | Release | | commit-and-tag-version | `release/cat-version` | Release | | Git hooks | `release/git-hooks` | Release | | package.json scripts | `scripts/package-scripts` | Scripts | | .npmrc | `scripts/npmrc` | Scripts | | .gitignore - tsbuildinfo | `gitignore/tsbuildinfo` | TypeScript | | pnpm workspace config | `workspace/pnpm-workspace` | Workspace | ### Package-scoped tasks [Section titled “Package-scoped tasks”](#package-scoped-tasks) | Task | ID | Group | | ------------------------ | ----------------- | ------------ | | vite-plugin-checker | `vite/checker` | Vite Plugins | | rollup-plugin-visualizer | `vite/visualizer` | Vite Plugins | | tsconfig - path aliases | `ts/paths` | TypeScript | ### Cross-cutting tasks (both) [Section titled “Cross-cutting tasks (both)”](#cross-cutting-tasks-both) These tasks appear everywhere - at the monorepo root and inside workspace packages: Biome, Oxlint config, Oxfmt config, TypeScript strict mode, TypeScript incremental builds, Knip, lint-staged, Plop, AGENTS.md, agent skills install # editor/vscode > Configure .vscode/settings.json and .vscode/extensions.json for consistent editor behavior. Writes or merges VS Code workspace settings and extension recommendations. ## Settings (.vscode/settings.json) [Section titled “Settings (.vscode/settings.json)”](#settings-vscodesettingsjson) Applies a set of opinionated defaults: * **Formatter**: Biome as default formatter for TS, JS, JSON, JSONC * **Format on save**: Enabled * **Format on paste**: Disabled (avoids unwanted formatting during paste) * **Code actions on save**: Biome fix and organize imports (explicit) * **Import module specifier**: Non-relative (`@/` paths) * **Update imports on file move**: Always (TS and JS) Conditional settings based on detected tools: | Detected | Settings Added | | ------------------- | --------------------------------------------------------------------------------------------------- | | **Monorepo** | `typescript.tsdk` set to workspace TypeScript; `search.exclude` for node\_modules, .turbo, dist | | **Vite** | `files.associations` maps `.css` to Tailwind CSS language mode | | **Vue** | `vue.server.hybridMode: true`; Vue formatter | | **React Native** | `typescript.tsserver.watchOptions` for fs events | | **Next.js** | `typescript.tsdk`; Emmet JSX include languages | | **TanStack Router** | `files.exclude` hides `routeTree.gen.ts` from file explorer | | **Tailwind CSS** | CVA/CN class regex patterns for IntelliSense | | **TypeScript** | `typescript.disableAutomaticTypeAcquisition: true`; `typescript.enablePromptUseWorkspaceTsdk: true` | ## Extensions (.vscode/extensions.json) [Section titled “Extensions (.vscode/extensions.json)”](#extensions-vscodeextensionsjson) Recommends `biomejs.biome` and `ms-vscode.vscode-typescript-next`, plus framework-specific extensions when detected (Tailwind CSS, Vue, React Native). Tip Extension recommendations are **merged** with any existing `recommendations` array in your file. Your custom extensions are never removed. ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | -------------------------------------------------- | | **Task ID** | `editor/vscode` | | **Group** | Editor | | **Scope** | Root (monorepo root only) | | **Applicable When** | Always | | **Config Targets** | `.vscode/settings.json`, `.vscode/extensions.json` | # Conformance Tasks > All available conformance tasks and what they do. xtarterize applies conformance configuration through discrete, independently applicable tasks. Each task detects whether it’s needed and only applies changes if necessary. In monorepos, tasks are further filtered by their **scope**. Root-scoped tasks (CI/CD, release tooling, editor config, etc.) only appear when running from the monorepo root. Package-scoped tasks (Vite plugins, tsconfig paths) only appear inside workspace packages. See the [Monorepo guide](/xtarterize/guide/monorepo) for details. ## Linting & Formatting [Section titled “Linting & Formatting”](#linting--formatting) | Task ID | Description | Applicable When | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | `lint/biome` | Install [Biome](https://biomejs.dev/) + [Ultracite](https://ultracite.ai/), write `biome.json` extending Ultracite presets with framework-aware overrides | Non-Vite+ projects (no ESLint/Oxlint detected) | | `lint/oxlint` | Install [Oxlint](https://oxc.rs/) + Ultracite, write `oxlint.config.ts` or `.oxlintrc.json` (legacy) extending Ultracite presets | [Vite+](https://viteplus.dev/) projects (no ESLint/Biome detected) | | `lint/oxfmt` | Install [Oxfmt](https://oxc.rs/) + Ultracite, write `oxfmt.config.ts` or `.oxfmtrc.json` (legacy) extending Ultracite preset | Vite+ projects (no ESLint/Biome detected) | All three tasks install [Ultracite](https://ultracite.ai/) automatically alongside the tool-specific dependency and generate configs that extend/import Ultracite presets. No separate `ultracite init` step needed. ### Framework-Aware Biome Config [Section titled “Framework-Aware Biome Config”](#framework-aware-biome-config) When [Tailwind CSS](https://tailwindcss.com/) is detected, the generated [`biome.json`](https://biomejs.dev/reference/configuration/) includes: ```json { "css": { "parser": { "tailwindDirectives": true } } } ``` This enables Biome to parse [Tailwind v4 directives](https://tailwindcss.com/docs/functions-and-directives) like [`@theme`](https://tailwindcss.com/docs/functions-and-directives#theme-directive) without errors. See [`css.parser.tailwindDirectives`](https://biomejs.dev/reference/configuration/#cssparsertailwinddirectives) in Biome’s configuration reference. ## TypeScript [Section titled “TypeScript”](#typescript) | Task ID | Description | Applicable When | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | | `ts/strict` | Patch [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) with 4 compiler options: [`strict: true`](https://www.typescriptlang.org/tsconfig/#strict), [`noUnusedLocals: true`](https://www.typescriptlang.org/tsconfig/#noUnusedLocals), [`noUnusedParameters: true`](https://www.typescriptlang.org/tsconfig/#noUnusedParameters), [`verbatimModuleSyntax: true`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) (each checked independently) | TypeScript detected | | `ts/paths` | Patch `tsconfig.json` with [`baseUrl`](https://www.typescriptlang.org/tsconfig/#baseUrl) and [`paths`](https://www.typescriptlang.org/tsconfig/#paths) aliases (`@/*` → [`./src/*`](https://www.typescriptlang.org/tsconfig/#paths)) | TypeScript detected | | `ts/incremental` | Patch `tsconfig.json` with [`incremental: true`](https://www.typescriptlang.org/tsconfig/#incremental) and [`tsBuildInfoFile: ".tsbuildinfo"`](https://www.typescriptlang.org/tsconfig/#tsBuildInfoFile) | TypeScript detected | | `gitignore/tsbuildinfo` | Add `*.tsbuildinfo` and `.tsbuildinfo/` to [`.gitignore`](https://git-scm.com/docs/gitignore) | TypeScript detected | ## Vite Plugins [Section titled “Vite Plugins”](#vite-plugins) | Task ID | Description | Applicable When | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | `vite/checker` | Inject [`vite-plugin-checker`](https://vite-plugin-checker.netlify.app/) ([`checker()`](https://vite-plugin-checker.netlify.app/checkers/typescript.html)) into [`vite.config.ts`](https://vitejs.dev/config/) via [AST](https://github.com/unjs/magicast) | Browser [Vite](https://vitejs.dev/) project | | `vite/visualizer` | Inject [`rollup-plugin-visualizer`](https://github.com/btd/rollup-plugin-visualizer) ([`visualizer()`](https://github.com/btd/rollup-plugin-visualizer#usage)) into `vite.config.ts` via AST | Browser Vite project | ## CI/CD [Section titled “CI/CD”](#cicd) | Task ID | Description | Applicable When | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | | `ci/release` | Write [`.github/workflows/release.yml`](https://docs.github.com/en/actions/using-workflows/about-workflows) - triggers on [`push.tags`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#running-your-workflow-when-a-push-of-a-specific-tag-occurs) | [GitHub](https://github.com/) detected | | `ci/auto-update` | Write [`.github/workflows/auto-update.yml`](https://docs.github.com/en/actions/using-workflows/about-workflows) - [`schedule.cron`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule) for weekly dependency updates | GitHub detected | | `ci/ci` | Write [`.github/workflows/ci.yml`](https://docs.github.com/en/actions/using-workflows/about-workflows) - lint, typecheck, test on [`pull_request`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request) | GitHub detected | ### Conditional pnpm Setup [Section titled “Conditional pnpm Setup”](#conditional-pnpm-setup) For projects using [**pnpm**](https://pnpm.io/), CI workflows automatically include [`pnpm/setup@v1`](https://github.com/pnpm/setup) with [`cache: true`](https://github.com/pnpm/setup#usage) before [`actions/setup-node@v6`](https://github.com/actions/setup-node). This ensures reproducible pnpm versions across runs. [npm](https://www.npmjs.com/) and [yarn](https://yarnpkg.com/) projects are unaffected. ### Monorepo Workspace Config [Section titled “Monorepo Workspace Config”](#monorepo-workspace-config) When running in a pnpm monorepo, the `workspace/pnpm-workspace` task ensures a `pnpm-workspace.yaml` file declares both workspace globs: ```yaml packages: - 'apps/*' - 'packages/*' ``` Existing files with a `packages:` list keep their comments, catalogs, overrides, and other settings; only missing globs are inserted, and files without the key are left untouched. Layouts that cannot be edited safely are reported as conflicts instead of being rewritten. The task only applies when the detected package manager is pnpm. ## Dependencies [Section titled “Dependencies”](#dependencies) | Task ID | Description | Applicable When | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | | `deps/renovate` | Write [`renovate.json`](https://docs.renovatebot.com/configuration-options/) with [`extends: ["config:base"]`](https://docs.renovatebot.com/presets-config/#configbase), [`automerge`](https://docs.renovatebot.com/key-concepts/automerge/), and [`stabilityDays: 2`](https://docs.renovatebot.com/configuration-options/#stabilitydays) | [GitHub](https://github.com/) detected | ## Release [Section titled “Release”](#release) | Task ID | Description | Applicable When | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | | `release/commitlint` | Install [commitlint](https://commitlint.js.org/) with [`@commitlint/config-conventional`](https://commitlint.js.org/reference/rules.html), write [`commitlint.config.ts`](https://commitlint.js.org/reference/configuration.html) | [Git](https://git-scm.com/) detected | | `release/czg` | Install [czg](https://cz-git.qbb.sh/cli/) ([Commitizen](https://commitizen.github.io/cz-cli/) adapter), add [`commit`](https://docs.npmjs.com/cli/v10/using-npm/scripts) script to `package.json` | Always | | `release/cat-version` | Install [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version), write [`.versionrc`](https://github.com/absolute-version/commit-and-tag-version#configuration) | Always | | `release/git-hooks` | Install [husky](https://typicode.github.io/husky/), wire 4 hooks: `commit-msg` (commitlint), `prepare-commit-msg` (czg/commitizen integration), `pre-commit` (lint-staged / biome), `pre-push` (typecheck + test / turbo) | Always | | `release/versionrc` | Write [`.versionrc.json`](https://github.com/absolute-version/commit-and-tag-version#configuration) mapping conventional commit types to changelog sections (feat/fix/refactor/perf visible, others hidden) | Always | ## Code Quality [Section titled “Code Quality”](#code-quality) | Task ID | Description | Applicable When | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | | `quality/knip` | Install [Knip](https://knip.dev/), write [`knip.json`](https://knip.dev/reference/configuration) with framework-aware [`entry`](https://knip.dev/reference/configuration#entry) and [`project`](https://knip.dev/reference/configuration#project) paths | Always (JSON format if no TypeScript) | | `quality/lint-staged` | Install [lint-staged](https://github.com/okonet/lint-staged), write [`.lintstagedrc.json`](https://github.com/okonet/lint-staged#configuration) running Biome on staged files | Non-Vite+ projects | | `quality/package-engines` | Add [`devEngines`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#devengines) to `package.json` with a Node floor derived from the detected Node version and detected package manager version constraint | Always | ## Code Generation [Section titled “Code Generation”](#code-generation) | Task ID | Description | Applicable When | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | | `codegen/plop` | Install [Plop](https://plopjs.com/), write [`plopfile.ts`](https://plopjs.com/documentation/#getting-started) with framework-specific [generators](https://plopjs.com/documentation/#setgenerator) | Framework detected | ## Monorepo [Section titled “Monorepo”](#monorepo) | Task ID | Description | Applicable When | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | | `monorepo/turbo` | Install [Turborepo](https://turbo.build/), write [`turbo.json`](https://turbo.build/repo/docs/reference/configuration) with [`pipeline`](https://turbo.build/repo/docs/reference/configuration#pipeline) for build/lint/test | Monorepo detected | | `workspace/pnpm-workspace` | Ensure [`pnpm-workspace.yaml`](https://pnpm.io/pnpm-workspace_yaml) declares the `apps/*` and `packages/*` globs, preserving existing settings | `packageManager` is `pnpm` | ## Editor [Section titled “Editor”](#editor) | Task ID | Description | Applicable When | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | | `editor/vscode` | Write/merge [`.vscode/settings.json`](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) (Biome formatter, save/on-paste actions, per-framework config) and [`.vscode/extensions.json`](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions) | Always | ### Git Hooks [Section titled “Git Hooks”](#git-hooks) The `release/git-hooks` task installs [husky](https://typicode.github.io/husky/) and generates 4 hooks: | Hook | Action | | ---------------------- | -------------------------------------------------------------------------------- | | **commit-msg** | Runs `commitlint --edit` on the commit message | | **prepare-commit-msg** | Runs `cz --hook` when `czg` or `commitizen` is detected; no-op otherwise | | **pre-commit** | Runs `lint-staged` (or `biome check --write`, or `vp staged` for Vite+ projects) | | **pre-push** | Runs `typecheck` + `test` (or `check:turbo` for Turborepo monorepos) | In Vite+ projects, hooks are written to `.vite-hooks/` instead of `.husky/`. ### Changelog Configuration [Section titled “Changelog Configuration”](#changelog-configuration) The `release/versionrc` task generates `.versionrc.json` for [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) with: * **Visible**: `feat` (Features), `fix` (Bug Fixes), `refactor` (Code Refactoring), `perf` (Performance Improvements) * **Hidden**: `docs`, `style`, `test`, `chore`, `ci`, `build`, `revert` This is separate from the `release/cat-version` task, which generates a legacy `.versionrc` file and installs the `commit-and-tag-version` dependency. The `versionrc` task can be used standalone or in combination with `cat-version`. ### Additive Extension Merging [Section titled “Additive Extension Merging”](#additive-extension-merging) When `.vscode/extensions.json` already exists, xtarterize **adds** its recommended extensions to your existing [`recommendations`](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions) array rather than replacing them. Your custom extensions are always preserved. ### devEngines [Section titled “devEngines”](#devengines) The `quality/package-engines` task adds a `devEngines` field to `package.json`: | Field | Value | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `runtime.name` | `node` | | `runtime.version` | `>=` + the project’s detected Node version (from `.nvmrc`, `engines.node`, or the CLI default), matching the version installed by generated CI workflows | | `packageManager.name` | Detected package manager | | `packageManager.version` | `>=9` (pnpm) or `>=10` (npm, yarn, bun) | ## Agent [Section titled “Agent”](#agent) | Task ID | Description | Applicable When | | ---------------------- | --------------------------------------------------------------------------------------------- | ------------------- | | `agent/agents-md` | Write [`AGENTS.md`](https://docs.opencode.ai/agents) with project description and commands | Always | | `agent/skills-install` | Install relevant [agent skills](https://skills.sh) via `npx skills@latest add` for your stack | TypeScript detected | ### Skills Install [Section titled “Skills Install”](#skills-install) The `agent/skills-install` task installs [agent skills](https://skills.sh) from the catalog in [`packages/tasks/src/agent/catalog.ts`](https://github.com/agustinusnathaniel/xtarterize/blob/main/packages/tasks/src/agent/catalog.ts). It combines general skills with entries selected from the detected runtime, framework, bundler, and dependencies. Before installing, it checks local skill directories (`.agents/skills`, `.claude/skills`, and `.cursor/skills`) so existing skills are not installed again. The catalog is the source of truth. Its current groups include: | Signal | Examples | | ------------------------ | ------------------------------------------------------------------------------------------------------- | | Every TypeScript project | `opensrc`, `grill-me`, `handoff`, `improve` | | Browser or edge runtime | `frontend-design`, `web-design-guidelines`, `fixing-accessibility` | | React or Next.js | `vercel-react-best-practices`, `react-dev`, `react-useeffect` | | Next.js | `next-dev-loop`, `next-cache-components-optimizer`, `next-cache-components-adoption` | | Vue or Nuxt | `vue`, `vue-best-practices`, `nuxt` | | Expo or React Native | `expo-overview`, `expo-router`, `eas-workflows`, `eas-app-stores`, `eas-update` | | Detected dependencies | Skills for component libraries, Vite, Vitest, tsdown, Turborepo, databases, auth, AI SDKs, and Remotion | ## Scripts [Section titled “Scripts”](#scripts) | Task ID | Description | Applicable When | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | | `scripts/package-scripts` | Patch [`package.json`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json) [`scripts`](https://docs.npmjs.com/cli/v10/using-npm/scripts) with `lint`, `format`, `typecheck`, etc. | Always | | `scripts/npmrc` | Write [`.npmrc`](https://docs.npmjs.com/cli/v10/configuring-npm/npmrc) with `save-exact`, `strict-peer-dependencies`, and `auto-install-peers` | Always | ## Idempotency [Section titled “Idempotency”](#idempotency) Tip Every task is idempotent. Running `init` twice produces no changes on the second run. Each task implements `check()`, `dryRun()`, and `apply()`: * **`check()`** - Returns `new`, `patch`, `skip`, or `conflict` based on current state * **`dryRun()`** - Returns exact diffs without writing anything * **`apply()`** - Writes changes, backing up files first ### Smart Equivalence Detection [Section titled “Smart Equivalence Detection”](#smart-equivalence-detection) xtarterize doesn’t just check key names - it also detects when an equivalent value already exists under a different key. This prevents redundant entries: | Scenario | Existing | xtarterize Action | | --------------------- | ------------------------------ | --------------------------------------------------------- | | Script name alias | `"type:check": "tsc --noEmit"` | Skips adding `"typecheck": "tsc --noEmit"` | | Config extends format | `"extends": "config:base"` | Treats same as `"extends": ["config:base"]` | | VS Code extensions | `["biomejs.biome"]` | Adds `"ms-vscode.vscode-typescript-next"`, keeps existing | If the exact same command, value, or configuration already exists somewhere, xtarterize skips adding a duplicate. ## Task gating [Section titled “Task gating”](#task-gating) Each task table above states its applicability. For detection and monorepo scope rules, see the [configuration guide](/xtarterize/guide/config/overview/). ## References [Section titled “References”](#references) See the external links in each task row and the [configuration guide](/xtarterize/guide/config/overview/) for detection and scope behavior. [Learn how to contribute a new task →](/xtarterize/contributing/tasks/overview/) # quality/package-engines > Add devEngines to package.json specifying Node and package manager requirements. Adds a `devEngines` field to `package.json` declaring the expected Node.js and package manager versions for the project. The task generates: ```json { "devEngines": { "runtime": { "name": "node", "version": ">=24" }, "packageManager": { "name": "pnpm", "version": ">=9" } } } ``` The `packageManager.version` is set based on the detected package manager: `>=9` for pnpm, `>=10` for npm, yarn, or bun. ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | ------------------------- | | **Task ID** | `quality/package-engines` | | **Group** | Quality | | **Scope** | Root (monorepo root only) | | **Applicable When** | Always | | **Config Target** | `package.json` | Tip This task writes `package.json` through the package.json owner and merges into an existing `devEngines` field rather than replacing it. Existing values take precedence over incoming values. # workspace/pnpm-workspace > Generate pnpm-workspace.yaml for pnpm monorepos. Generates a `pnpm-workspace.yaml` file for projects using pnpm as their package manager. The file defines the workspace globs that pnpm uses to discover packages. ```yaml packages: - 'apps/*' - 'packages/*' ``` ## Existing files [Section titled “Existing files”](#existing-files) The task creates `pnpm-workspace.yaml` when it is missing. When the file already exists: * With a top-level `packages:` list, only the missing `apps/*` and `packages/*` entries are inserted. Comments, other keys such as `catalog:`, `overrides:`, and `onlyBuiltDependencies`, key order, indentation, quote style, and line endings stay untouched. * Without a `packages:` key, the file is left untouched, so a settings-only `pnpm-workspace.yaml` never gains workspace globs. Layouts that cannot be edited safely, such as a flow-style `packages:` list that is missing a glob, are reported as a conflict instead of being rewritten. ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | -------------------------- | | **Task ID** | `workspace/pnpm-workspace` | | **Group** | Monorepo | | **Scope** | Root (monorepo root only) | | **Applicable When** | `packageManager` is `pnpm` | | **Config Target** | `pnpm-workspace.yaml` | Tip This task only applies when `pnpm` is the detected package manager. Non-pnpm projects do not need a `pnpm-workspace.yaml`. # release/git-hooks > Install and configure Git hooks for commit quality and pre-push validation. Installs [husky](https://typicode.github.io/husky/) and wires four Git hooks to enforce commit conventions and run quality gates before pushing. ## Hooks [Section titled “Hooks”](#hooks) | Hook | Action | Details | | ---------------------- | ------------------------- | ---------------------------------------------------------------------- | | **commit-msg** | commitlint check | Runs `commitlint --edit` on the commit message | | **prepare-commit-msg** | Commit wizard integration | Runs `cz --hook` if `czg` or `commitizen` is detected; no-op otherwise | | **pre-commit** | Staged file check | Runs `lint-staged` if installed, or `biome check --write` otherwise | | **pre-push** | Typecheck + tests | Runs `typecheck` + `test` (or `check:turbo` for Turborepo projects) | ### pre-commit behavior [Section titled “pre-commit behavior”](#pre-commit-behavior) In [Vite+](https://viteplus.dev/) projects, the pre-commit hook uses `vp staged` instead of lint-staged or Biome. This delegates to Vite+’s own staging pipeline. ### pre-push behavior [Section titled “pre-push behavior”](#pre-push-behavior) The pre-push hook adapts to the project setup: | Project Type | Command | | ---------------------- | ---------------------------------- | | Turborepo monorepo | `pnpm check:turbo` (or equivalent) | | TypeScript (non-Turbo) | `pnpm typecheck && pnpm test` | | Other | `pnpm test` | ## File Paths [Section titled “File Paths”](#file-paths) Hooks are written to `.husky/` by default. In Vite+ projects, they are written to `.vite-hooks/` instead. ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | ---------------------------------------------------------------------------------------- | | **Task ID** | `release/git-hooks` | | **Group** | Release | | **Scope** | Root (monorepo root only) | | **Applicable When** | Always | | **Config Targets** | `.husky/commit-msg`, `.husky/prepare-commit-msg`, `.husky/pre-commit`, `.husky/pre-push` | | **Dependency** | `husky` (dev) - skipped in Vite+ projects | Tip The `prepare-commit-msg` hook is a no-op when no commit wizard (`czg` or `commitizen`) is installed, so it won’t interfere with your existing workflow. # ts/strict > Enable strict TypeScript compiler options for type safety. Patches `tsconfig.json` with four compiler options for maximum type safety: ```json { "compilerOptions": { "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "verbatimModuleSyntax": true } } ``` | Option | Purpose | | ---------------------------- | ------------------------------------------- | | `strict: true` | Enables all strict type-checking options | | `noUnusedLocals: true` | Error on unused local variables | | `noUnusedParameters: true` | Error on unused function parameters | | `verbatimModuleSyntax: true` | Enforce `import type` for type-only imports | ## Conflict Detection [Section titled “Conflict Detection”](#conflict-detection) Each option is checked independently. If any option already exists with a different value (e.g. `strict: false`), the task returns `conflict` rather than overwriting it. This prevents accidental loosening of intentional configurations. Tip Use `--skip ts/strict` when initializing to skip this task. The other TypeScript tasks remain available unless you also skip them. ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | ------------------- | | **Task ID** | `ts/strict` | | **Group** | TypeScript | | **Applicable When** | TypeScript detected | | **Config Target** | `tsconfig.json` | # release/versionrc > Generate .versionrc.json for commit-and-tag-version / standard-version changelog customization. Generates a `.versionrc.json` configuration file for [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) (and standard-version-compatible tools) that maps conventional commit types to changelog sections. ```json { "bumpFiles": ["package.json"], "types": [ { "type": "feat", "section": "Features" }, { "type": "fix", "section": "Bug Fixes" }, { "type": "refactor", "section": "Code Refactoring" }, { "type": "perf", "section": "Performance Improvements" }, { "type": "docs", "section": "Documentation", "hidden": true }, { "type": "style", "section": "Styles", "hidden": true }, { "type": "test", "section": "Tests", "hidden": true }, { "type": "chore", "section": "Chores", "hidden": true }, { "type": "ci", "section": "CI/CD", "hidden": true }, { "type": "build", "section": "Build System", "hidden": true }, { "type": "revert", "section": "Reverts", "hidden": true } ] } ``` **Visible sections** (appear in changelog): `feat`, `fix`, `refactor`, `perf` **Hidden sections** (excluded from changelog): `docs`, `style`, `test`, `chore`, `ci`, `build`, `revert` ## Details [Section titled “Details”](#details) | Property | Value | | ------------------- | ------------------------- | | **Task ID** | `release/versionrc` | | **Group** | Release | | **Scope** | Root (monorepo root only) | | **Applicable When** | Always | | **Config Target** | `.versionrc.json` | Tip This task is separate from `release/cat-version`. The `cat-version` task installs the `commit-and-tag-version` dependency and generates a `.versionrc` file (JSONC, legacy format). The `versionrc` task generates `.versionrc.json` (strict JSON, more feature-complete). You can use both in combination, or only `versionrc` if you install the tool separately.