Measure the thread of your site's destiny.
Open-source web audit tool. Drop a URL — receive a measured verdict on SEO, performance, accessibility, and locale-specific best practices.
Named after Lachesis, the Greek goddess of the Moirai (Fates) who measures the thread of mortal life. Klotho spins it, Atropos cuts it. Lachesis decides how long it runs.
Built by CyberDemigods.
- Next.js 16 (App Router, React 19, Turbopack)
- TypeScript
- Tailwind CSS 4
- cheerio for server-side HTML parsing
- Playwright + axe-core for headless rendering, real Web Vitals, and accessibility scans
- Google PageSpeed Insights API for Core Web Vitals + Lighthouse scores (optional)
- Local vision-language model (LM Studio with Qwen3-VL or similar) for visual design evaluation
| Module | Status | Checks |
|---|---|---|
on-page |
done | Title, meta description, H1/headings, canonical, robots, OG, Twitter, JSON-LD, alt coverage, links, hreflang, lang/content language match |
pagespeed |
done | Lighthouse scores (Performance, A11y, Best Practices, SEO) + Core Web Vitals (LCP, INP, CLS, TTFB, FCP) via Google PSI |
image-perf |
done | Server-side fetch of image samples — total weight, average load time, slowest/heaviest, lazy-loading and modern-format coverage |
headless |
done | Real Chromium render via Playwright — Web Vitals (LCP/FCP/CLS), layout signals (overflow, underfilled-page, footer position, tiny fonts), axe-core a11y full scan, screenshot |
visual |
done | LM Studio vision-language model rates the screenshot across composition, hierarchy, professionalism, readability, typography, and color |
locale |
done | Polish: encoding correctness, RODO mention, cookie consent, NIP/REGON/KRS detection, hreflang variants |
The orchestrator runs modules in parallel where possible and aggregates findings into a weighted overall score across six categories: SEO, Performance, Accessibility, Best Practices, Content, Locale.
app/
├── api/scan/route.ts Audit API endpoint (POST + GET)
├── components/
│ ├── scan-form.tsx URL input form (client component)
│ └── report-view.tsx Renders a ScanReport
├── layout.tsx
├── page.tsx Landing page
└── globals.css
lib/audit/
├── index.ts Orchestrator: runs modules in parallel
├── types.ts Shared types (AuditFinding, AuditSection, ScanReport)
├── scoring.ts Per-category aggregation + weighted overall score
├── on-page.ts cheerio-based HTML audit
├── pagespeed.ts Google PageSpeed Insights API client
├── headless.ts Playwright + axe-core (stub — see file)
└── locale.ts Locale-specific checks (currently Polish)
git clone https://github.com/CyberDemigods/lachesis
cd lachesis
npm install
cp .env.example .env.local # optional — add PageSpeed API key for higher rate limits
npm run devOpen http://localhost:3000.
The audit is accessible programmatically:
# GET (query params)
curl 'http://localhost:3000/api/scan?url=https://example.com&skipPageSpeed=1'
# POST (JSON body)
curl -X POST http://localhost:3000/api/scan \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com"}'Response: a ScanReport (see lib/audit/types.ts) with
overall score, per-category scores, and findings grouped by module.
| Variable | Required | Purpose |
|---|---|---|
PAGESPEED_API_KEY |
optional | Google PageSpeed Insights key. Without it, requests are rate-limited. |
LM_STUDIO_URL |
optional | Base URL of an OpenAI-compatible API (e.g. LM Studio). Default http://192.168.0.38:1234. |
VISION_MODEL |
optional | Identifier of an instruction-tuned vision-language model (e.g. qwen3-vl-4b-instruct). |
Each finding has a severity (pass / warn / fail / info). Findings map
to one or more categories (lib/audit/scoring.ts). A category score is the
average of its findings (pass=1, warn=0.5, fail=0, info is excluded). The
overall score is a weighted average of category scores:
| Category | Weight |
|---|---|
| SEO | 27% |
| Performance | 22% |
| Accessibility | 18% |
| Best Practices | 13% |
| Visual | 10% |
| Content | 5% |
| Locale | 5% |
Findings are also weighted (Lighthouse-style): critical = 5, major = 3, medium = 2, minor = 1 (default). Weight comes from the weight field on each AuditFinding.
- On-page audit (cheerio)
- PageSpeed Insights integration
- Image performance module
- Locale-aware checks (Polish)
- Headless Playwright + axe-core
- Visual evaluation via local vision-language model
- Side-by-side comparison mode — designed to integrate with
web-transformation - Production deployment (Vercel Sandbox or external Playwright worker)
- Persistent scan history (Postgres / SQLite)
- PDF export of audit reports
- More locales (DE, ES, FR — locale-specific privacy regulations and structured data)
- CLI:
npx lachesis https://example.com - GitHub Action for PR-time SEO regression checks
Issues and PRs welcome. The audit modules are intentionally decoupled — adding
a new check is usually a single function in the relevant module plus a category
mapping in lib/audit/scoring.ts.
MIT — see LICENSE.
Forged by CyberDemigods.