|
| 1 | +# eslint-plugin-template |
| 2 | + |
| 3 | +> A modern, TypeScript-first template for building ESLint plugins (Flat Config |
| 4 | +> ready) |
| 5 | +
|
| 6 | +[![npm version][npm-version-src]][npm-version-href] |
| 7 | +[![npm downloads][npm-downloads-src]][npm-downloads-href] |
| 8 | +[![License][license-src]][license-href] |
| 9 | + |
| 10 | +This repository is a starter template for creating your own ESLint plugin with: |
| 11 | + |
| 12 | +- ESLint 9 Flat Config support out of the box |
| 13 | +- TypeScript with strong typing for rules and options |
| 14 | +- Vitest-based rule tests via eslint-vitest-rule-tester |
| 15 | +- Rule scaffolding script to generate rule code, tests, and docs |
| 16 | +- Auto-generated README rules section via eslint-doc-generator |
| 17 | + |
| 18 | +Use it as a “Use this template” on GitHub or fork and rename. |
| 19 | + |
| 20 | +## Quick start |
| 21 | + |
| 22 | +1. Create your repo from this template |
| 23 | + |
| 24 | +- Click “Use this template” on GitHub, or |
| 25 | +- Degit locally: `degit christopher-buss/eslint-plugin-template my-plugin` |
| 26 | + |
| 27 | +2. Install dependencies |
| 28 | + |
| 29 | +```pwsh |
| 30 | +pnpm i |
| 31 | +``` |
| 32 | + |
| 33 | +3. Rename the package and plugin |
| 34 | + |
| 35 | +Update these fields to your plugin name (e.g., `eslint-plugin-awesome`): |
| 36 | + |
| 37 | +- `package.json` → `name`, `description`, `repository`, `author`, `license` |
| 38 | +- README title and badges |
| 39 | + |
| 40 | +The runtime plugin name (used in config) is derived from the package name by |
| 41 | +removing the `eslint-plugin-` prefix. For `eslint-plugin-awesome` the plugin key |
| 42 | +becomes `awesome`. |
| 43 | + |
| 44 | +4. Scaffold your first rule |
| 45 | + |
| 46 | +```pwsh |
| 47 | +pnpm create-rule my-new-rule |
| 48 | +``` |
| 49 | + |
| 50 | +This generates: |
| 51 | + |
| 52 | +- `src/rules/my-new-rule/rule.ts` – rule implementation |
| 53 | +- `src/rules/my-new-rule/rule.spec.ts` – tests |
| 54 | +- `src/rules/my-new-rule/documentation.md` – rule docs |
| 55 | + |
| 56 | +5. Run tests and docs |
| 57 | + |
| 58 | +```pwsh |
| 59 | +pnpm test |
| 60 | +pnpm eslint-docs |
| 61 | +``` |
| 62 | + |
| 63 | +The docs command updates the auto-generated rules list in this README. |
| 64 | + |
| 65 | +## Using your plugin |
| 66 | + |
| 67 | +Once published to npm as `eslint-plugin-awesome`, you can enable it in a |
| 68 | +project. |
| 69 | + |
| 70 | +### Flat Config (ESLint 9+) |
| 71 | + |
| 72 | +```js |
| 73 | +// eslint.config.js / eslint.config.mjs / eslint.config.ts |
| 74 | +import yourPlugin from "eslint-plugin-awesome"; |
| 75 | + |
| 76 | +export default [ |
| 77 | + // Enable all recommended rules from your plugin |
| 78 | + yourPlugin.configs.recommended, |
| 79 | + |
| 80 | + // Or wire it manually |
| 81 | + { |
| 82 | + plugins: { |
| 83 | + awesome: yourPlugin, |
| 84 | + }, |
| 85 | + rules: { |
| 86 | + "awesome/my-new-rule": "error", |
| 87 | + }, |
| 88 | + }, |
| 89 | +]; |
| 90 | +``` |
| 91 | + |
| 92 | +### Legacy Config (.eslintrc) |
| 93 | + |
| 94 | +```json |
| 95 | +{ |
| 96 | + "extends": ["plugin:yourname/recommended"] |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +## Development |
| 101 | + |
| 102 | +Scripts you’ll use during development: |
| 103 | + |
| 104 | +- `pnpm dev` – fast stub build for local iteration |
| 105 | +- `pnpm build` – type-safe build with d.ts via tsdown |
| 106 | +- `pnpm test` – run Vitest tests |
| 107 | +- `pnpm lint` – run ESLint on this repo |
| 108 | +- `pnpm typecheck` – run `tsc --noEmit` |
| 109 | +- `pnpm eslint-docs` – regenerate README rules list |
| 110 | +- `pnpm release` – bump version via bumpp |
| 111 | + |
| 112 | +Requirements: |
| 113 | + |
| 114 | +- Node.js >= 20 |
| 115 | +- pnpm >= 10 |
| 116 | +- ESLint >= 9.15.0 (peer dep for consumers) |
| 117 | + |
| 118 | +## Project structure |
| 119 | + |
| 120 | +```text |
| 121 | +src/ |
| 122 | + configs/ # Flat config presets (e.g., recommended) |
| 123 | + rules/ # Your rules (each in its own folder) |
| 124 | + plugin.ts # Plugin host (name, version, rules) |
| 125 | + util.ts # Rule creator with docs links |
| 126 | + index.ts # Entry combining plugin + configs (default export) |
| 127 | +scripts/ |
| 128 | + create-rule.ts # Scaffolds a new rule (code, tests, docs) |
| 129 | + template/ # Rule templates used by the script |
| 130 | +``` |
| 131 | + |
| 132 | +{ "extends": ["plugin:awesome/recommended"] } |
| 133 | + |
| 134 | +- The plugin key is computed from your package name (see `src/plugin.ts`). |
| 135 | +- `src/configs/recommended` is provided for convenience; add your rules there |
| 136 | + when ready. |
| 137 | + |
| 138 | +## Scaffolding a rule |
| 139 | + |
| 140 | +```pwsh |
| 141 | +pnpm create-rule my-new-rule |
| 142 | +``` |
| 143 | + |
| 144 | +What happens: |
| 145 | + |
| 146 | +1. Creates `src/rules/my-new-rule/` with `rule.ts`, `rule.spec.ts`, |
| 147 | + `documentation.md`. |
| 148 | +2. Attempts to register the rule. If automatic edit cannot be applied, the |
| 149 | + script prints the exact import and entry you can paste into your plugin/index |
| 150 | + file. |
| 151 | +3. Run `pnpm test` to validate, then `pnpm eslint-docs` to refresh this README. |
| 152 | + |
| 153 | +## Publishing |
| 154 | + |
| 155 | +Typical flow: |
| 156 | + |
| 157 | +```pwsh |
| 158 | +pnpm test |
| 159 | +pnpm build |
| 160 | +pnpm release # chooses the next semver and commits tags |
| 161 | +# CI publishes to npm |
| 162 | +``` |
| 163 | + |
| 164 | +## Rules reference |
| 165 | + |
| 166 | +Generate this section with: |
| 167 | + |
| 168 | +```pwsh |
| 169 | +pnpm eslint-docs |
| 170 | +``` |
| 171 | + |
| 172 | +<!-- begin auto-generated rules list --> |
| 173 | +<!-- end auto-generated rules list --> |
| 174 | + |
| 175 | +## Contributing |
| 176 | + |
| 177 | +PRs and issues welcome. If you’re using this as a template, adapt the sections |
| 178 | +to your needs and replace the badges and links. |
| 179 | + |
| 180 | +## License |
| 181 | + |
| 182 | +[MIT](./LICENSE) © 2025 [Christopher Buss](https://github.com/christopher-buss) |
| 183 | + |
| 184 | +<!-- Badges --> |
| 185 | + |
| 186 | +[npm-version-src]: https://img.shields.io/npm/v/eslint-plugin-template |
| 187 | +[npm-version-href]: https://npmjs.com/package/eslint-plugin-template |
| 188 | +[npm-downloads-src]: https://img.shields.io/npm/dm/eslint-plugin-template |
| 189 | +[npm-downloads-href]: https://npmjs.com/package/eslint-plugin-template |
| 190 | +[license-src]: |
| 191 | + https://img.shields.io/github/license/christopher-buss/eslint-plugin-template.svg |
| 192 | +[license-href]: ./LICENSE |
0 commit comments