How switching to OXLint, Prettier, and automated pre-commit hooks transformed our code quality workflow—making it 50x faster and completely invisible to developers.
Tony Kornmeier
After years of battling slow ESLint builds and wrestling with formatting conflicts, I've found a setup that finally gets out of the way and lets developers focus on writing code. Here's how modern tooling transformed our approach to code quality.
Most projects start with good intentions: ESLint for linting, Prettier for formatting, maybe some pre-commit hooks if you're disciplined. But in practice, this setup often creates friction:
The result? Developers disable linters, skip formatting, or worse—spend time in code review arguing about style instead of discussing logic.
Here's our current stack and why each tool earned its place:
We replaced ESLint with OXLint, a Rust-based linter that's 50-100x faster. Not 50% faster—50 times faster.
# Old ESLint setup
eslint . # ~12s on our codebase
# New OXLint setup
oxlint . # ~0.2s on the same codebase
Why OXLint wins:
The speed difference isn't just a nice-to-have—it fundamentally changes how you interact with your linter. Instant feedback means you actually run it. Frequently.
Prettier remains the gold standard for code formatting, and for good reason:
{
"semi": false,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "es5",
"plugins": ["prettier-plugin-tailwindcss"]
}
Why Prettier is non-negotiable:
prettier-plugin-tailwindcss plugin keeps utility classes organizedThe key insight: Formatting isn't a code quality concern—it's an automation problem. Let Prettier handle it and move on.
Unlike ESLint + Prettier (which requires eslint-config-prettier to prevent conflicts), OXLint and Prettier work together naturally:
No overlap. No conflicts. No configuration needed to make them play nice.
Having great tools is only half the battle—you need to ensure they actually run. Enter simple-git-hooks and lint-staged.
We chose simple-git-hooks over alternatives like Husky because:
{
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
}
}
lint-staged ensures we only process changed files:
{
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"oxlint --fix",
"prettier --write"
],
"*.{json,yml,yaml,css,scss,md}": [
"prettier --write"
]
}
}
The magic:
git commitThis happens invisibly, every single time. No manual intervention required.
Here's the full configuration for our stack:
Install dependencies:
pnpm add -D oxlint prettier prettier-plugin-tailwindcss
pnpm add -D simple-git-hooks lint-staged
package.json:
{
"scripts": {
"lint": "oxlint .",
"lint:fix": "oxlint --fix .",
"format": "prettier --write .",
"format:check": "prettier --check .",
"postinstall": "simple-git-hooks"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": ["oxlint --fix", "prettier --write"],
"*.{json,yml,yaml,css,scss,md}": ["prettier --write"]
}
}
.prettierrc:
{
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"plugins": ["prettier-plugin-tailwindcss"]
}
Initialize hooks:
pnpm exec simple-git-hooks
That's it. Under 100 lines of configuration for a complete, production-ready linting and formatting system.
Since switching to this setup six months ago on our team:
The key insight from this setup isn't just about faster tools—it's about how speed changes behavior.
When linting takes 12 seconds, you run it reluctantly. When it takes 0.2 seconds, you run it constantly. When formatting requires manual intervention, it gets skipped. When it's automatic, it never fails.
Fast, invisible tooling doesn't just save time—it creates a culture where quality is the default, not an aspiration.
If you're still using ESLint + Prettier with manual formatting:
The future of developer tooling is fast, focused, and frictionless. This setup is available today.
Interested in more content on developer tools, accessibility testing, and building better workflows? Check out my open source projects or get in touch.