{"id":51724351,"url":"https://github.com/codingstark-dev/decant","last_synced_at":"2026-07-17T16:38:37.645Z","repository":{"id":365530003,"uuid":"1272505093","full_name":"codingstark-dev/decant","owner":"codingstark-dev","description":"decant is an AI-native website mirroring tool written in Rust. It downloads a site's complete UI layer — HTML, CSS, JS, web fonts, and images — rewrites all references to relative local paths so the capture works offline, and outputs three machine-readable artifacts","archived":false,"fork":false,"pushed_at":"2026-06-22T19:34:44.000Z","size":4379,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-17T16:38:16.955Z","etag":null,"topics":["ai-tools","clone","clone-website","httrack","rust","ui-design","uiclone"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codingstark-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-17T17:12:01.000Z","updated_at":"2026-07-12T00:28:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/codingstark-dev/decant","commit_stats":null,"previous_names":["codingstark-dev/decant"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/codingstark-dev/decant","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingstark-dev%2Fdecant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingstark-dev%2Fdecant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingstark-dev%2Fdecant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingstark-dev%2Fdecant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codingstark-dev","download_url":"https://codeload.github.com/codingstark-dev/decant/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codingstark-dev%2Fdecant/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35588703,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-17T02:00:06.162Z","response_time":116,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","clone","clone-website","httrack","rust","ui-design","uiclone"],"created_at":"2026-07-17T16:38:37.124Z","updated_at":"2026-07-17T16:38:37.621Z","avatar_url":"https://github.com/codingstark-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"./logo.png\" alt=\"decant logo\" width=\"120\" /\u003e\n\n# decant\n\n\u003e **Mirror websites for AI.** Extract HTML, CSS, JS, fonts, screenshots, and design tokens into a structured capture that AI agents can understand and reproduce.\n\n[![Rust](https://img.shields.io/badge/rust-1.88%2B-orange)](https://www.rust-lang.org)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Crates](https://img.shields.io/badge/crates.io-decant-green)](https://crates.io/crates/decant)\n\n\u003c/div\u003e\n\n![decant TUI Dashboard](./decant-image.png)\n\n---\n\n## What is decant?\n\n`decant` is an AI-native website mirroring tool written in Rust. It downloads a site's complete UI layer — HTML, CSS, JS, web fonts, and images — rewrites all references to relative local paths so the capture works offline, and outputs three machine-readable artifacts:\n\n| File | Purpose |\n|---|---|\n| `context.md` | Token-budgeted LLM primer — paste this into your prompt first |\n| `design-tokens.json` | Full color palette, type scale, spacing, breakpoints, shadows |\n| `manifest.json` | Page tree, component regions, and asset catalog |\n| `repair-hints.json` | Clone health, failed asset categories, and AI repair actions |\n\nWhen used with `--render chrome`, decant also captures **browser-observed runtime resources** and **multi-viewport screenshots** (mobile, tablet, desktop) so an AI agent has a visual ground truth to compare against. `decant verify` then compares the live site and local preview screenshots and writes a machine-readable repair report.\n\n---\n\n## Features\n\n- **Static Mirroring** — extremely fast HTML/CSS/JS/asset crawl without a browser\n- **Headless Chrome** — full JavaScript rendering (`--render chrome`), runtime network resource capture, cookie injection, multi-viewport screenshots\n- **Lightpanda** — ultra-fast (~11× faster, ~16× less RAM than Chrome) JS rendering (`--render lightpanda`) — no screenshots, pure DOM extraction\n- **Design Token Extraction** — colors, font families, spacing scale, breakpoints, radii, shadows from every stylesheet\n- **URL Rewriting** — all absolute and root-relative references rewritten to relative local paths for offline use, with query-distinct assets saved separately\n- **JS Chunk Discovery** — scans compiled JS bundles to find and download dynamically-imported chunks (Vite, webpack, etc.)\n- **Cookie \u0026 Header Auth** — inline cookie string (`--cookies`) or Netscape cookie jar (`--cookie-file`) + custom request headers (`--header`)\n- **Selective Capture** — choose exactly which aspects to collect via `--capture html,css,js,fonts,screenshots,tokens,context`\n- **Multi-Viewport Screenshots** — `mobile` (390×844), `tablet` (768×1024), `desktop` (1440×900)\n- **TUI Dashboard** — real-time crawl progress with a ratatui terminal UI\n- **Offline Preview** — serve any capture directory locally with `decant serve`\n- **Visual Verification** — compare live/local screenshots with `decant verify`\n- **Repair Hints** — every clone writes `repair-hints.json` so agents know whether blocked, missing, malformed, or retryable assets need follow-up\n- **robots.txt** — respected by default; bypass with `--ignore-robots`\n\n---\n\n## Installation\n\n### Option 1 — Cargo (recommended)\n\n```bash\n# Static crawl only (no browser dependency — fastest install)\ncargo install decant\n\n# With headless-browser support (Chrome + Lightpanda)\ncargo install decant --features render\n```\n\nAfter install, `decant` is on your `$PATH` immediately.\n\n### Option 2 — npm / npx\n\n```bash\n# Install globally\nnpm install -g decant-cli\n\n# Or run without installing (one-shot)\nnpx decant-cli clone https://example.com --output ./capture\n```\n\n### Option 3 — curl (Linux / macOS)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/codingstark-dev/decant/main/install.sh | sh\n```\n\n### Option 4 — Build from source\n\n```bash\ngit clone https://github.com/codingstark-dev/decant\ncd decant\n\n# Static crawl only\ncargo build --release\n\n# With headless-browser support\ncargo build --release --features render\n\n# Add to PATH\nexport PATH=\"$PWD/target/release:$PATH\"\n```\n\n### Requirements\n\n- **Chrome/Chromium** — required only when using `--render chrome`\n- **Lightpanda** — required only when using `--render lightpanda`; install from [lightpanda.io](https://lightpanda.io)\n\n---\n\n## 🤖 AI Agent Skill\n\ndecant ships a **`SKILL.md`** — a structured instruction file that teaches any AI coding assistant (Claude code, antigravity, codex, opencode, etc.) how to use decant autonomously, without you having to explain it.\n\n### Install the skill globally (all projects)\n\n```bash\n# Using the skills CLI\nnpx skills add codingstark-dev/decant --skill decant -g\n```\n\n### Install manually\n\nCopy [`SKILL.md`](https://raw.githubusercontent.com/codingstark-dev/decant/main/SKILL.md) into your project's `.agents/skills/decant/` directory:\n\n```bash\nmkdir -p .agents/skills/decant\ncurl -fsSL https://raw.githubusercontent.com/codingstark-dev/decant/main/SKILL.md \\\n  -o .agents/skills/decant/SKILL.md\n```\n\n### What the skill teaches AI agents\n\nOnce installed, your AI assistant will automatically know how to:\n\n| Task | Command it will use |\n|------|---------------------|\n| Clone a website statically | `decant clone \u003cURL\u003e --output ./site` |\n| Clone an SPA with Chrome | `decant clone \u003cURL\u003e --render chrome` |\n| Clone with authentication | `decant clone \u003cURL\u003e --cookies \"session=abc\"` |\n| Deep crawl multiple pages | `decant clone \u003cURL\u003e --depth 2` |\n| Extract design tokens | `decant tokens ./site` |\n| Serve a capture locally | `decant serve ./site --port 8080` |\n| Serve without JS (SPA fix) | `decant serve ./site --noscript` |\n| Compare live vs local | `decant verify \u003cLIVE_URL\u003e http://127.0.0.1:8080` |\n| Inspect repair guidance | `cat ./site/repair-hints.json` |\n\n---\n\n\n## Quick Start\n\n### 1. Static clone (fast, no browser)\n\n```bash\ndecant clone https://example.com --output ./example-capture\n```\n\n### 2. Chrome clone with screenshots\n\n```bash\ndecant clone https://example.com \\\n  --render chrome \\\n  --screenshots mobile,tablet,desktop \\\n  --output ./example-chrome\n```\n\nRuntime capture is `auto` for Chrome. Use `--runtime-capture on` when you want Decant to fail clearly unless Chrome runtime capture is available:\n\n```bash\ndecant clone https://example.com \\\n  --render chrome \\\n  --runtime-capture on \\\n  --output ./example-chrome\n```\n\nAfter the clone, check the native repair artifact:\n\n```bash\njq . ./example-chrome/repair-hints.json\n```\n\nIf `status` is `needs_repair`, use the listed issue categories before deciding the clone is visually wrong. For example, `malformed_css_url` means Decant's URL rewriting needs a parser fix; `blocked_asset` means rerun with cookies or headers; `third_party_optional` means compare screenshots before treating it as harmless.\n\nServe and verify the capture:\n\n```bash\ndecant serve ./example-chrome --port 8080 --noscript\ndecant verify https://example.com http://127.0.0.1:8080 \\\n  --viewports desktop \\\n  --output ./example-chrome/verify-report.json \\\n  --screenshots-dir ./example-chrome/verify-screenshots\n```\n\n`verify-report.json` contains `status: \"match\"` or `status: \"needs_repair\"`, per-viewport similarity scores, live/local screenshot paths, and AI next steps.\n\n### 3. Lightpanda clone (lightweight JS, no screenshots)\n\n```bash\ndecant clone https://spa.example.com \\\n  --render lightpanda \\\n  --output ./example-lp\n```\n\n### 4. Authenticated clone behind a session cookie\n\n```bash\ndecant clone https://app.example.com \\\n  --cookies \"session=abc123; csrf=xyz789\" \\\n  --header \"Authorization: Bearer eyJhbGciOi...\" \\\n  --output ./auth-capture\n```\n\n### 5. Selective capture (HTML + screenshots only, skip JS/fonts)\n\n```bash\ndecant clone https://example.com \\\n  --render chrome \\\n  --capture html,screenshots \\\n  --output ./visual-only\n```\n\n### 6. Serve a captured site locally\n\n```bash\n# Standard serve\ndecant serve ./example-capture --port 8080\n\n# SPA captures (Next.js / React) — strip scripts to prevent client-side errors\ndecant serve ./example-capture --port 8080 --noscript\n# Open http://localhost:8080\n```\n\n\n\n## Output Structure\n\n```\n./output-dir/\n├── index.html               # Rewritten HTML (relative links)\n├── about/\n│   └── index.html           # Nested pages follow URL structure\n├── assets/\n│   ├── app-71RbDVbK.css     # Stylesheets with rewritten font/image references\n│   ├── index-B8uUuc7f.js    # JS entry chunk\n│   └── chunk-XYZ.js         # Dynamically discovered code-split chunks\n├── screenshots/\n│   ├── index/\n│   │   ├── mobile.png       # 390×844 — iPhone 14 viewport\n│   │   ├── tablet.png       # 768×1024 — iPad viewport\n│   │   └── desktop.png      # 1440×900 — laptop viewport\n│   └── about/\n│       └── ...\n├── context.md               # AI-native LLM primer (start here)\n├── design-tokens.json       # Full design system tokens\n├── manifest.json            # Page tree + asset catalog\n└── repair-hints.json        # Clone health + AI repair actions\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eExample: context.md (Click to expand)\u003c/summary\u003e\n\n```markdown\n# decant capture — context.md\n\n\u003e Read this file first. It is a token-budgeted primer.\n\u003e Then consult `design-tokens.json` and `manifest.json` for full detail.\n\n## Overview\n\n- **Seed URL**: https://example.com/\n- **Captured at**: 2026-06-16 12:56:22 UTC\n- **Render mode**: rendered\n- **Pages captured**: 1\n- **Assets captured**: 23\n- **Total size**: 2.1 MB\n\n## Pages\n\n- **/** → `index.html`\n  - Title: Example Site\n  - Regions: header, nav, main, footer, hero, testimonial\n\n## Captured Screenshots\n\n- `screenshots/index/mobile.png`\n- `screenshots/index/tablet.png`\n- `screenshots/index/desktop.png`\n\n## Key Design Tokens\n\n### Colors\nPalette: `#0b0b0c` `#ffffff` `#000000` `#6366f1` `#e0e7ff`\n\n### Spacing\n`2px` `4px` `8px` `12px` `16px` `24px` `32px` `48px`\n\n### Breakpoints\n640px, 768px, 1024px, 1280px\n\n## How to Use This Capture\n1. **You are here** — this file orients you without burning context.\n2. **`design-tokens.json`** — full color palette, type scale, spacing, radii, shadows, breakpoints. Translate into your target stack (Tailwind config / CSS custom properties / design system tokens).\n3. **`manifest.json`** — page tree and component region breakdown. Build one component per listed region.\n4. **Raw HTML/CSS files** — open only when you need exact markup or a specific class name. Reproduce structure and styling approach, not class names verbatim.\n5. **`screenshots/`** — visual ground truth. Compare your output against these images at matching breakpoints.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eExample: design-tokens.json (Click to expand)\u003c/summary\u003e\n\n```json\n{\n  \"schemaVersion\": \"1.0\",\n  \"source\": \"https://example.com/\",\n  \"capturedAt\": \"2026-06-16T12:56:01.537658Z\",\n  \"colors\": {\n    \"swatches\": [\n      \"#fff\",\n      \"#000\",\n      \"#0b0b0c\",\n      \"#6366f1\",\n      \"#e0e7ff\"\n    ],\n    \"byUsage\": {}\n  },\n  \"typography\": {\n    \"fontFamilies\": [\"Inter\", \"sans-serif\"],\n    \"scale\": [\"12px\", \"14px\", \"16px\", \"20px\", \"24px\", \"32px\", \"48px\"],\n    \"lineHeights\": [\"1.2\", \"1.5\"],\n    \"fontWeights\": [\"400\", \"500\", \"700\"]\n  },\n  \"spacing\": [2.0, 4.0, 8.0, 12.0, 16.0, 24.0, 32.0, 48.0],\n  \"breakpoints\": [640, 768, 1024, 1280],\n  \"radii\": [\"4px\", \"8px\", \"12px\", \"9999px\"],\n  \"shadows\": [\"0 1px 2px 0 rgba(0, 0, 0, 0.05)\", \"0 4px 6px -1px rgba(0, 0, 0, 0.1)\"]\n}\n```\n\n\u003c/details\u003e\n\n---\n\n## CLI Reference\n\n### `decant clone \u003cURL\u003e [OPTIONS]`\n\n| Option | Default | Description |\n|---|---|---|\n| `--output \u003cDIR\u003e` | `\u003chostname\u003e` | Output directory |\n| `--depth \u003cN\u003e` | `0` | Link-follow recursion depth (0 = single page) |\n| `--render \u003cchrome\\|lightpanda\u003e` | *(off)* | Enable JS rendering via headless browser |\n| `--runtime-capture \u003cauto\\|on\\|off\u003e` | `auto` | Capture browser-observed static resources when rendering with Chrome |\n| `--screenshots \u003cVIEWPORTS\u003e` | `mobile,tablet,desktop` | Comma list of viewports (requires `--render chrome`) |\n| `--no-screenshots` | false | Disable screenshots even with `--render chrome` |\n| `--capture \u003cASPECTS\u003e` | `html,css,js,fonts,images,tokens,context` | Comma list: html, css, js, fonts, images, screenshots, tokens, context |\n| `--cookies \u003cSTRING\u003e` | — | Inline cookie: `\"name=val; name2=val2\"` |\n| `--cookie-file \u003cPATH\u003e` | — | Netscape cookie jar file path |\n| `--header \u003cKEY:VALUE\u003e` | — | Extra request header (repeatable) |\n| `--user-agent \u003cSTRING\u003e` | decant/\u003cversion\u003e | Override the User-Agent header |\n| `--concurrency \u003cN\u003e` | `16` | Max parallel HTTP requests |\n| `--rate-limit \u003cR\u003e` | `4` | Max requests/second per host |\n| `--ignore-robots` | false | Bypass robots.txt |\n| `--same-origin` | true | Only follow links on the same origin |\n| `--allow-domains \u003cD1,D2\u003e` | — | Extra domains to crawl (e.g. CDN hosts) |\n| `--no-tokens` | false | Skip design-tokens.json |\n| `--no-manifest` | false | Skip manifest.json / context.md |\n| `--tui \u003ctrue\\|false\u003e` | auto | Force TUI on/off (auto-detects TTY) |\n\n\u003e [!NOTE]\n\u003e **Why is `--depth 0` the default?** Unlike general-purpose web crawlers (like HTTrack) that recursively scrape entire websites by default, `decant` defaults to a single-page mirror (`--depth 0`). For AI code generation and visual reference, you usually want to feed a single, specific reference page at a time to stay within LLM token budgets. If you need multi-page crawling, pass `--depth 2` or higher.\n\n\n### `decant serve \u003cDIR\u003e [OPTIONS]`\n\n| Option | Default | Description |\n|---|---|---|\n| `--port \u003cN\u003e` | `8080` | Port to listen on |\n| `--host \u003cADDR\u003e` | `127.0.0.1` | Address to bind to |\n| `--noscript` | `false` | Strip all script tags on-the-fly to prevent client-side hydration crashes on modern SPAs (Next.js, React, etc.) |\n\n\u003e [!TIP]\n\u003e **Hydration Crashes on Local Preview:** Modern SPAs (like Next.js or TanStack Start) attempt to execute client-side hydration when loaded in the browser. Since the backend APIs do not exist on the local port, this execution can crash or wipe out the DOM. Use `decant serve \u003cDIR\u003e --noscript` to dynamically strip scripts on-the-fly, allowing you to preview the static mirrored UI and styling cleanly.\n\n\n### `decant tokens \u003cDIR\u003e`\n\nRe-run design-token extraction on an existing capture directory without re-downloading anything.\n\n---\n\n## Compatibility\n\n| Site Type | Support |\n|---|---|\n| Static HTML sites | ✅ Full support |\n| React/Vue SPAs with SSR/prerendering | ✅ Full support |\n| React/Vue client-only SPAs | ✅ Use `--render chrome` or `--render lightpanda` |\n| Sites behind session auth | ✅ Use `--cookies` or `--cookie-file` |\n| Browser-inserted JS/CSS/images/fonts/media | ✅ Use `--render chrome` with runtime capture |\n| Live backend state, WebSocket/SSE streams, DRM/protected media, bot-gated APIs | ⚠️ Not fully capturable as static offline files |\n| Multi-page sites | ✅ Use `--depth 2` or higher to follow links |\n| Sites with Cloudflare/bot protection | ⚠️ May get 403/429 — inject real session cookies |\n| React Native / Electron apps | ❌ Not applicable |\n\n---\n\n## Benchmarks\n\nMeasured against **[multigres.com](https://multigres.com)** (a real-world Astro/Vite SPA) on Apple M-series.  \nAll three modes use `--depth 0` (single-page render) for a fair head-to-head comparison.  \nRun: `python3 benchmark.py https://your-site.com`\n\n```\ndecant benchmark — target: https://multigres.com\n============================================================\n RESULTS  (depth=0, single-page, same URL)\n============================================================\nMode                       Time (s)  Peak RAM (MB)\n------------------------------------------------------------\nStatic (no browser)            23.0             20\nLightpanda (JS)                28.2             45    (1.2× slower)\nChrome (headless)              26.5           1066    (1.2× slower)\n------------------------------------------------------------\n→ Lightpanda uses 24× less RAM than Chrome\n→ Static mode uses 53× less RAM than Chrome\n```\n\n**Key observations:**\n\n- **All three modes are near-identical in speed** — decant's rate limiter (4 req/s) is the bottleneck, not the browser. You get JS rendering for free in time terms.\n- **Lightpanda: 45 MB vs Chrome: 1 GB** — 24× less RAM for the same JS execution. The right choice for servers, CI, and Docker containers.\n- **Static: 20 MB** — zero browser overhead. Perfect for sites where JS rendering doesn't change the HTML (most blogs, docs, marketing sites).\n- **When to use each mode:**\n  | Mode | Use when |\n  |---|---|\n  | `static` (default) | Most sites — fastest, least RAM |\n  | `--render lightpanda` | SPAs on Linux/Docker servers |\n  | `--render chrome` | SPAs + browser-observed runtime assets + screenshots |\n\n---\n\n## Use with AI Coding Assistants\n\nInstall the bundled `decant` coding skill so Claude Code, Cursor, and Codex know how to use `decant`'s output to reproduce a UI:\n\n```bash\nnpx skills add codingstark-dev/decant\n```\n\n---\n\n## Browser Backends\n\n| Feature | Chrome | Lightpanda |\n|---|---|---|\n| Full JavaScript execution | ✅ | ✅ |\n| Screenshots | ✅ | ❌ |\n| Runtime network resource capture | ✅ | ❌ |\n| React / Vue / SPA HTML | ✅ | ✅ |\n| Cookie injection (CDP) | ✅ | ✅ |\n| Speed | Same (rate-limited) | Same (rate-limited) |\n| RAM usage | ~1 GB | ~18 MB |\n| Protocol | CDP WebSocket | CDP WebSocket |\n\nBoth backends speak the same Chrome DevTools Protocol (CDP) WebSocket. When `--render chrome` is set, runtime capture is enabled by default in `auto` mode and screenshots are captured automatically unless `--no-screenshots` is passed.\n\nRuntime capture is static-resource focused. It captures browser-observed scripts, stylesheets, images, fonts, media, manifests, and module chunks such as `.mjs`; it does not promise perfect cloning of authenticated sessions, live backend APIs, WebSocket/SSE updates, protected media, checkout flows, or server-personalized state.\n\n\u003e **Note:** Lightpanda is in active development. On macOS arm64, some sites trigger a known CDP navigation hang — decant works around this with a 15-second per-page timeout that automatically falls back to static fetch.\n\n---\n\n## Architecture\n\n```\ndecant              CLI binary — argument parsing, orchestration, TUI\n  ├── decant-core   Fetch engine, URL frontier, rate limiter, robots.txt, file writer\n  ├── decant-extract HTML/CSS/JS parsing, link rewriting, design-token \u0026 manifest extraction\n  ├── decant-render  Headless browser backends (Chrome + Lightpanda via CDP) [feature-gated]\n  └── decant-tui    ratatui dashboard, progress reporter, app state\n```\n\n### Key design decisions\n\n- **Feature gate**: `decant-render` is compiled only when `--features render` is passed. The default binary has zero browser dependencies.\n- **No OpenSSL**: Uses `rustls` exclusively — no native TLS library is required.\n- **Pure transform**: `decant-extract` has no network I/O. It receives bytes and returns structured data.\n- **Arc-based frontier**: The `Frontier` is shared across all tokio tasks via `Arc\u003cMutex\u003c_\u003e\u003e` with fragment-normalized URL deduplication.\n\n---\n\n## Development\n\n```bash\n# Run all tests\ncargo test --workspace\n\n# Run tests including network integration tests (requires internet)\ncargo test --workspace -- --include-ignored\n\n# Check all lints\ncargo clippy --workspace --all-targets -- -D warnings\n\n# Build docs\ncargo doc --workspace --no-deps --open\n```\n\n---\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feat/my-feature`\n3. Commit your changes: `git commit -m \"feat: add my feature\"`\n4. Push to the branch: `git push origin feat/my-feature`\n5. Open a Pull Request\n\nPlease make sure `cargo clippy --workspace -- -D warnings` and `cargo test --workspace` both pass before submitting.\n\n---\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n\u003e ⚠️ **Legal notice**: Mirroring a site's layout and design system for reference/study purposes is generally permissible, but you may not redistribute a site's copyrighted text, images, or branding. Always review a site's Terms of Service before crawling it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingstark-dev%2Fdecant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodingstark-dev%2Fdecant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodingstark-dev%2Fdecant/lists"}