Chrome Extension + Zustand + Tailwind rules for AI coding agents
Full stack: Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest
Ready-to-commit rules for Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest in every major format: AGENTS.md (Codex, Cursor, Copilot), CLAUDE.md (Claude Code), Cursor .mdc project rules, legacy .cursorrules, Copilot instructions, Windsurf rules and GEMINI.md. A Manifest V3 Chrome extension with a React popup.
Last reviewed 2026-10-21 · Customise in the generator · Raw: AGENTS.md, CLAUDE.md
Agents keep state in service worker globals, which vanish when Chrome stops the worker.
Generated files
# AGENTS.md - this project
Instructions for AI coding agents working in this repository.
## Project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## Project structure
- `src/background/` service worker, `src/content/` content scripts, `src/popup/` and `src/options/` UI.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
## Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
## Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
## Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
## Reference docs
- [Chrome extensions docs](https://developer.chrome.com/docs/extensions)
- [Tailwind CSS docs](https://tailwindcss.com/docs)
- [Zustand docs](https://zustand.docs.pmnd.rs)
- [Vitest docs](https://vitest.dev)
# CLAUDE.md - this project
Project instructions for Claude Code.
## Project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## Project structure
- `src/background/` service worker, `src/content/` content scripts, `src/popup/` and `src/options/` UI.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
## Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
## Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
## Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
## Reference docs
- [Chrome extensions docs](https://developer.chrome.com/docs/extensions)
- [Tailwind CSS docs](https://tailwindcss.com/docs)
- [Zustand docs](https://zustand.docs.pmnd.rs)
- [Vitest docs](https://vitest.dev)
---
description: "Core rules for this project"
alwaysApply: true
---
# this project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
description: "Chrome Extension (MV3) conventions: Manifest V3 browser extension in TypeScript."
globs: src/**/*.ts, src/**/*.tsx, manifest.json
alwaysApply: false
---
# Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
Docs: https://developer.chrome.com/docs/extensions
---
description: "Tailwind CSS v4 conventions: Utility-first styling with Tailwind CSS v4."
globs: **/*.css, **/*.tsx, **/*.vue, **/*.svelte, **/*.astro, **/*.html, **/*.blade.php, **/*.erb
alwaysApply: false
---
# Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
Docs: https://tailwindcss.com/docs
---
description: "Zustand conventions: Lightweight client state with Zustand."
globs: **/store/**/*.ts, **/stores/**/*.ts
alwaysApply: false
---
# Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
Docs: https://zustand.docs.pmnd.rs
---
description: "Vitest conventions: Unit and component tests with Vitest."
globs: **/*.test.ts, **/*.test.tsx, **/*.spec.ts
alwaysApply: false
---
# Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
Docs: https://vitest.dev
# Cursor rules - this project
You are an expert Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest engineer working on this codebase. Follow these rules.
## Project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## Project structure
- `src/background/` service worker, `src/content/` content scripts, `src/popup/` and `src/options/` UI.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
## Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
## Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
## Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
## Reference docs
- [Chrome extensions docs](https://developer.chrome.com/docs/extensions)
- [Tailwind CSS docs](https://tailwindcss.com/docs)
- [Zustand docs](https://zustand.docs.pmnd.rs)
- [Vitest docs](https://vitest.dev)
# Copilot instructions - this project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
applyTo: "src/**/*.ts,src/**/*.tsx,manifest.json"
---
# Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
---
applyTo: "**/*.css,**/*.tsx,**/*.vue,**/*.svelte,**/*.astro,**/*.html,**/*.blade.php,**/*.erb"
---
# Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
---
applyTo: "**/store/**/*.ts,**/stores/**/*.ts"
---
# Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
---
applyTo: "**/*.test.ts,**/*.test.tsx,**/*.spec.ts"
---
# Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
---
trigger: always_on
---
# this project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
trigger: glob
globs: src/**/*.ts, src/**/*.tsx, manifest.json
---
# Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
---
trigger: glob
globs: **/*.css, **/*.tsx, **/*.vue, **/*.svelte, **/*.astro, **/*.html, **/*.blade.php, **/*.erb
---
# Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
---
trigger: glob
globs: **/store/**/*.ts, **/stores/**/*.ts
---
# Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
---
trigger: glob
globs: **/*.test.ts, **/*.test.tsx, **/*.spec.ts
---
# Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
# GEMINI.md - this project
Project context for Gemini CLI.
## Project
A Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest project.
Stack: Chrome Extension (MV3), Tailwind CSS v4, Zustand, Vitest.
## Commands
- Build: `npm run build`
- Dev/watch: `npm run dev`
- Unit tests: `npx vitest run`
## Project structure
- `src/background/` service worker, `src/content/` content scripts, `src/popup/` and `src/options/` UI.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Chrome Extension (MV3)
- Manifest V3 only. The background script is a service worker: no DOM, no `window`, and it can be terminated at any time.
- Persist state in `chrome.storage`, never in service worker globals.
- Request the minimum permissions and host permissions. Prefer `activeTab` and optional permissions.
- No remotely hosted code and no `eval`; all code ships in the package.
- Communicate between contexts with `chrome.runtime.sendMessage` / `onMessage` and typed message objects.
- Register event listeners at the top level of the service worker so they survive restarts.
## Tailwind CSS v4
- Tailwind v4 is configured in CSS: `@import "tailwindcss";` plus `@theme { ... }` for design tokens. Do not create a `tailwind.config.js` unless the project already has one.
- Use theme tokens (colors, spacing) instead of arbitrary values like `w-[37px]`.
- Build responsive layouts mobile-first with `sm:`, `md:`, `lg:` prefixes.
- Extract repeated class lists into components, not `@apply` chains.
- Support dark mode with the `dark:` variant when the project uses it.
## Zustand
- Keep stores small and split by domain.
- Select only what a component needs (`useStore((s) => s.count)`) to avoid unnecessary re-renders.
- Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
## Vitest
- Co-locate tests next to the code as `*.test.ts(x)`.
- Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
## Reference docs
- [Chrome extensions docs](https://developer.chrome.com/docs/extensions)
- [Tailwind CSS docs](https://tailwindcss.com/docs)
- [Zustand docs](https://zustand.docs.pmnd.rs)
- [Vitest docs](https://vitest.dev)
Commands your agent should run
| Task | Command |
|---|---|
| Build | npm run build |
| Dev/watch | npm run dev |
| Unit tests | npx vitest run |
What the rules cover
Chrome Extension (MV3)
Manifest V3 browser extension in TypeScript. Scoped to src/**/*.ts, src/**/*.tsx, manifest.json in Cursor, Copilot and Windsurf.
- Manifest V3 only. The background script is a service worker: no DOM, no
window, and it can be terminated at any time. - Persist state in
chrome.storage, never in service worker globals. - Request the minimum permissions and host permissions. Prefer
activeTaband optional permissions. - No remotely hosted code and no
eval; all code ships in the package. - Communicate between contexts with
chrome.runtime.sendMessage/onMessageand typed message objects. - Register event listeners at the top level of the service worker so they survive restarts.
Source docs: Chrome extensions docs
Tailwind CSS v4
Utility-first styling with Tailwind CSS v4. Scoped to **/*.css, **/*.tsx, **/*.vue, **/*.svelte, **/*.astro, **/*.html, **/*.blade.php, **/*.erb in Cursor, Copilot and Windsurf.
- Tailwind v4 is configured in CSS:
@import "tailwindcss";plus@theme { ... }for design tokens. Do not create atailwind.config.jsunless the project already has one. - Use theme tokens (colors, spacing) instead of arbitrary values like
w-[37px]. - Build responsive layouts mobile-first with
sm:,md:,lg:prefixes. - Extract repeated class lists into components, not
@applychains. - Support dark mode with the
dark:variant when the project uses it.
Source docs: Tailwind CSS docs
Zustand
Lightweight client state with Zustand. Scoped to **/store/**/*.ts, **/stores/**/*.ts in Cursor, Copilot and Windsurf.
- Keep stores small and split by domain.
- Select only what a component needs (
useStore((s) => s.count)) to avoid unnecessary re-renders. - Use Zustand for client/UI state only. Server data belongs in the data-fetching layer.
Source docs: Zustand docs
Vitest
Unit and component tests with Vitest. Scoped to **/*.test.ts, **/*.test.tsx, **/*.spec.ts in Cursor, Copilot and Windsurf.
- Co-locate tests next to the code as
*.test.ts(x). - Test behaviour through public APIs; for components use Testing Library queries by role/label.
- Mock network calls at the boundary (e.g. MSW) rather than mocking internal modules.
- Every bug fix adds a test that fails without the fix.
Source docs: Vitest docs
How to install
- Copy
AGENTS.mdto your repo root. That covers Codex, Cursor, GitHub Copilot and most other agents. - Using Claude Code? Add a
CLAUDE.mdwith the single line@AGENTS.md, or use the standalone CLAUDE.md tab above. - Want rules that only load for certain files in Cursor? Add the
.cursor/rules/*.mdcfiles. - Commit the files so your whole team (and every agent) shares them.
FAQ
Where do I put the AGENTS.md for Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest?
Save it as AGENTS.md in the root of your repository, next to your main config file. Codex, Cursor and GitHub Copilot pick it up automatically. For Claude Code, add a CLAUDE.md containing @AGENTS.md (or use the standalone CLAUDE.md on this page).
What is the most common mistake AI agents make with Chrome Extension (MV3)?
Agents keep state in service worker globals, which vanish when Chrome stops the worker.
Which commands should the agent run to check its work?
For this stack: npm run build, npm run dev, npx vitest run. They are listed in the generated files so the agent runs them before finishing a task.
Do these Chrome Extension (MV3) + Tailwind CSS v4 + Zustand + Vitest rules work with Cursor and Claude Code?
Yes. This page includes the same rules as AGENTS.md, CLAUDE.md, Cursor .mdc project rules, a legacy .cursorrules file, GitHub Copilot instructions, Windsurf rules and GEMINI.md.
Can I customise these rules?
Yes. Open this stack in the generator to add or remove libraries, set your project name and package manager, switch beginner explanations on, and download everything as a zip.
Related stacks
Next.js (App Router) + Tailwind CSS v4 + Supabase + Stripe payments + Zod validation + Vitest
The full indie-hacker SaaS kit: auth, database, payments and tests.
Next.js (App Router) + Tailwind CSS v4 + Vitest + Playwright E2E
A Next.js app with a proper test setup: Vitest for units, Playwright for end-to-end.
React + Vite + Tailwind CSS v4 + TanStack Query + Vitest + Zod validation
A classic single-page app: React + Vite with TanStack Query for server data.
React + Vite + Tailwind CSS v4 + Supabase + Zustand
A client-only React app talking straight to Supabase, popular for quick prototypes and internal tools.
React + Vite + Tailwind CSS v4 + Firebase + Vitest
A React SPA on Firebase Auth and Firestore.
SvelteKit (Svelte 5) + Tailwind CSS v4 + Drizzle ORM + Vitest
SvelteKit full-stack with Drizzle ORM.