searchparty
v0.1.0
Published
Crawl a website and preview every page's SEO metadata and social images in a realtime dashboard.
Maintainers
Readme
searchparty
Crawl a website and preview every page's SEO metadata and social images in a realtime dashboard, as they're scraped.
bun x searchparty veraison.com.auThis crawls the site (sitemap + on-page links), starts a local dashboard, and opens it in your browser. Page cards stream in live — each shows the og:image preview, title, description, HTTP status, and an SEO score. Click any card for a full breakdown: live page render, every social image, all Open Graph / Twitter / SEO tags, and flagged issues.
Usage
searchparty <domain> [options]
--max=<n> Max pages to crawl (default 150)
--concurrency=<n> Parallel requests (default 6)
--port=<n> Dashboard port (default 4477, auto-bumps if busy)
--sitemap-only Only crawl sitemap + homepage, don't follow links
--render Render each page with a headless Chrome — full SPA DOM +
screenshots. Needs a local Chrome/Chromium (see below);
falls back to plain fetch() if none is found.
--no-open Don't auto-open the browserExamples:
searchparty example.com
searchparty https://example.com --max=50 --sitemap-only
searchparty https://example.com --render # SPA-aware + screenshotsFeatures
The dashboard is built from a plugin architecture (see below). Out of the box it ships these features:
- Live page grid (built-in) — virtualized cards stream in as pages are scraped; filter by issues / no-image / errors and search.
- Social card simulator (per-page detail) — pixel-accurate share previews for Google, X/Twitter, Facebook, LinkedIn, Slack, iMessage and Discord, each with that platform's real truncation + inline warnings.
- Image health (enricher + per-page detail) — fetches every og/twitter image and measures HTTP status, content-type, byte size and real pixel dimensions, flagging undersized / wrong-aspect / oversized social images.
- Site audit (tab) — cross-page findings: duplicate titles/descriptions/ H1s, missing/conflicting canonicals, redirects, error pages, noindex pages, thin content, grouped by severity.
- Export & reports (tab) — download the crawl as CSV, JSON, or a
self-contained styled HTML audit report (
/api/export?format=…). - History & crawl diff (tab) — every completed crawl is persisted to a
SQLite db at
~/.searchparty/history.db; compare any two runs to see added / removed / changed pages. - AI meta suggestions (per-page detail, optional) — improved title, meta
description and og:image alt text via Claude. Requires
ANTHROPIC_API_KEY. - Lighthouse / Core Web Vitals (per-page detail, optional) — on-demand
Lighthouse audit (performance/SEO/accessibility/best-practices + LCP/CLS/TBT).
Requires a local Chrome and the optional
lighthouse+chrome-launcherpackages. - Headless render (
--render) — capture the post-JS DOM and a screenshot per page so SPAs and JS-injected meta tags are scraped correctly. - Live page proxy (built-in) —
/api/proxyre-serves same-host pages with a<base>tag and framebusters stripped so previews can be framed.
Optional requirements (graceful degradation)
These features degrade cleanly — the UI shows an "unavailable" state, the server never crashes:
- Local Chrome / Chromium — needed for
--render(screenshots + SPA DOM) and for the Lighthouse audit. Auto-detected at common install paths, or setPUPPETEER_EXECUTABLE_PATH(orCHROME_PATHfor Lighthouse). Without it,--renderfalls back tofetch()and Lighthouse returns{available:false}. ANTHROPIC_API_KEY— enables AI meta suggestions. Unset → the AI panel shows a setup hint instead of erroring.lighthouse+chrome-launcher— optional npm deps. Not installed → Lighthouse returns{available:false}.
Architecture
searchparty is a plugin system. The foundation (crawler + server + dashboard shell) is fixed; every feature is a self-contained file that's discovered and loaded dynamically — no central registry to edit.
- Enrichers —
src/enrichers/*.ts, eachexport defaultan(ctx: EnricherCtx) => Promise<void>. They run after base SEO extraction and mutatectx.pagein place to add fields (declared additively viadeclare module "../types.ts"). Loaded byloadEnrichers()insrc/enrich.ts. Enrichers must never throw — a misbehaving one cannot break the crawl. - Routes —
src/routes/*.ts, each exportingroute(ordefault) of typeRoute({ method, path, handler, init? }).pathmay end in/*for prefix matching. The optionalinit(ctx)hook runs once at server startup with the liveRouteCtx— use it to subscribe to crawler events (e.g. persist on"done"). Loaded byloadRoutes()insrc/server.ts. - UI features —
ui/src/features/<name>/. Drop atab.tsx(export const tab: FeatureTab) to add a top-level dashboard tab, and/or adetail.tsx(export const detail: FeatureDetail) to append a section to the per-page Sheet. Collected viaimport.meta.globinui/src/features/registry.ts.
To add a feature: drop the file(s) in the right directory — they're picked up automatically. To remove one: delete the file.
How it works
- Crawler (
src/crawler.ts) — BFS over same-host links, seeded fromsitemap.xml. Extracts title, description, canonical, robots, h1, Open Graph, Twitter cards, favicon, and all preview images. Flags common SEO issues, runs enrichers, then emits apageevent. - Server (
src/server.ts) —Bun.servethat streams crawl events over SSE (/api/events), serves a full state snapshot (/api/state), serves the built dashboard, proxies pages (/api/proxy), serves screenshots (/api/screenshot), and mounts all plugin routes. - Renderer (
src/render.ts) — optional headless Chrome (puppeteer-core), reused across pages, only when--renderis set and a browser is found. - Dashboard (
ui/) — Vite + React + Tailwind v4 + coss ui.
Development
bun install # backend deps
bun run build:ui # build the dashboard (ui/ -> ui/dist)
bun run index.ts veraison.com.au # run locally
# Live UI dev (run the CLI on :4477 in one terminal, then):
bun run dev:ui # vite dev server, proxies /api to the CLITo make the searchparty command available globally for local use:
bun linkPublishing
npm version patch
npm publish --access public # prepublishOnly builds the UI