@rnzeus/eslint-plugin
v0.1.3
Published
ESLint plugin for React / React Native projects focused on **style discipline**.
Readme
@rnzeus/eslint-plugin-style
ESLint plugin for React / React Native projects focused on style discipline.
This plugin is designed to solve real-world problems that appear during refactoring:
- unused styles left in
*.styles.tsfiles - inconsistent style naming
- unsafe dynamic style usage
- passing whole
stylesobjects to components
The plugin is static, runtime-free, and optimized for ESLint Flat Config (ESLint v9+).
Features
✅ rnzeus/styles-usage
Ensures that all styles declared in *.styles.ts(x) files are actually used in the corresponding component file.
What it checks:
- detects unused style keys
- forbids passing the whole
stylesobject (styles={styles}) - supports arrays:
style={[styles.foo, condition && styles.bar]} - supports conditional styles
- supports dynamic styles only with explicit directive comments
- supports additional “style-like” props (configurable): e.g.
contentContainerStyle
File convention (required):
Component.tsx
Component.styles.ts✅ rnzeus/styles-naming
Enforces snake_case naming for style keys.
Example:
// ❌ bad
itemName: {}
// ✅ good
item_name: {}Installation
npm install -D @rnzeus/eslint-plugin-style
# or
yarn add -D @rnzeus/eslint-plugin-stylePeer dependency:
eslint >= 9
Usage (ESLint Flat Config)
This plugin exports ready-to-use flat config presets.
No .default access and no manual plugin wiring is required.
Import preset
const styles = require('@rnzeus/eslint-plugin-style/configs/styles');Minimal setup
module.exports = [
...styles,
];With other presets
const rnfsd = require('@rnzeus/themis/eslint/rnfsd');
const styles = require('@rnzeus/eslint-plugin-style/configs/styles');
module.exports = [
...rnfsd,
...styles,
];Configure styles-usage style props
By default, rnzeus/styles-usage tracks style usage from these JSX props:
stylecontentContainerStyle
You can extend or override this list via rule options.
Merge (default)
type: "merge" is the default behavior:
- takes plugin defaults
- adds your
styleProps - de-duplicates
Example (add FlatList prop):
module.exports = [
...styles,
{
rules: {
"rnzeus/styles-usage": [
"error",
{
styleProps: ["columnWrapperStyle"],
type: "merge", // optional (default)
},
],
},
},
];Override
type: "override" ignores plugin defaults and uses only your styleProps.
module.exports = [
...styles,
{
rules: {
"rnzeus/styles-usage": [
"error",
{
styleProps: ["style"],
type: "override",
},
],
},
},
];Dynamic styles (important)
Dynamic access like this is not allowed by default:
<View style={styles[variant]} />You must explicitly document allowed keys using a directive comment:
// rnzeus-styles-used: primary | secondary
<View style={styles[variant]} />Supported comment forms:
// rnzeus-styles-used: a | b
/* rnzeus-styles-used: a | b */This makes dynamic styles:
- explicit
- reviewable
- safe during refactors
Rules
rnzeus/styles-usage
| Check | Status |
|-----|------|
Unused styles | ✅ |
Whole styles object (styles={styles}) | ❌ |
Array styles | ✅ |
Conditional styles | ✅ |
Dynamic styles | ⚠️ (directive required) |
Extra style props | ✅ (configurable) |
rnzeus/styles-naming
| Rule | Status | |----|----| snake_case only | ✅ | camelCase | ❌ | PascalCase | ❌ |
Regex used:
/^[a-z][a-z0-9_]*$/Philosophy
This plugin intentionally:
- avoids runtime helpers
- avoids TypeScript compiler APIs
- avoids project-wide analysis
- favors strict conventions over heuristics
The goal is predictability, performance, and refactor safety.
License
MIT
