Setting Up Linting and Formatting for Astro
How I configured Prettier and ESLint for my Astro blog to keep code consistent and catch issues early — with Tailwind class sorting included.
Why Bother?
Formatting and linting might seem like overkill for a personal blog, but here’s why I set them up from day one:
- Consistency — I don’t want to think about semicolons, quotes, or indentation. Ever.
- Tailwind class ordering — Tailwind utility classes can get long. Having them automatically sorted makes templates readable.
- Catch mistakes early — ESLint with the Astro plugin catches issues specific to
.astrofiles before they become runtime bugs. - Good habits — If I share code snippets on this blog, they should be well-formatted.
Prettier: The Formatter
Astro recommends Prettier with their official plugin. I also added the Tailwind plugin for automatic class sorting.
Installation
npm install --save-dev --save-exact prettier prettier-plugin-astro prettier-plugin-tailwindcss
The --save-exact flag pins exact versions — Prettier recommends this to avoid formatting changes between patch releases breaking your CI.
Configuration
.prettierrc at the project root:
{
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
],
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100
}
Key points:
prettier-plugin-tailwindcssmust be last in the plugins array — it needs to run after other plugins.- The
overridesblock tells Prettier to use the Astro parser for.astrofiles. - I chose single quotes and trailing commas — personal preference, pick what you like.
I also added a .prettierignore to skip generated files:
dist
node_modules
.astro
Usage
# Format everything
npm run format
# Check without writing (useful for CI)
npm run format:check
ESLint: The Linter
The community-maintained eslint-plugin-astro provides Astro-specific rules.
Installation
npm install --save-dev --save-exact eslint eslint-plugin-astro @typescript-eslint/parser
Configuration
eslint.config.mjs (flat config format):
import eslintPluginAstro from 'eslint-plugin-astro';
export default [
...eslintPluginAstro.configs.recommended,
{
ignores: ['.astro/**', 'dist/**'],
},
{
rules: {
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
},
},
];
Notes:
- **
.astro/**is ignored** — that’s Astro’s auto-generated types directory. Linting it produces dozens of false positives. argsIgnorePattern: '^_'— prefix unused variables with_to silence the warning intentionally.
Usage
npm run lint
VS Code Integration
To make this all seamless, I added .vscode/settings.json:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
},
"eslint.validate": ["javascript", "typescript", "astro"]
}
And recommended extensions in .vscode/extensions.json:
{
"recommendations": [
"astro-build.astro-vscode",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint"
]
}
Now when anyone clones this repo, VS Code will suggest the right extensions and formatting just works on save.
The Scripts
Here’s what my package.json scripts look like now:
{
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"format": "prettier . --write",
"format:check": "prettier . --check",
"lint": "eslint ."
}
}
What’s Next
In the next post, I’ll cover deployment — setting up CI/CD so that format:check and lint run automatically on every push, and the site deploys on merge to main.
Comments
Comments are powered by giscus and GitHub Discussions. Loading them connects to giscus.app and github.com, which may process your IP address and set cookies. See the privacy policy for details.