skill
astro-doctor
Astro diagnostics for performance, accessibility, security, and best practices—CLI, ESLint/Oxlint plugins, GitHub Action, and VS Code extension.
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/santi020k/astro-doctor itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 25, 2026Your agent writes bad Astro. This catches it.
Astro Doctor deterministically scans your Astro codebase and catches issues across performance, accessibility, security, and best practices — before they reach production. It scores your project health (0–100), teaches your coding agent Astro patterns, and reports new issues directly on PRs.
Works as a CLI, an ESLint plugin, and a GitHub Action.
Explore: Install · Rules · Health Score · CLI Reference · Configuration · Development
Install
1. Quick scan (no install needed)
pnpm dlx @santi020k/astro-doctor@latest
Sample output:
Scanning /my-project...
src/pages/index.astro 12:3 warning Prefer client:idle over client:load (no-client-load-overuse)
src/components/Hero.astro 5:1 warning Use <Image> from astro:assets (use-astro-image)
2 problems (0 errors, 2 warnings) across 14 files
Astro Doctor Score: 98/100 (A) 🟢
2. Install the ESLint plugin
For inline editor diagnostics via ESLint:
pnpm add -D @santi020k/eslint-plugin-astro-doctor
// eslint.config.js
import astroDoctorPlugin from '@santi020k/eslint-plugin-astro-doctor'
export default [
astroDoctorPlugin.configs.recommended,
]
3. Install agent skills
Once you have a scan, install skills so your coding agent learns from the findings:
pnpm dlx @santi020k/astro-doctor@latest install
This copies the packaged guide to skills/astro-doctor.md. Reference it from your agent instructions. Add --agent-hooks to also install native Claude Code and Cursor paths.
4. Run in CI (GitHub Actions)
On pull requests, Astro Doctor compares the branch against its base and reports only issues introduced by your change — not pre-existing findings in touched files — then posts a sticky summary comment that updates in-place.
name: Astro Doctor
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
pull-requests: write
concurrency:
group: astro-doctor-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
astro-doctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # required for diff mode
- uses: santi020k/astro-doctor@v1
Pin to a commit SHA for hardened CI:
- uses: santi020k/astro-doctor@<sha> # v1.x.x
Rules
Astro Doctor owns 13 opinionated Astro rules and composes them with the official
eslint-plugin-astro catalog. Depending on the preset, the CLI provides up to
73 checks: 63 ESLint checks plus ten project audits in the all preset.
Overlapping rules are deduplicated automatically.
| Preset | Coverage |
|---|---|
recommended | Astro Doctor rules, project audits, and official Astro recommended rules |
strict | Recommended plus selected official Astro security and best-practice rules |
all | Every non-deprecated official Astro rule, including stylistic rules |
ci | Recommended coverage, failing on warnings with the CI score threshold |
Performance
| Rule | Severity | Description |
|---|---|---|
no-client-load-overuse | ⚠️ warning | Prefer client:idle or client:visible over client:load |
use-astro-image | ⚠️ warning | Use <Image> from astro:assets instead of raw <img> |
require-image-dimensions | ⚠️ warning | Add dimensions for public and remote Astro image components |
no-blocking-script | ⚠️ warning | Add defer, async, or type="module" to <script src="..."> tags |
no-unprocessed-script-surprises | ⚠️ warning | Warn when script attributes opt out of Astro processing |
Accessibility
| Rule | Severity | Description |
|---|---|---|
no-missing-alt | ❌ error | All image elements must have an alt attribute |
no-missing-lang | ❌ error | The <html> element must have a lang attribute |
require-island-fallback | ⚠️ warning | Add fallback content for client:only and server:defer islands |
Security
| Rule | Severity | Description |
|---|---|---|
no-set-html | ⚠️ warning | set:html is a potential XSS vector — sanitize before use |
no-public-secret-env | ⚠️ warning | Avoid PUBLIC_ env names that look like secrets |
Best Practices
| Rule | Severity | Description |
|---|---|---|
prefer-class-list | ⚠️ warning | Use class:list instead of template literals for dynamic class names |
no-process-env | ⚠️ warning | Use import.meta.env instead of process.env in Astro files |
prefer-content-collections | ⚠️ warning | Use Content Collections instead of Astro.glob() / import.meta.glob() for typed, cached content |
Project Audits
The CLI also checks project files such as astro.config.*, package.json, .env.example, src/actions/, src/content/, and Astro components.
| Check | Severity | Description |
|---|---|---|
no-disabled-origin-check | ⚠️ warning | Keep Astro's CSRF origin check enabled |
no-insecure-session-cookie | ⚠️ warning | Keep secure, HTTP-only, same-site session cookie protections enabled |
no-open-allowed-domains | ⚠️ warning | Avoid security.allowedDomains: [{}] |
no-legacy-astro-7-experimental-flags | ⚠️ warning | Migrate removed Astro 7 experimental flags |
prefer-env-schema | ⚠️ warning | Define an Astro env schema for documented env vars |
prefer-pnpm | opt-in | Use pnpm consistently and avoid npm, Yarn, and Bun lockfiles |
require-action-input-schema | ⚠️ warning | Validate untrusted Astro Action input before handlers run |
require-client-router-script-lifecycle | strict | Initialize scripts on astro:page-load when using ClientRouter |
require-content-config | ⚠️ warning | Add a content config when using src/content/ |
require-fetch-default-export | ⚠️ warning | Ensure Astro 7 advanced-routing entrypoints have a default export |
Health Score
Every scan produces a score from 0 to 100 with a letter grade (S–F).
Each file is scored independently: errors cost 25 points and warnings cost 10 points (clamped to 0–100 per file). The per-file scores are then averaged, so a single heavily-broken file doesn't drag down the score of an otherwise-clean project.
Projects with unresolved errors cannot score above 89, and projects with unresolved security errors cannot score above 74. Multi-project scans use the lowest project score as the aggregate so a healthy package cannot hide an unhealthy one.
| Grade | Score | Meaning |
|---|---|---|
| S 🌟 | 100 | Zero diagnostics — no issues found anywhere in the codebase |
| A ✅ | 90–99 | Excellent |
| B 🟢 | 75–89 | Good |
| C 🟡 | 60–74 | Fair |
| D 🟠 | 40–59 | Needs attention |
| F 🔴 | 0–39 | Critical |
Use --no-score to hide the score from output.
CLI Reference
# Scan the current directory
pnpm dlx @santi020k/astro-doctor@latest
# Scan a specific path
pnpm dlx @santi020k/astro-doctor@latest --dir ./src
# Scaffold config, ESLint setup, and GitHub Action
pnpm dlx @santi020k/astro-doctor@latest init
# Output a JSON report (to stdout)
pnpm dlx @santi020k/astro-doctor@latest --json
# Output a JSON report to a file
pnpm dlx @santi020k/astro-doctor@latest --json ./report.json
# Output SARIF for GitHub Code Scanning or other SARIF consumers
pnpm dlx @santi020k/astro-doctor@latest --format sarif > astro-doctor.sarif
# Apply safe automatic fixes where supported
pnpm dlx @santi020k/astro-doctor@latest --fix
# Cache lint results by file content
pnpm dlx @santi020k/astro-doctor@latest --cache
# Adopt Astro Doctor without failing on existing findings
pnpm dlx @santi020k/astro-doctor@latest baseline create
pnpm dlx @santi020k/astro-doctor@latest --baseline .astro-doctor-baseline.json
# Report only diagnostics introduced since main
pnpm dlx @santi020k/astro-doctor@latest --scope changed --base main
# Fail on warnings too (default: only errors)
pnpm dlx @santi020k/astro-doctor@latest --fail-on warning
# Use the CI preset (fail on warnings, score threshold 90)
pnpm dlx @santi020k/astro-doctor@latest --preset ci
# Run all non-deprecated official Astro rules
pnpm dlx @santi020k/astro-doctor@latest --preset all
# Hide the health score
pnpm dlx @santi020k/astro-doctor@latest --no-score
# Install agent skills
pnpm dlx @santi020k/astro-doctor@latest install
# Experimental language server (LSP)
pnpm dlx @santi020k/astro-doctor@latest experimental-lsp --stdio
# Show help
pnpm dlx @santi020k/astro-doctor@latest --help
Configuration
Create a doctor.config.ts (or .js, .mjs, .cjs, .json, .jsonc) in your project root:
// doctor.config.ts
import type { AstroDoctorConfig } from '@santi020k/astro-doctor'
export default {
preset: 'recommended',
rules: {
// Promote to error — no client:load allowed in this project
'astro-doctor/no-client-load-overuse': 'error',
// Disable if you sanitize set:html globally
'astro-doctor/no-set-html': 'off',
},
overrides: [
{
files: ['src/legacy/**'],
rules: {
'astro-doctor/no-set-html': 'off',
},
},
],
ignore: ['src/legacy/**'],
failOn: 'error',
} satisfies AstroDoctorConfig
Or in JSON:
{
"$schema": "https://doctor.santi020k.com/schema/config.json",
"preset": "ci",
"rules": {
"astro-doctor/no-client-load-overuse": "error"
}
}
GitHub Action Reference
- uses: santi020k/astro-doctor@v1
with:
working-directory: '.' # directory to scan
fail-on: 'error' # error | warning | off
min-score: '0' # minimum passing health score (0–100)
comment: 'true' # post sticky PR summary comment
diff-only: 'true' # on PRs, report only newly introduced diagnostics
json-report: '' # path to write JSON report (optional)
sarif-report: '' # path to write SARIF 2.1.0 (optional)
upload-sarif: 'false' # upload to GitHub Code Scanning
Set security-events: write in the workflow permissions when upload-sarif is enabled.
PR comments are skipped automatically for fork and Dependabot pull requests because GitHub gives
those workflows a read-only token. Scanning and failure gates still run.
Outputs:
| Output | Description |
|---|---|
total | Total diagnostics found |
errors | Error-severity count |
warnings | Warning-severity count |
score | Health score 0–100 |
score-label | Letter grade (S, A–F) |
Editor Integrations
VS Code & Cursor
Astro Doctor has an official extension for VS Code and Cursor. It provides:
- Live Diagnostics: Real-time linting as you type.
- Quick Fixes: Apply safe rule fixes where supported and offer effective line suppression actions in JavaScript frontmatter.
- Health Sidebar: A visual health report with a score ring and category breakdown inside the VS Code Sidebar.
- Hover Info: Detailed explanations when hovering over issues.
Commands available in the Command Palette:
Astro Doctor: Scan WorkspaceAstro Doctor: Scan Current FileAstro Doctor: Apply All Safe Fixes in File
Other Editors (Experimental LSP)
Any LSP-capable editor (like Zed or Neovim) can run the language server directly over stdio:
astro-doctor experimental-lsp --stdio
The LSP is experimental — its protocol may change between releases.
Agent Skills
The repository includes three additional skills for manual use and contribution:
| Skill | Location | Description |
|---|---|---|
| Astro Rules | .agents/skills/astro-rules/ | All 13 rules with before/after examples |
| Astro Performance | .agents/skills/astro-performance/ | Islands architecture patterns |
| Add Rule | .agents/skills/add-rule/ | How to add a new rule to astro-doctor |
Install the packaged Astro Doctor guide into skills/astro-doctor.md:
pnpm dlx @santi020k/astro-doctor@latest install
Use --agent-hooks to additionally write .claude/skills/astro-doctor.md and
.cursor/rules/astro-doctor.mdc. The installer does not copy the repository-only skill folders.
Packages
| Package | Description |
|---|---|
@santi020k/astro-doctor | CLI tool + public API |
@santi020k/eslint-plugin-astro-doctor | ESLint plugin with all rules |
Development
pnpm install # Install dependencies
pnpm run build # Build all packages
pnpm run test # Run tests (TDD: tests were written before implementations)
pnpm run lint # Run ESLint + CSpell + Knip
pnpm run ok # Full check: build + test + lint + typecheck
Credits & Inspiration
Astro Doctor was inspired by react-doctor by Million Software, Inc.
react-doctor is a fantastic tool that deterministically scans React codebases for performance, security, and accessibility issues. It introduced the diagnostic CLI for framework-specific anti-patterns, the PR diff mode that reports only new issues, the sticky summary comment, the JSON report format, the health score, and the installable agent skill format.
Astro Doctor brings the same philosophy to Astro. If you work with React, go check out react-doctor — it's excellent.
ESLint configuration powered by @santi020k/eslint-config-basic.
Find your next step
| Resource | Use it for |
|---|---|
@santi020k/astro-doctor | Focused installation and usage reference. |
@santi020k/eslint-plugin-astro-doctor | Focused installation and usage reference. |
| Security policy | Private vulnerability reporting and support boundaries. |
License
MIT — santi020k
For confidential vulnerability reports, see SECURITY.md.
For pull-request selection, full-validation safeguards, and measured timings, see affected CI validation.