Skip to main content
Glama
README.md
# frameshot

[![npm version](https://img.shields.io/npm/v/frameshot-mcp)](https://www.npmjs.com/package/frameshot-mcp) [![npm downloads](https://img.shields.io/npm/dm/frameshot-mcp)](https://www.npmjs.com/package/frameshot-mcp) [![GitHub stars](https://img.shields.io/github/stars/kamegoro/frameshot)](https://github.com/kamegoro/frameshot) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Give your AI agent eyes.** Render components with real Vite imports, Tailwind, and CSS Modules — right in your terminal or AI chat. No story files required.

<p align="center">
  <img src="docs/demo.gif" alt="frameshot demo" width="720" />
</p>

**Claude Code**

```bash
claude mcp add frameshot -- npx frameshot-mcp@latest
```

<details>
<summary>Cursor · VS Code · Windsurf · Cline</summary>

```json
{
  "mcpServers": {
    "frameshot": {
      "command": "npx",
      "args": ["frameshot-mcp@latest"]
    }
  }
}
```

</details>

---

## Watch mode — live AI feedback loop

The AI edits a file, saves it, and immediately sees how it looks — without you calling anything.

```
watch_start({ patterns: ["src/components/Button.tsx"] })
→ renders on every save → call watch_get_latest("watch-1") to see it
```

The agent fixes → saves → sees → fixes again. You just watch.

---

## GitHub Action — free Chromatic alternative

Two lines. Auto-detects changed components. Posts before/after/diff screenshots directly in the PR comment.

```yaml
- uses: actions/checkout@v7
  with:
    fetch-depth: 0
- uses: kamegoro/frameshot@v0.8.0
```

<p align="center">
  <img src="docs/diff-before.png" alt="Before" width="210" />
  &nbsp;
  <img src="docs/diff-after.png" alt="After" width="210" />
  &nbsp;
  <img src="docs/diff-result.png" alt="Diff" width="210" />
</p>

Changed `.tsx`, `.jsx`, `.vue`, `.svelte`, `.astro`, `.mdx` files detected automatically. No Storybook. No signup. Free forever.

<details>
<summary>Options</summary>

```yaml
- uses: kamegoro/frameshot@v0.8.0
  with:
    paths: "./src/components/*.tsx"       # default: auto-detect
    extensions: ".jsx,.tsx,.vue"          # default: .jsx,.tsx,.vue,.svelte,.astro,.mdx
    exclude: "*.test.*,*.spec.*"          # default: *.test.*,*.spec.*,*.stories.*
```

</details>

---

## Render any component

Point to a file. Get a screenshot. Full Vite pipeline.

```
render_file("src/components/Dashboard.tsx")
```

<p align="center">
  <img src="docs/example-output.png" alt="Rendered PricingCard with full Tailwind styling" width="280" />
</p>

Resolves your project's real imports, Tailwind config, CSS Modules, and path aliases — not a CDN polyfill.

---

## Using with Claude

After installing, just describe what you want:

```
"Render src/components/PricingCard.tsx — does it look right?"
"Refactor the layout to CSS grid and show me before/after"
"Watch Button.tsx while I edit — tell me when something looks off"
```

Claude calls `render_file`, `diff_component`, `watch_start`, or any other tool automatically.

---

## Try it without an AI client

Works standalone on any React / Vue / Svelte project:

```bash
npx frameshot render src/components/Button.tsx
npx frameshot diff src/components/Header.tsx
npx frameshot catalog src/components/ --recursive
```

Images display inline in iTerm2, Kitty, and Sixel terminals. Saved to `.frameshot/` by default.

> First run installs Playwright's Chromium (~150MB). Subsequent renders are fast.

---

## Tools

| Tool | What it does |
|------|-------------|
| `render_file` | Render a file via Vite — real imports, Tailwind, CSS Modules |
| `diff_component` | Pixel diff before/after — % changed, highlighted pixels |
| `watch_start` | Watch files — auto-render on every save |
| `watch_get_latest` | Get the latest render from a watch session |
| `render_catalog` | Render every component in a directory at once |
| `screenshot_url` | Screenshot any URL — localhost, staging, prod |
| `render_responsive` | Mobile + tablet + desktop in one call |
| `render_theme` | Light + dark mode side by side |
| `audit_a11y` | axe-core accessibility audit (WCAG violations) |
| `render_component` | Render a self-contained code snippet |

<details>
<summary>All 22 tools</summary>

| Tool | What it does |
|------|-------------|
| `render_file` | Render a project file with full Vite dependency resolution |
| `render_component` | Render a self-contained snippet → screenshot |
| `screenshot_url` | Screenshot any URL with retry and network idle wait |
| `render_responsive` | Mobile + tablet + desktop in one call |
| `render_variants` | Multiple prop/state variants at once |
| `render_theme` | Light + dark mode side by side |
| `render_interaction` | Simulate click/hover/type, then screenshot |
| `render_grid` | Multiple snippets in a labeled grid |
| `render_matrix` | Viewport × theme matrix in one call |
| `capture_animation` | Multi-frame CSS animation capture |
| `diff_component` | Before/after pixel diff with % changed |
| `diff_reference` | Compare render against a reference image (Figma QA) |
| `audit_a11y` | axe-core accessibility audit |
| `perf_audit` | DOM count, depth, render timing |
| `render_catalog` | Render all components in a directory |
| `snapshot_save` | Save a render as named baseline |
| `snapshot_check` | Compare current render against saved baseline |
| `snapshot_list` | List all saved snapshots |
| `watch_start` | Start watching files — renders on every save |
| `watch_stop` | Stop a watch session |
| `watch_get_latest` | Get the latest rendered screenshot from a session |
| `watch_list` | List active watch sessions |

</details>

---

## Performance

| Scenario | Time |
|----------|------|
| Warm render (Vite server cached) | **~200–500ms** |
| CDN fallback (no Vite) | **~120ms** |
| Cold start (first render) | ~1–3s |
| Subsequent renders (same session) | ~200ms |

Vite server is cached per project root. Browser pool stays warm between MCP calls.

---

## vs. alternatives

| | Storybook | Chromatic | Browser MCP | **frameshot** |
|---|-----------|-----------|-------------|---------------|
| Setup | Stories + config | SaaS signup | Browser install | **`npx` — done** |
| Speed | Dev server startup | Cloud round-trip | 2–5s | **~200ms warm** |
| Cost | Free (labor cost) | $149–800+/mo | Free | **Free forever** |
| Story files needed | Yes | Yes | No | **No** |
| Real imports resolved | Via Storybook | Via Storybook | No | **Via Vite** |
| Works offline | Yes | No | Yes | **Yes** |
| Watch mode | No | No | No | **Yes** |
| AI-native (MCP) | No | No | Full-page only | **Component-level** |

---

## Development

```bash
git clone https://github.com/kamegoro/frameshot.git
cd frameshot && npm install
npx playwright install chromium
npm run build && npm test
```

See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for architecture details.

---

MIT © [kamegoro](https://github.com/kamegoro)

TDQS

A3.7/5.0

Scored across 22 tools

Disambiguation4/5

Most tools have distinct responsibilities (render vs diff vs snapshot vs watch), and the render_* variants are separated by output type. However, render_component and render_file overlap as ways to render component code, and render_grid/render_matrix could be confused when comparing multiple views.

Naming Consistency4/5

Tools overwhelmingly follow a predictable verb_noun pattern (render_, snapshot_, watch_, diff_). The main deviation is perf_audit, which reverses the verb_noun order used by audit_a11y, but the pattern remains readable.

Tool Count3/5

22 tools is on the heavy side. While each tool has a plausible purpose, many render_* variants (responsive, theme, variants, grid, matrix) could be consolidated into a single parameterized render tool.

Completeness4/5

The surface covers the full visual QA loop: render, interact, compare, snapshot, audit, and watch. Minor gaps exist—there is no snapshot deletion or management beyond listing, and no way to control browser engines—but these do not create dead ends.

Maintenance

ActivityMaintained
ResponsivenessSyncing