@agent-qofeno/unbuild
v1.5.2
Published
Deconstruct a rendered website into evidence-backed UI, UX, design-system, responsive and motion artifacts for AI coding agents.
Maintainers
Keywords
Readme
unbuild
Deconstruct a rendered website into evidence-backed UI, UX, design-system, responsive and motion artifacts for AI coding agents.
unbuild renders a public website in Chromium and unbuilds what the browser can actually observe: layout, typography, colors, spacing, radii, shadows, components, responsive behavior, motion evidence, links, controls, images, fonts, and screenshots.
The result is a local, structured reference that can be inspected by a developer or handed directly to OpenCode, Claude Code, Codex, Gemini CLI, Cursor, and other coding agents.
Cross-platform support
unbuild is a Node.js CLI with platform-neutral extraction code.
- Windows, macOS, Linux: use Playwright's managed Chromium or an installed Chromium/Chrome/Edge binary.
- Linux ARM64/ARMv7 and other architectures: use a compatible installed Chromium binary with
--browserwhen Playwright's managed browser is unavailable. - Android / Termux: unbuild can launch the native Termux Chromium package directly when it is installed, or connect to any Chromium-compatible browser with
--cdp. - Other Unix-like environments: use
--browseror--cdpwhen a managed Playwright browser is unavailable.
The npm package installs the Playwright Chromium browser during package installation on supported desktop platforms. If browser installation is intentionally skipped or unavailable, use --browser with an installed Chromium/Chrome/Edge binary or --cdp with an existing Chromium browser. On Android / Termux, unbuild automatically uses the native Termux Chromium executable when present and applies the Android-compatible Playwright host workaround. The CLI keeps browser initialization lazy so unbuild --help works on Android.
Install and run
Install locally with npm
For a normal project dependency, install the package locally:
npm install @agent-qofeno/unbuildThen run the local CLI with:
npx unbuild https://www.example.comThe package exposes the unbuild executable through npm's local node_modules/.bin directory.
Recommended: run directly with npx
You do not need to install the CLI globally:
npx @agent-qofeno/unbuild https://www.example.comThis is the recommended way to try or run unbuild.
Install globally: use the unbuild command directly
If you want unbuild available as a normal terminal command on Windows, macOS, or Linux, install it globally:
npm install -g @agent-qofeno/unbuild
unbuild https://www.example.comImportant: local npm install does not add unbuild to your terminal PATH
This:
npm install @agent-qofeno/unbuildinstalls the package locally in the current project. It does not make the unbuild executable globally available, so typing unbuild --help directly in a Windows Command Prompt will not work from that installation.
After a local install, use either:
npx unbuild --help
``
or the local executable explicitly:
```bash
.\\node_modules\\.bin\\unbuild.cmd --helpIf you want to type unbuild --help directly, use the global installation command above.
The package installs the matching Playwright Chromium browser as part of npm installation on supported desktop platforms, so normal npx and global-install flows do not require a separate npx playwright install step.
Usage
unbuild <url> [options]
Options:
-o, --output <dir> Output directory (default: ./unbuild-output)
--timeout <ms> Browser timeout
--pages <n> Maximum same-origin pages
--browser <path> Use an installed Chromium/Chrome/Edge executable
--cdp <url> Connect to an existing Chromium browser over CDP
--no-headless Show Chromium while analyzing
-h, --help Show helpExamples:
npx @agent-qofeno/unbuild https://www.turbostarter.dev -o ./unbuild-outputWith an installed browser:
unbuild https://www.example.com --browser /path/to/chromiumWith a CDP browser:
unbuild https://www.example.com --cdp http://127.0.0.1:9222Android / Termux
Android needs a native browser executable because Playwright's bundled desktop Chromium is not an Android browser. unbuild now supports the native Chromium package shipped for Termux.
Install it once:
pkg install x11-repo
pkg install chromiumThen run unbuild normally; it automatically detects /data/data/com.termux/files/usr/bin/chromium-browser:
unbuild https://www.example.comYou can also provide the executable explicitly:
unbuild https://www.example.com --browser /data/data/com.termux/files/usr/bin/chromium-browserIf you already have a Chromium browser exposing CDP, use:
unbuild https://www.example.com --cdp http://127.0.0.1:9222A CDP connection only works when a browser is actually listening on that endpoint. ECONNREFUSED 127.0.0.1:9222 means nothing is listening there; unbuild cannot create an Android Chrome CDP endpoint by itself. For native Termux Chromium, use the automatic mode above.
What it produces
A typical run produces:
unbuild-output/
├── README.md
├── AI.md
├── DESIGN.md
├── evidence/
│ ├── pages.json # discovered same-origin URLs, in crawl order
│ ├── all-pages.json # every page's full extracted evidence, combined
│ └── <page>-runtime.json # per-page browser console messages and page errors
├── pages/
│ ├── <page>.json # per-page computed geometry/style/DOM evidence
│ └── <page>.html # per-page rendered HTML snapshot
├── responsive/
│ ├── desktop-<page>.json
│ ├── tablet-<page>.json
│ └── mobile-<page>.json
├── screenshots/
│ ├── desktop/<page>.png
│ ├── tablet/<page>.png
│ └── mobile/<page>.png
├── tokens/
│ └── tokens.json
├── components/
│ ├── components.json # aggregated component/landmark/button inventory
│ ├── <page>-screenshots.json # manifest of cropped component screenshots below
│ └── screenshots/*.png # cropped screenshots of header/nav/main/footer/etc.
├── assets/
│ ├── manifest.json
│ ├── images/
│ ├── icons/
│ ├── fonts/
│ ├── styles/
│ └── media/
├── styles/
│ └── inventory.json
├── accessibility/
│ ├── summary.json # aggregated axe pass/violation counts per page+viewport
│ ├── axe-<viewport>-<page>.json # full axe results for one page at one viewport
│ ├── desktop-<page>.yml # ARIA/accessibility-tree snapshot (page-load viewport)
│ └── <viewport>-<page>.yml # ARIA/accessibility-tree snapshot per viewport
├── motion/
│ └── summary.json
└── ux/
├── summary.json
├── interaction-states.json # hover/focus state deltas actually observed
└── states/*.png # screenshots of those changed hover/focus states is the filesystem-safe slug derived from that page's URL path (e.g. /docs/setup → docs-setup, / → home). If two different pages would slug to the same name, later ones get -2, -3, etc. appended — always read the actual filenames present in pages/, evidence/pages.json, or the "Evidence files" line for that page in AI.md/DESIGN.md rather than re-deriving the slug yourself.
The exact files may grow as extraction capabilities expand.
Evidence hierarchy
When reconstructing a site from an unbuild package:
- Screenshots are the visual source of truth.
- Responsive evidence describes observed viewport behavior.
- JSON evidence contains measured browser values.
- Markdown reports explain the evidence and reconstruction intent.
- Inference should only be used when the evidence does not directly answer a question.
Do not treat a frequency count as proof of a design token. Repeated values are evidence of reuse, not proof of the original implementation.
What unbuild observes
Visual system
- rendered colors
- font families and font metadata exposed by the browser
- font sizes
- border radii
- spacing values
- shadows
- document and content dimensions
- screenshots at desktop, tablet, and mobile viewports
Structure
- common semantic HTML elements
- links and external links
- form controls
- navigation/header/footer/form/dialog evidence
- classes and representative text samples
- document language metadata
- image URLs, dimensions, and alt text
- browser-delivered image, icon, font, stylesheet, media, and manifest assets saved locally under
assets/ - CSS-referenced assets discovered from captured stylesheets, including
@font-face, background images, cursors, and imported CSS - asset manifest mapping every captured resource to its source URL and page usage
- parsed stylesheet inventory with selectors, media queries, keyframes, custom properties, font-face declarations, and referenced assets
- automated axe accessibility findings for each captured viewport
- heading hierarchy, component geometry, navigation structure, forms, focus evidence, and CSS custom properties
Responsive behavior
Each configured viewport is rendered independently. The output records measurements and screenshots for:
- desktop: 1440×1000
- tablet: 1024×1000
- mobile: 390×844
These are observation points, not claims about the site's original breakpoint values.
Motion
unbuild records observable CSS transition and animation metadata exposed by computed styles and the Web Animations API. Changed hover/focus states are also captured as element screenshots when possible.
Assets
The browser network is observed while pages render. Image, icon, font, stylesheet, media, and manifest responses are captured into assets/ when they are available and within the safety/size budget. assets/manifest.json records the original URL, local path, content type, size, status, and pages where the resource was observed. It does not claim to recover every JavaScript-driven interaction or animation.
What unbuild does not do
unbuild intentionally does not attempt to:
- recover private source repositories
- bypass authentication
- access databases or APIs as an authenticated user
- discover secrets
- reproduce server-side business logic
- claim that inferred implementation details are exact
- bypass a site's access controls
- guarantee pixel identity across machines, browsers, fonts, or dynamic content
Only analyze sites you are authorized to analyze and respect the target site's terms, access controls, robots policies, and applicable law.
Security
unbuild is a browser-based network client. The URL you provide is loaded by a local Chromium process, and the target page can cause Chromium to make additional network requests for resources such as images, fonts, scripts, stylesheets, and APIs.
This matters because arbitrary URL fetching can become an SSRF and local-network access risk.
For that reason:
- Do not run unbuild against untrusted URLs in a privileged network environment.
- Do not assume the browser is a security sandbox.
- Do not provide credentials, client certificates, or private network access to the browser.
- Run unbuild inside a container or isolated environment when analyzing untrusted targets.
- Treat generated output as untrusted data; pages can contain attacker-controlled text, URLs, filenames, and metadata.
- Never execute generated files or agent instructions without reviewing them.
See SECURITY.md for the threat model and vulnerability reporting process.
Development
Requirements:
- Node.js 22.14+
- npm
- Chromium installed by the Playwright browser dependency, or an installed Chromium-compatible browser
Install dependencies:
npm installIf browser installation is intentionally skipped, install Chromium separately with npx playwright install chromium, or use --browser / --cdp.
Verify the repository:
npm run check
npm testBuild the package:
npm run buildWorking with coding agents
The repository includes AGENTS.md with project-specific instructions for OpenCode and other agents.
The intended workflow is:
website
↓
Chromium
↓
rendered evidence
↓
structured JSON + screenshots
↓
AI.md / DESIGN.md
↓
coding agent
↓
new implementationAn agent should reconstruct the design language and observable interaction model, not copy the target site's proprietary implementation or content.
Releases
Releases use Conventional Commits and semantic-release for npm versioning and publishing. The npm registry is the distribution source of truth.
Examples:
feat: add breakpoint discovery
fix: handle pages with delayed fonts
docs: improve security guidance
refactor: simplify extraction pipeline
test: cover responsive evidenceAutomated releases use npm Trusted Publishing (OIDC), so no long-lived npm publish token is stored in the repository.
See CONTRIBUTING.md for release and contribution rules.
Contributing
Bug fixes, tests, extraction improvements, documentation, and security hardening are welcome.
Please read CONTRIBUTING.md before opening an issue or pull request.
License
MIT. See LICENSE.
