A comprehensive SEO audit tool with 251 audit rules across 20 categories . Available as both a command-line tool and an Electron desktop app . Analyze any website for SEO best practices, Core Web Vitals, security headers, structured data, accessibility, JavaScript rendering, redirect chains, and more.
Prefer a web interface? Try our Free SEO Audit Tool for a visual, browser-based SEO analysis.
251 SEO Audit Rules across 20 categories
Desktop App - Visual audit dashboard with real-time progress, interactive results, score history, and light/dark theme
CLI Tool - Single page & crawl mode with 5 output formats
Core Web Vitals - LCP, CLS, FCP, TTFB, INP measurement via Playwright
JavaScript Rendering Analysis - Compare raw vs rendered DOM for SPA/CSR sites
5 Output Formats - Console, JSON, HTML, Markdown, and LLM-optimized XML
AI/GEO Readiness - Check semantic HTML, AI bot access, and llms.txt
Redirect Chain Detection - Loops, broken redirects, meta/JS redirects
HTML Validation - Doctype, charset, head structure, lorem ipsum detection
Cross-Page Analysis - Duplicate content detection, orphan pages, pagination
Concurrent Crawling - Fast multi-page audits with configurable concurrency
SQLite Storage - Persistent crawl data with compression and audit history
CI/CD Ready - Exit codes, JSON output, GitHub Actions & GitLab CI examples
TOML Configuration - Project-level settings with presets and inheritance
# Install globally
npm install -g @seomator/seo-audit
# Run audit
seomator audit https://example.com
Note: The CLI automatically uses your system Chrome, Chromium, or Edge browser for Core Web Vitals measurement. No additional browser installation is required if you have Chrome installed.
git clone https://github.com/seo-skills/seo-audit-skill.git
cd seo-audit-skill
npm install
npm run build
# Run directly
./dist/cli.js audit https://example.com
# Or link globally
npm link
seomator audit https://example.com
The desktop app provides a visual audit dashboard with real-time progress streaming, interactive results, score history, and light/dark theme support.
# From source
git clone https://github.com/seo-skills/seo-audit-skill.git
cd seo-audit-skill
npm install
npx electron-rebuild -f -w better-sqlite3 # Compile native module for Electron
npm run electron:dev # Launch with hot reload
npm run electron:build # Production build
npm run electron:pack # Build + package distributable
Real-time progress - Live category-by-category progress as the audit runs
Score dashboard - Overall score circle, category grid, and issues summary table
Interactive results - Expandable rule cards with rule descriptions, affected items, page URL badges, and inline fix suggestions
Filter & navigate - Filter by status (All/Failures/Warnings/Passed), click issues to jump to details
Score history - Track audit scores over time per domain with trend charts
Light/dark theme - Follows your system preference or toggle manually
# Basic audit
seomator audit https://example.com
# Skip Core Web Vitals (faster)
seomator audit https://example.com --no-cwv
# Audit specific categories
seomator audit https://example.com -c core,security,perf
# JSON output (for CI/CD or parsing)
seomator audit https://example.com --format json
# HTML report
seomator audit https://example.com --format html -o report.html
# LLM-optimized output (pipe to Claude)
seomator audit https://example.com --format llm --no-cwv | claude " analyze and prioritize fixes"
# Crawl multiple pages
seomator audit https://example.com --crawl --max-pages 20
# Full options
seomator audit https://example.com --crawl -m 50 --concurrency 5 --timeout 60000 --format json -o results.json
Run SEO audit on a URL.
Option
Alias
Description
Default
--format <type>
-f
Output format: console, json, html, markdown, llm
console
--output <path>
-o
Output file path
-
--categories <list>
-c
Comma-separated categories to audit
All
--json
-j
Output as JSON (deprecated, use --format json)
false
--crawl
-
Enable crawl mode for multiple pages
false
--max-pages <n>
-m
Maximum pages to crawl
10
--concurrency <n>
-
Concurrent requests
3
--timeout <ms>
-
Request timeout in milliseconds
30000
--no-cwv
-
Skip Core Web Vitals measurement
false
--verbose
-v
Show progress
false
--refresh
-r
Ignore cache, fetch fresh
false
--resume
-
Resume interrupted crawl
false
--config <path>
-
Config file path
-
--save
-
Save report to .seomator/reports/
false
Create a seomator.toml config file.
seomator init # Interactive setup
seomator init -y # Use defaults
seomator init --preset blog # Blog preset
seomator init --preset ecommerce # E-commerce preset
seomator init --preset ci # Minimal CI config
Crawl website without running analysis. Saves data for later analysis with seomator analyze.
seomator crawl https://example.com -m 20
seomator crawl https://example.com --refresh
seomator crawl https://example.com --resume
seomator analyze [crawl-id]
Run rules on stored crawl data.
seomator analyze # Analyze latest crawl
seomator analyze --latest --save # Analyze and save
seomator analyze 2026-01-23-abc123 # Specific crawl
View and query past reports.
seomator report --list # List all reports
seomator report --project mysite # Filter by project
seomator config [key] [value]
View or modify configuration.
seomator config --list # Show all config
seomator config crawler.max_pages 50 # Set value
seomator config validate # Validate config
Database management.
seomator db migrate # Migrate JSON to SQLite
seomator db migrate --dry-run # Preview migration
seomator db stats -v # Database statistics
seomator db restore # Rollback migration
Check system setup and dependencies.
seomator self doctor -v # Verbose diagnostics
Code
Meaning
0
Audit passed (score >= 70)
1
Audit failed (score < 70)
2
Error occurred
Categories & Rules (251 total)
Core (19 rules) - 12% weight
Rule
Description
core-title-present
<title> tag exists
core-title-length
Title should be 30-60 characters
core-description-present
Meta description exists
core-description-length
Description should be 120-160 characters
core-canonical-present
Canonical URL exists
core-canonical-valid
Canonical URL is valid absolute URL
core-viewport-present
Viewport meta tag exists
core-favicon-present
Favicon link exists
core-h1-present
At least one H1 exists
core-h1-single
Only one H1 exists
core-canonical-header
HTML canonical and Link header match
core-nosnippet
Detects nosnippet/max-snippet:0 directives
core-robots-meta
Checks noindex/nofollow directives
core-title-unique
Titles should be unique site-wide
core-canonical-conflicting
HTML and header canonicals should not conflict
core-canonical-to-homepage
Canonical should not always point to homepage
core-canonical-http-mismatch
Canonical protocol should match page protocol
core-canonical-loop
Detects circular canonical chains
core-canonical-to-noindex
Canonical should not point to noindexed page
Performance (22 rules) - 12% weight
Rule
Description
cwv-lcp
Largest Contentful Paint (<2.5s pass, >4s fail)
cwv-cls
Cumulative Layout Shift (<0.1 pass, >0.25 fail)
cwv-inp
Interaction to Next Paint (<200ms pass, >500ms fail)
cwv-ttfb
Time to First Byte (<800ms pass, >1800ms fail)
cwv-fcp
First Contentful Paint (<1.8s pass, >3s fail)
perf-dom-size
DOM should have <1500 nodes
perf-css-file-size
CSS files should be reasonably sized
perf-font-loading
Font-display: swap should be used
perf-preconnect
Preconnect hints for third-party origins
perf-render-blocking
Scripts should use async/defer
perf-lazy-above-fold
Above-fold images should not be lazy-loaded
perf-lcp-hints
LCP element should be preloaded
perf-text-compression
Responses should use gzip/Brotli compression
perf-brotli
Prefer Brotli over gzip for better compression
perf-cache-policy
Static assets should have cache headers
perf-minify-css
CSS should be minified
perf-minify-js
JavaScript should be minified
perf-response-time
Server response time should be <200ms
perf-http2
Site should serve over HTTP/2
perf-page-weight
Total page size should be <3MB
perf-js-file-size
Individual JS files should be <500KB
perf-video-for-animations
Use <video> instead of animated GIFs
Links (19 rules) - 8% weight
Rule
Description
links-broken-internal
Internal links should return 200
links-external-valid
External links should be reachable
links-internal-present
Page should have internal links
links-nofollow-appropriate
nofollow used appropriately
links-anchor-text
Anchor text should be descriptive
links-depth
Page depth should be ≤3 from homepage
links-dead-end-pages
Pages should have outgoing internal links
links-https-downgrade
HTTPS pages should not link to HTTP
links-external-count
Warn if >100 external links
links-invalid-links
No empty, javascript:, or malformed hrefs
links-tel-mailto
Valid tel: and mailto: link formats
links-redirect-chains
Links should not go through redirects
links-orphan-pages
Pages should have incoming links
links-localhost
No localhost/127.0.0.1 URLs in production
links-local-file
No file:// protocol links
links-broken-fragment
Fragment links should match element IDs
links-excessive
Limit internal links per page
links-onclick
No onclick-based navigation instead of <a> tags
links-whitespace-href
No whitespace in href attributes
Images (14 rules) - 8% weight
Rule
Description
images-alt-present
All images should have alt attribute
images-alt-quality
Alt text should be descriptive
images-dimensions
Images should have width/height
images-lazy-loading
Below-fold images should use lazy loading
images-modern-format
Use WebP/AVIF formats
images-size
Images should be <200KB
images-responsive
Use srcset for responsive images
images-broken
Images should not return 404
images-figure-captions
Figure elements should have figcaption
images-filename-quality
Use descriptive filenames
images-inline-svg-size
Inline SVGs should be <5KB
images-picture-element
Picture elements must have img fallback
images-alt-length
Alt text should be under 125 characters
images-background-seo
Content images should use <img>, not CSS background
Security (16 rules) - 8% weight
Rule
Description
security-https
Site should use HTTPS
security-https-redirect
HTTP should redirect to HTTPS
security-hsts
Strict-Transport-Security header
security-csp
Content-Security-Policy header
security-x-frame
X-Frame-Options header
security-x-content-type
X-Content-Type-Options: nosniff
security-external-links
External target="_blank" links have noopener/noreferrer
security-form-https
Form actions use HTTPS
security-mixed-content
No HTTP resources on HTTPS pages
security-permissions-policy
Permissions-Policy header present
security-referrer-policy
Referrer-Policy header present
security-leaked-secrets
No exposed API keys or credentials
security-password-http
Login forms served over HTTPS only
security-protocol-relative
No protocol-relative URLs (//example.com)
security-ssl-expiry
SSL certificate not near expiration
security-ssl-protocol
TLS 1.2+ required; no TLS 1.0/1.1
Technical SEO (13 rules) - 7% weight
Rule
Description
technical-robots-txt-exists
robots.txt should return 200
technical-robots-txt-valid
robots.txt should have valid syntax
technical-sitemap-exists
sitemap.xml should exist
technical-sitemap-valid
Sitemap should have valid XML structure
technical-url-structure
URL should use hyphens, lowercase
technical-trailing-slash
Consistent trailing slash usage
technical-www-redirect
www/non-www should redirect to one version
technical-404-page
Custom 404 page should exist
technical-soft-404
Soft 404 pages should return proper 404 status
technical-server-error
No 5xx server errors
technical-4xx-non-404
No 400, 403, 410 client errors
technical-timeout
Pages should respond within timeout
technical-bad-content-type
Content-Type header matches actual content
Crawlability (18 rules) - 5% weight
Rule
Description
crawl-schema-noindex-conflict
Schema.org and noindex should not conflict
crawl-pagination-canonical
Paginated pages should self-canonicalize
crawl-sitemap-domain
Sitemap URLs should match host domain
crawl-noindex-in-sitemap
Noindexed pages should not be in sitemap
crawl-indexability-conflict
robots.txt and noindex should not both block
crawl-canonical-redirect
Canonical should not point through redirects
crawl-sitemap-url-limit
Sitemap should have <50,000 URLs
crawl-sitemap-size-limit
Sitemap should be <50MB
crawl-sitemap-duplicate-urls
No duplicate URLs in sitemap
crawl-sitemap-orphan-urls
Sitemap URLs should be linked internally
crawl-blocked-resources
Critical resources not blocked by robots.txt
crawl-crawl-delay
Excessive Crawl-delay slows indexing
crawl-sitemap-in-robotstxt
robots.txt should reference sitemap
crawl-pagination-broken
Pagination links should not be broken
crawl-pagination-loop
No circular pagination chains
crawl-pagination-sequence
No gaps in pagination sequence
crawl-pagination-noindex
Paginated pages should not be noindexed
crawl-pagination-orphaned
Paginated pages should be linked from content
Structured Data (13 rules) - 5% weight
Rule
Description
schema-present
JSON-LD or microdata should exist
schema-valid
JSON-LD should be valid JSON
schema-type
@type field should be present
schema-required-fields
Required fields for schema type
schema-article
Validates Article schema properties
schema-breadcrumb
Checks BreadcrumbList on non-homepage
schema-faq
Validates FAQPage schema structure
schema-local-business
Validates LocalBusiness for local SEO
schema-organization
Validates Organization schema
schema-product
Validates Product schema for e-commerce
schema-review
Validates Review/AggregateRating schema
schema-video
Validates VideoObject schema
schema-website-search
Checks WebSite sitelinks searchbox
JavaScript Rendering (13 rules) - 5% weight
Rule
Description
js-rendered-title
Title present in rendered DOM
js-rendered-description
Meta description present in rendered DOM
js-rendered-h1
H1 present in rendered DOM
js-rendered-canonical
Canonical present in rendered DOM
js-canonical-mismatch
Canonical matches between raw and rendered HTML
js-noindex-mismatch
Noindex consistent between raw and rendered HTML
js-title-modified
Title not changed by JavaScript
js-description-modified
Description not changed by JavaScript
js-h1-modified
H1 not changed by JavaScript
js-rendered-content
Main content present without JavaScript dependency
js-rendered-links
Navigation links present without JavaScript
js-blocked-resources
Critical JS not blocked by robots.txt
js-ssr-check
Server-side rendering detected
Accessibility (12 rules) - 4% weight
Rule
Description
a11y-aria-labels
Interactive elements have accessible names
a11y-color-contrast
Color contrast issues detected
a11y-focus-visible
Focus indicator styles present
a11y-form-labels
Form inputs have associated labels
a11y-heading-order
Heading levels don't skip
a11y-landmark-regions
Proper landmark regions (main, nav, footer)
a11y-link-text
Descriptive link text (no "click here")
a11y-skip-link
Skip-to-content link for keyboard navigation
a11y-table-headers
Data tables have proper headers
a11y-touch-targets
Minimum 44x44px touch target sizing
a11y-video-captions
Videos have captions or transcripts
a11y-zoom-disabled
Viewport doesn't disable user zoom
Content (17 rules) - 5% weight
Rule
Description
content-word-count
Page should have 300+ words
content-reading-level
Flesch-Kincaid reading level check
content-keyword-stuffing
Detects excessive keyword repetition
content-article-links
Checks link-to-content ratio
content-broken-html
Detects malformed HTML structure
content-meta-in-body
Meta tags should be in head
content-mime-type
Validates Content-Type header
content-duplicate-description
Descriptions should be unique site-wide
content-heading-hierarchy
Proper heading hierarchy (H1>H2>H3)
content-heading-length
Headings should be 10-70 characters
content-heading-unique
Headings should be unique
content-text-html-ratio
Text-to-HTML ratio should be >10%
content-title-same-as-h1
Title and H1 should differ
content-title-pixel-width
Title pixel width for SERP display (<580px)
content-description-pixel-width
Description pixel width for SERP (<920px)
content-duplicate-exact
Detects exact duplicate content across pages
content-duplicate-near
Detects near-duplicate content via simhash
Social (9 rules) - 3% weight
Rule
Description
social-og-title
og:title meta tag
social-og-description
og:description meta tag
social-og-image
og:image with valid URL
social-og-image-size
og:image dimensions (1200x630)
social-twitter-card
twitter:card meta tag
social-og-url
og:url meta tag
social-og-url-canonical
og:url matches canonical
social-share-buttons
Social share buttons present
social-social-profiles
Social profile links present
E-E-A-T (14 rules) - 3% weight
Rule
Description
eeat-about-page
About page exists
eeat-affiliate-disclosure
Affiliate links have disclosure
eeat-author-byline
Author attribution present
eeat-author-expertise
Author credentials/bio present
eeat-citations
Links to authoritative sources
eeat-contact-page
Contact page exists
eeat-content-dates
Publication/modification dates present
eeat-disclaimers
YMYL content has disclaimers
eeat-editorial-policy
Editorial policy page exists
eeat-physical-address
Business address present
eeat-privacy-policy
Privacy policy link present
eeat-terms-of-service
Terms of service link present
eeat-trust-signals
Trust badges, reviews, certifications
eeat-ymyl-detection
YMYL content detection
URL Structure (14 rules) - 3% weight
Rule
Description
url-slug-keywords
URL slug contains keywords
url-stop-words
URL should not have stop words
url-uppercase
URLs should be lowercase
url-underscores
Use hyphens, not underscores
url-double-slash
No consecutive slashes in path
url-spaces
No spaces in URL
url-non-ascii
No non-ASCII characters in URL
url-length
URL should be under 2048 characters
url-repetitive-path
No repetitive path segments
url-parameters
Excessive query parameters
url-session-ids
No session IDs in URL
url-tracking-params
Tracking parameters should use canonical
url-internal-search
Internal search URLs should be noindexed
url-http-https-duplicate
HTTP/HTTPS versions should canonicalize
Redirects (8 rules) - 3% weight
Rule
Description
redirect-meta-refresh
No <meta http-equiv="refresh"> redirects
redirect-javascript
No JavaScript-based redirects
redirect-http-refresh
No HTTP Refresh header redirects
redirect-loop
No circular redirect chains
redirect-type
Prefer 301 over 302 for permanent moves
redirect-broken
Redirects should not lead to errors
redirect-resource
No redirects on CSS/JS/image resources
redirect-case-normalization
Redirect uppercase URLs to lowercase
Mobile (5 rules) - 2% weight
Rule
Description
mobile-font-size
Minimum 16px body text
mobile-horizontal-scroll
No horizontal scrolling
mobile-interstitials
No intrusive interstitials
mobile-viewport-width
No fixed viewport width
mobile-multiple-viewports
Single viewport meta tag
Internationalization (10 rules) - 2% weight
Rule
Description
i18n-lang-attribute
HTML lang attribute present
i18n-hreflang
Hreflang tags for multilingual sites
i18n-hreflang-return-links
Hreflang targets link back to source
i18n-hreflang-to-noindex
Hreflang should not point to noindexed pages
i18n-hreflang-to-non-canonical
Hreflang should point to canonical URLs
i18n-hreflang-to-broken
Hreflang should not point to broken URLs
i18n-hreflang-to-redirect
Hreflang should not point through redirects
i18n-hreflang-conflicting
No duplicate hreflang for same language
i18n-hreflang-lang-mismatch
Page language matches hreflang code
i18n-hreflang-multiple-methods
Use single hreflang method
HTML Validation (9 rules) - 2% weight
Rule
Description
htmlval-missing-doctype
<!DOCTYPE html> must be present
htmlval-missing-charset
<meta charset> must be in head
htmlval-invalid-head
Only metadata elements in <head>
htmlval-noscript-in-head
<noscript> should be in body
htmlval-multiple-heads
Single <head> element only
htmlval-size-limit
HTML should be under 5MB
htmlval-lorem-ipsum
No placeholder lorem ipsum text
htmlval-multiple-titles
Single <title> tag only
htmlval-multiple-descriptions
Single meta description only
AI/GEO Readiness (5 rules) - 2% weight
Rule
Description
geo-semantic-html
Uses semantic HTML elements
geo-content-structure
Proper heading hierarchy and lists
geo-ai-bot-access
AI crawlers (GPTBot, ClaudeBot) not blocked
geo-llms-txt
/llms.txt file for AI discovery
geo-schema-drift
JSON-LD matches visible content
Legal Compliance (1 rule) - 1% weight
Rule
Description
legal-cookie-consent
Cookie consent banner present
Create a seomator.toml config file with seomator init:
[project ]
name = " my-website"
domains = [" example.com" , " www.example.com" ]
[crawler ]
max_pages = 100
concurrency = 3
timeout_ms = 30000
respect_robots = true
delay_ms = 100
include = []
exclude = [" /admin/**" , " /api/**" ]
drop_query_prefixes = [" utm_" , " gclid" , " fbclid" ]
[rules ]
enable = [" *" ]
disable = [" perf-inp" ] # Supports wildcards: "core-*"
[output ]
format = " console" # console, json, html, markdown, llm
Config priority (highest to lowest):
CLI arguments
Local ./seomator.toml
Parent directory configs
Global ~/.seomator/config.toml
Built-in defaults
Format
Flag
Best For
Console
--format console
Human terminal output (default)
JSON
--format json
CI/CD, programmatic processing
HTML
--format html
Standalone reports, sharing
Markdown
--format markdown
Documentation, GitHub
LLM
--format llm
AI agents, piping to Claude
╔══════════════════════════════════════════════════════════════╗
║ SEOmator Audit Report ║
╚══════════════════════════════════════════════════════════════╝
URL: https://example.com
Score: 88/100 [A]
┌──────────────────────────┬───────┬────────┬──────────┬────────┐
│ Category │ Score │ Passed │ Warnings │ Failed │
├──────────────────────────┼───────┼────────┼──────────┼────────┤
│ Core │ 97 │ 18 │ 1 │ 0 │
│ Performance │ 85 │ 18 │ 3 │ 1 │
│ JavaScript Rendering │ 100 │ 13 │ 0 │ 0 │
│ ... │ │ │ │ │
└──────────────────────────┴───────┴────────┴──────────┴────────┘
{
"url" : " https://example.com" ,
"overallScore" : 88 ,
"categoryResults" : [
{
"categoryId" : " core" ,
"score" : 97 ,
"passCount" : 18 ,
"warnCount" : 1 ,
"failCount" : 0 ,
"results" : [... ]
}
],
"timestamp" : " 2026-01-23T16:00:00.000Z" ,
"crawledPages" : 1
}
name : SEO Audit
on :
push :
branches : [main]
pull_request :
branches : [main]
jobs :
audit :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- name : Setup Node.js
uses : actions/setup-node@v4
with :
node-version : ' 20'
- name : Install SEOmator
run : npm install -g @seomator/seo-audit
- name : Install Playwright browsers
run : npx playwright install chromium
- name : Run SEO Audit
run : seomator audit https://your-staging-url.com --format json -o seo-report.json
- name : Upload Report
uses : actions/upload-artifact@v4
with :
name : seo-report
path : seo-report.json
seo-audit :
image : node:20
script :
- npm install -g @seomator/seo-audit
- npx playwright install chromium
- seomator audit https://your-staging-url.com --format json -o seo-report.json
artifacts :
paths :
- seo-report.json
import { Auditor , createAuditor } from '@seomator/seo-audit' ;
const auditor = createAuditor ( {
categories : [ 'core' , 'security' , 'perf' ] ,
measureCwv : true ,
onCategoryComplete : ( categoryId , name , result ) => {
console . log ( `${ name } : ${ result . score } /100` ) ;
}
} ) ;
const result = await auditor . audit ( 'https://example.com' ) ;
console . log ( `Overall Score: ${ result . overallScore } ` ) ;
Use SEOmator directly in Claude Code as an AI skill for automated SEO auditing.
npx skills add seo-skills/seo-audit-skill
"Run an SEO audit on https://example.com"
"Audit https://mysite.com and tell me what to fix first"
"Check SEO health of https://example.com with 20-page crawl"
Node.js 18+ (uses native fetch API)
Playwright (for Core Web Vitals and JS rendering analysis)
After installing, run npx playwright install chromium to install the browser for CWV measurement.
For the desktop app, better-sqlite3 must be compiled for Electron's Node version:
npx electron-rebuild -f -w better-sqlite3
MIT