StyleX + ESLint: When Best Practices Fight Each Other
Source: Dev.to
The Setup: Following All the Rules
Vite config
Using enableMediaQueryOrder: true as recommended in v0.15.0:
// vite.config.js
styleXUnplugin.vite({
enableMediaQueryOrder: true,
})
ESLint config
Using the recommended StyleX plugin rules:
// eslint.config.mjs
rules: {
"@stylexjs/valid-styles": "error",
"@stylexjs/sort-keys": "warn", // Keep styles organized!
}
Responsive styles
Using inline strings with the correct cascade order:
const styles = stylex.create({
container: {
padding: {
default: "2rem",
"@media (max-width: 768px)": "1.5rem", // tablet
"@media (max-width: 640px)": "1rem", // mobile
},
},
});
The order is larger breakpoints first so smaller ones can override them in the CSS cascade.
The Problem: A Helpful ESLint Warning
Running npm run lint produced:
warning StyleX property key "@media (max-width: 640px)"
should be above "@media (max-width: 768px)"
Running npm run lint -- --fix let ESLint “fix” the code:
padding: {
default: "2rem",
"@media (max-width: 640px)": "1rem", // now first (640)
}
“You can now write overlapping media queries in the order you desire, and the compiler will rewrite them so that later queries take precedence over earlier ones.”
— StyleX v0.15.0 Release Notes
The feature relies on source order, but the StyleX ESLint plugin’s sort-keys rule destroys that order. The two tools are at odds.
The Workaround
Until the issue is fixed upstream, wrap responsive properties in ESLint disable blocks:
const styles = stylex.create({
container: {
/* eslint-disable @stylexjs/sort-keys -- max-width cascade: larger breakpoints first */
padding: {
default: "2rem",
"@media (max-width: 768px)": "1.5rem",
"@media (max-width: 640px)": "1rem",
},
/* eslint-enable @stylexjs/sort-keys */
},
});
The block comments prevent the sort-keys rule from reordering the nested media queries while still allowing the rule to run elsewhere.
Key Takeaways
- Don’t blindly trust
--fix– automatic fixes can break semantic ordering that linters don’t understand. - Test responsive styles after linting – verify that breakpoints still work after running
eslint --fix. - Document exceptions – comments like
-- max-width cascade: larger breakpoints firstexplain why a rule is disabled. - File upstream issues – reporting the problem helps the maintainers improve the rule.
The Fix We Need
The @stylexjs/sort-keys rule should:
- Skip sorting inside media query objects – detect
@mediakeys and preserve the author’s order. - Sort by specificity – understand that
max-widthqueries need descending order, whilemin-widthqueries need ascending order. - Provide configuration – allow users to opt out of sorting for specific patterns.
Until such improvements land, keep the ESLint disable comments handy.
Reference: