# Conformance Tasks

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

| 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

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

| Task ID | Description | Applicable When |
|---------|-------------|-----------------|
| `ts/strict` | Patch [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) with [`strict: true`](https://www.typescriptlang.org/tsconfig/#strict) (skips if explicitly `false`) | 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

| 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) | Bundler is [Vite](https://vitejs.dev/) |
| `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 | Bundler is Vite |

## CI/CD

| 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

For projects using [**pnpm**](https://pnpm.io/), CI workflows automatically include [`pnpm/action-setup@v4`](https://github.com/pnpm/action-setup) with [`package_json_file`](https://github.com/pnpm/action-setup#inputs) 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.

## 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

| 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 [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks), wire `commit-msg` hook to commitlint, add `prepare` script | Always |

## 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 |

## 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

| 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 |

## Editor

| Task ID | Description | Applicable When |
|---------|-------------|-----------------|
| `editor/vscode` | Write/merge [`.vscode/settings.json`](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) and [`.vscode/extensions.json`](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions) | Always |

### 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.

## 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

The `agent/skills-install` task automatically installs [agent skills](https://skills.sh) from the open ecosystem based on your detected stack. It reads your existing `skills-lock.json` and local skill directories to avoid reinstalling already-present skills.

| Stack | Skills Installed |
|-------|-----------------|
| **Web Frontend** (all browser/edge projects) | `frontend-design`, `web-design-guidelines`, `baseline-ui`, `fixing-accessibility`, `fixing-metadata`, `fixing-motion-performance` |
| **React** (including Next.js) | `vercel-react-best-practices`, `vercel-composition-patterns`, `react-dev`, `react-useeffect` |
| **Next.js** | `next-best-practices`, `next-cache-components`, `next-upgrade` |
| **Vue** | `vue`, `vue-best-practices` |
| **Nuxt** | `nuxt` |
| **Expo / React Native** | `expo-tailwind-setup`, `expo-cicd-workflows`, `expo-deployment`, `expo-dev-client`, `building-native-ui`, `native-data-fetching`, `expo-module`, `upgrading-expo`, `vercel-react-native-skills` |
| **Shadcn UI** | `shadcn` |
| **Ultracite** | `ultracite` |
| **Vite** | `vite` |
| **Vitest** | `vitest` |
| **tsdown** | `tsdown` |
| **Turborepo** | `turborepo` |
| **Supabase / Postgres** | `supabase-postgres-best-practices` |
| **Drizzle** | `postgres-drizzle` |
| **Redis** | `redis-best-practices` |
| **Better Auth** | `better-auth-best-practices`, `create-auth-skill` |
| **AI SDK** | `ai-sdk` |
| **Remotion** | `remotion-best-practices` |

## 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
**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

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

Tasks only run when their conditions are met:

- 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`

## References

### Linting & Formatting
- [Biome Documentation](https://biomejs.dev/) - Fast linter and formatter for JavaScript/TypeScript
- [Ultracite](https://www.ultracite.ai/) - Strict Biome preset for code quality
- [Tailwind CSS Directives](https://tailwindcss.com/docs/functions-and-directives) - `@theme`, `@apply`, and other directives

### TypeScript
- [TypeScript tsconfig Reference](https://www.typescriptlang.org/tsconfig/) - All compiler options
- [strict](https://www.typescriptlang.org/tsconfig/#strict) - Enable all strict type-checking options
- [paths](https://www.typescriptlang.org/tsconfig/#paths) - Module resolution path mapping
- [incremental](https://www.typescriptlang.org/tsconfig/#incremental) - Incremental compilation

### Vite
- [Vite Documentation](https://vitejs.dev/) - Next-generation build tool
- [vite-plugin-checker](https://vite-plugin-checker.netlify.app/) - Type-checking in development
- [rollup-plugin-visualizer](https://github.com/btd/rollup-plugin-visualizer) - Bundle visualization

### CI/CD
- [GitHub Actions Documentation](https://docs.github.com/en/actions) - Workflow syntax and features
- [actions/checkout](https://github.com/actions/checkout) - Check out repository
- [actions/setup-node](https://github.com/actions/setup-node) - Set up Node.js
- [pnpm/action-setup](https://github.com/pnpm/action-setup) - Set up pnpm

### Dependencies
- [Renovate Documentation](https://docs.renovatebot.com/) - Automated dependency updates

### Release
- [commitlint](https://commitlint.js.org/) - Lint commit messages
- [czg](https://cz-git.qbb.sh/cli/) - Interactive commit message helper
- [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) - Automated versioning

### Code Quality
- [Knip Documentation](https://knip.dev/) - Find unused files, dependencies, and exports

### Code Generation
- [Plop Documentation](https://plopjs.com/documentation/) - Micro-generator framework (only for projects with a detected framework)

### Monorepo
- [Turborepo Documentation](https://turbo.build/repo/docs) - Monorepo task orchestration

### Editor
- [VS Code Settings](https://code.visualstudio.com/docs/getstarted/settings) - Editor configuration
- [VS Code Extension Recommendations](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions) - Workspace extensions

[Learn how to contribute a new task →](/xtarterize/contributing/tasks/overview/)