Skip to content

Repository files navigation

Occhio

Occhio audits a web page's usability the way a reviewer would: it takes a screenshot, reads the markup alongside it, and scores the page against Nielsen's 10 usability heuristics. The output is a scored report — issues ranked by severity, annotated on the screenshot, with an accessibility pass and copy and conversion suggestions.

Scores are weighted by page type. A landing page is graded hardest on whether its value proposition lands; a checkout flow is graded hardest on error prevention and system status. The page category is detected during analysis, not configured up front. See lib/scoring.ts for the weights.

How it works

  1. POST /api/analyze accepts one or more URLs and creates an analyses row.
  2. A screenshot is captured through ScreenshotAPI, and readable text and structure are extracted from the page HTML (lib/html-extractor.ts).
  3. Both go to a vision model — GPT-5.1 on the free tier, Claude Opus 4 on the paid tier, over identical inputs (lib/ai-analysis.ts, prompts in lib/prompts.ts).
  4. Issues come back with coordinates, so they can be drawn onto the screenshot as numbered markers (lib/annotations.ts).
  5. Severity-weighted deductions produce a 0–100 score (lib/scoring.ts).
  6. Paid reports are rendered to PDF (lib/pdf-generator.tsx) and emailed via Resend.

Analysis runs in the background after the request returns, using waitUntil() so the serverless invocation stays alive on Vercel.

Stack

Next.js 14 (App Router) · TypeScript · Tailwind · Supabase (Postgres + Storage) · Stripe · Resend · @react-pdf/renderer

Running it locally

npm install
cp env.example .env.local
npm run dev

You need accounts with Supabase, OpenAI, Anthropic, Stripe, ScreenshotAPI, and Resend; env.example lists every variable and where it comes from. The free tier alone needs only Supabase, OpenAI, and ScreenshotAPI — the Stripe and Resend paths are for paid reports.

Database

Against a fresh Supabase project, run supabase/schema.sql in the SQL editor, then apply the files in supabase/migrations/ in filename order. With the Supabase CLI:

supabase db push

Storage

Create two private buckets: screenshots and reports.

Layout

app/
  api/         analyze, results, Stripe checkout and webhooks, email capture
  results/     report view
  pro/         paid tier landing
lib/
  ai-analysis  model calls and response parsing
  prompts      heuristic prompt construction
  scoring      severity deductions and category weighting
  screenshot   capture via ScreenshotAPI
  annotations  numbered issue markers drawn onto screenshots
  html-extractor  text and structure extraction for model context
  pdf-generator   report rendering
supabase/      schema and migrations
types/         shared types for analyses, issues, audits

Rate limiting

DAILY_AUDIT_LIMIT caps total audits per day and DAILY_IP_AUDIT_LIMIT caps them per client IP. Both are read from the environment, so they can be tuned per deployment.

License

MIT — see LICENSE.

About

Heuristic UX audits for any URL: screenshots a page, scores it against Nielsen's 10 usability heuristics, and returns issues annotated on the screenshot

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages