React Grab

React Grab for Agents

By Aiden Bai, Ben Maclaurin · December 4, 2025

Prefer a video breakdown?

TL;DR

React Grab used to stop at copying context for your coding agent. Now it can directly talk to the agent to edit the code -- all from the browser.

What stays the same

  • React Grab is still free and open source
  • It still works with any AI coding tool (Claude Code, Cursor, Opencode, Copilot, etc.)
  • The core idea is still "click an element, get real React context and file paths"

What is new

  • You can now spin up agents like Claude Code or Cursor directly from the page
  • You can run multiple UI tasks at once, each attached to the element you clicked
  • You can make changes to your code without leaving the browser

How React Grab started

React Grab came from a simple (but very relevant!) annoyance.

Coding agents are good at generating code, but bad at guessing what I actually want. The loop looked like this:

  1. I would look at some UI, form a mental picture, and then try to describe it in English.
  2. The agent would guess which files to open, grep around, and maybe land on the right component. As the codebase grew, this "guess where this is" step became the bottleneck.

I built the first version of React Grab2 to solve this: press ⌘C, click an element, and React Grab gives you the component stack with exact file paths and line numbers.

React Grab demo

Now, instead of guessing where an element might live, the agent jumps straight to the exact file, line, and column.

In the benchmarks I ran on a shadcn dashboard, that alone made Claude Code roughly 66% faster on average for a set of UI tasks.1 The agent did fewer tool calls, read fewer files, and got to the edit sooner, because it no longer had to search.

React Grab worked. People wired it into their apps. It made coding agents feel less random for UI work.

It also had an obvious flaw.

We can do better

React Grab solved the context problem and ignored everything else (this is actually intentional!). You still had to copy, switch to your agent, paste, wait, switch back, and refresh. For one-off tasks this was fine. After using it daily, I realized we can do a LOT better.

The browser had the best view of your intent. The agent had the power to edit the code. Why not put the agent in the browser?

(Theo predicted this months ago.)

React Grab for Agents

React Grab for Agents is what happens when you let the browser do more of the loop.

The idea is simple.

You hold ⌘C, click an element, and a small label appears showing the component name and tag. Press Enter to expand the prompt input. Type what you want to change, press Enter again, and the agent starts working.

React Grab sends the context (file paths, line numbers, component stack, nearby HTML) along with your prompt to the agent. The agent edits your files directly while the label streams back status updates. When it finishes, the label shows "Completed" and your app reloads with the changes.

You never leave the browser. You never touch the clipboard.

You can run multiple tasks at once. Click one element, start an edit, then click another and start a different task. Each selection tracks its own progress independently. It starts to feel less like "I am chatting with an assistant" and more like a small job queue attached to my UI

Setup

Setup is designed to feel like adding one more feature to your existing React Grab integration, not like adopting a new framework.

CLI (Recommended)

Run this command at your project root to automatically install React Grab:

npx @react-grab/cli@latest

The CLI will detect your framework and add the necessary scripts automatically.

Claude Code

Server Setup

The server runs on port 4567 and interfaces with the Claude Agent SDK. Add to your package.json:

{
  "scripts": {
    "dev": "npx @react-grab/claude-code@latest && next dev"
  }
}

Client Setup

If you already have React Grab running via a script tag in a Next.js app, add the Claude Code client script in your <head>:

<script src="//unpkg.com/react-grab/dist/index.global.js"></script>
<script src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"></script>

Or using Next.js Script component in your app/layout.tsx:

import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {process.env.NODE_ENV === "development" && (
          <>
            <Script
              src="//unpkg.com/react-grab/dist/index.global.js"
              strategy="beforeInteractive"
            />
            <Script
              src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"
              strategy="lazyOnload"
            />
          </>
        )}
      </head>
      <body>{children}</body>
    </html>
  );
}

Cursor CLI

Server Setup

The server runs on port 5567 and interfaces with the cursor-agent CLI. Add to your package.json:

{
  "scripts": {
    "dev": "npx @react-grab/cursor@latest && next dev"
  }
}

Client Setup

Add the Cursor client script in your <head>:

<script src="//unpkg.com/react-grab/dist/index.global.js"></script>
<script src="//unpkg.com/@react-grab/cursor/dist/client.global.js"></script>

Or using Next.js Script component in your app/layout.tsx:

import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {process.env.NODE_ENV === "development" && (
          <>
            <Script
              src="//unpkg.com/react-grab/dist/index.global.js"
              strategy="beforeInteractive"
            />
            <Script
              src="//unpkg.com/@react-grab/cursor/dist/client.global.js"
              strategy="lazyOnload"
            />
          </>
        )}
      </head>
      <body>{children}</body>
    </html>
  );
}

Hold ⌘C, click an element, then press Enter to open the prompt. Type your query, pick an agent from the dropdown, and hit Enter again to run it.

Opencode

Server Setup

The server runs on port 6567 and interfaces with the opencode CLI. Add to your package.json:

{
  "scripts": {
    "dev": "npx @react-grab/opencode@latest && next dev"
  }
}

Client Setup

Add the Opencode client script in your <head>:

<script src="//unpkg.com/react-grab/dist/index.global.js"></script>
<script src="//unpkg.com/@react-grab/opencode/dist/client.global.js"></script>

Or using Next.js Script component in your app/layout.tsx:

import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {process.env.NODE_ENV === "development" && (
          <>
            <Script
              src="//unpkg.com/react-grab/dist/index.global.js"
              strategy="beforeInteractive"
            />
            <Script
              src="//unpkg.com/@react-grab/opencode/dist/client.global.js"
              strategy="lazyOnload"
            />
          </>
        )}
      </head>
      <body>{children}</body>
    </html>
  );
}

How it works

Under the hood, React Grab for Agents is built on the same mechanics as the original library.

When you select an element, React Grab:

  • Walks the React fiber tree upward from that element.
  • Collects component display names and, in development, source locations with file path and line and column numbers.
  • Captures a small slice of DOM and attributes around the node.

This is the context that made the original benchmarks so much better. The agent gets a direct pointer instead of a fuzzy description.

The new part is the agent provider.

An agent provider is a small adapter that connects React Grab to a coding agent. When you submit a prompt, React Grab sends the context and your message to a local server. The server passes this to the actual CLI (claude or cursor-agent) which edits your codebase directly. Status updates stream back to the browser so you can watch the agent work.

The providers are open source. You can read through the implementation or use them as a starting point for your own: @react-grab/claude-code, @react-grab/cursor, @react-grab/opencode.

What's next

Right now, React Grab for Agents is tool-agnostic on purpose. It integrates with the agents that exist. If your tool has a CLI or an API, you can add a provider.

However, I do not think the long term story is just "wire up whatever you already have." There is a missing piece: a coding agent designed specifically for UI work, built around the way React Grab represents context.

Soon, we'll be releasing Ami.3

The idea is that React Grab handles the UI side: selections, stacks, file paths, and prompts. Ami handles the agent side: planning, editing, and understanding component hierarchies and design systems. The contract is narrow. React Grab says "here is exactly what the user clicked and what they asked for." Ami replies with "here is the minimal patch that makes that true, in a style you will recognize."

React Grab for Agents is the infrastructure that makes that relationship possible. Before Ami exists, it makes your existing tools faster and less random for frontend work. Once Ami is ready, it gives it a natural place to live.

Try it out

React Grab is free and open source. Go try it out!

Footnotes

1See the full benchmark writeup. Single trial per test case, so treat the exact number with appropriate skepticism. The direction is consistent across tasks.

2This only works in development mode. React strips source locations in production builds for performance and bundle size. React Grab detects this and falls back to showing component names without file paths. You can enable source maps in production if you need the full paths.

3Ami is under active development. If you want early access or want to help shape it, reach out on Twitter.