Back to home
React Grab

I made your coding agent 55% faster at frontend

By Aiden Bai · November 24, 2025

Coding agents suck at frontend because translating intent (from UI → prompt → code → UI) is lossy.

For example, if you want to make a UI change:

  1. Create a visual representation in your brain
  2. Write a prompt (e.g. "make this button bigger")

How the coding agent processes this:

  1. Turns your prompt into a trajectory (e.g. "let me grep/search for where this code might be")
  2. Tries to guess what you're referencing and edits the code

Search is a pretty random process since language models have non-deterministic outputs. Depending on the search strategy, these trajectories range from instant (if lucky) to very long. Unfortunately, this means added latency, cost, and performance.

Today, there are two solutions to this problem:

  • Prompt better: Use @ to add additional context, write longer and more specific prompts (this is something YOU control)
  • Make the agent better at codebase search (e.g. Instant Grep, SWE-Grep - this is something model/agent PROVIDERS control)

Improving the agent is a lot of unsolved research problems. It involves training better models (see Instant Grep, SWE-grep).

Ultimately, reducing the amount of translation steps required makes the process faster and more accurate (this scales with codebase size).

But what if there was a different way?

Digging through React internals

In my ad-hoc tests, I noticed that referencing the file path (e.g. path/to/component.tsx) or something to grep (e.g. className="flex flex-col gap-5 text-shimmer") made the coding agent much faster at finding what I was referencing. In short - there are shortcuts to reduce the number of steps needed to search!

Turns out, React.js exposes the source location for elements on the page. React Grab walks up the component tree from the element you clicked, collects each component's component name and source location (file path + line number), and formats that into a readable stack.

It looks something like this:

<selected_element>

## HTML Frame:

<span class="font-bold">
  React Grab
</span>

## Code Location:

  at motion.div
  at StreamingText in /[project]/packages/website/components/blocks/streaming-text.tsx
  at MessageBlock in /[project]/packages/website/components/blocks/message-block.tsx
  at StreamDemo in /[project]/packages/website/components/stream-demo.tsx

</selected_element>

When I passed this to Cursor, it instantly found the file and made the change in a couple seconds. Trying on a couple other cases got the same result.

demo gif

Benchmarking for speed

I used the shadcn/ui dashboard as the test codebase. This is a Next.js application with auth, data tables, charts, and form components.

The benchmark consists of 20 test cases designed to cover a wide range of UI element retrieval scenarios. Each test represents a real-world task that developers commonly perform when working with coding agents.

Each test ran twice: once with React Grab enabled (treatment), once without (control). Both conditions used identical codebases and Claude 4.5 Sonnet (in Claude Code).

Without React Grab:
"Find the forgot password link in the login form"
Read components/login-form.tsx
Grepped forgot password
Read components/auth/forgot.tsx
Read components/ui/field.tsx
Grepped ml-auto.*password
~13.6s, 5 tool calls, 41.8K tokens
With React Grab:
"Find the forgot password link in the login form"
<selected_element>

<a class="ml-auto inline-block text-..." href="#">
  Forgot your password?
</a>

  at a in components/login-form.tsx:46:19
  at div in components/login-form.tsx:44:17
  at Field in components/ui/field.tsx:87:5
  at FieldGroup in components/ui/field.tsx:46:5
  at form in components/login-form.tsx:32:11

</selected_element>
Read components/login-form.tsx
~6.9s, 1 tool call, 28.1K tokens

Without React Grab, the agent must search through the codebase to find the right component. Since language models predict tokens non-deterministically, this search process varies dramatically - sometimes finding the target instantly, other times requiring multiple attempts. This unpredictability adds latency, increases token consumption, and degrades overall performance.

With React Grab, the search phase is eliminated entirely. The component stack with exact file paths and line numbers is embedded directly in the DOM. The agent can jump straight to the correct file and locate what it needs in O(1) time complexity.

…and turns out, Claude Code becomes ~55% faster with React Grab!

Normalized to Control = 100%
MetricControl
React GrabReact Grab
Avg Duration17.4s7.6s 55.9%
Total Cost$0.75$0.40 46.8%
Avg Tool Calls4.40.5 89.8%

Below are the latest measurement results from all 20 test cases. The table below shows a detailed breakdown comparing performance metrics (time, tool calls, tokens) between the control and treatment groups, with speedup percentages indicating how much faster React Grab made the agent for each task.

Results

Performance metrics per test: tokens, cost (USD), duration, and tool calls. React Grab shows % change vs. Control.Last run: November 20, 2025 at 12:17 PM

Test Name
Input Tokens
Output Tokens
Cost
Duration
Tool Calls
Control
React GrabReact Grab
Control
React GrabReact Grab
Control
React GrabReact Grab
Control
React GrabReact Grab
Control
React GrabReact Grab
Calendar Date Cell44,02127,366↓38%24188↓63%$0.04$0.02↓50%13.1s8.5s↓35%31↓67%
Drag Handle40,54613,544↓67%19510↓95%$0.02$0.01↓48%10.3s7.2s↓29%20↓100%
Dropdown Actions42,97913,608↓68%41910↓98%$0.03$0.01↓76%15.7s5.8s↓63%50↓100%
Editable Target Input55,56237,228↓33%65869↓90%$0.07$0.05↓25%32.4s9.1s↓72%131↓92%
Field Description Text40,51013,592↓66%17310↓94%$0.02$0.01↓66%13.4s5.8s↓56%20↓100%
Forgot Password Link41,79528,026↓33%26169↓74%$0.03$0.02↓25%13.5s6.9s↓49%51↓80%
Full Name Input Field26,91013,562↓50%8710↓89%$0.02$0.01↓58%7.6s6.4s↓15%10↓100%
GitHub Link Button58,94213,536↓77%43510↓98%$0.05$0.01↓73%19.8s6.3s↓68%80↓100%
Grayscale Avatar42,21727,153↓36%256106↓59%$0.03$0.02↓41%13.1s9.8s↓25%31↓67%
Keyboard Shortcut Badge68,29413,561↓80%52211↓98%$0.05$0.01↓74%34.4s6.1s↓82%100↓100%
OTP Input43,22728,413↓34%25096↓62%$0.05$0.02↓62%16.3s9.6s↓41%41↓75%
Projects More Button61,70713,604↓78%24910↓96%$0.04$0.01↓82%19.1s5.6s↓70%30↓100%
Quick Create Button55,03528,079↓49%22069↓69%$0.03$0.02↓34%12.6s9.2s↓27%31↓67%
Revenue Card Badge42,81413,611↓68%36310↓97%$0.03$0.01↓77%16.3s6s↓63%60↓100%
Sidebar Trigger Toggle64,48413,533↓79%36310↓97%$0.07$0.01↓83%19.4s7.4s↓62%60↓100%
Sign Up With Google Button41,44713,576↓67%16610↓94%$0.03$0.01↓56%11.6s6.7s↓42%20↓100%
Status Badge154,62537,212↓76%74294↓87%$0.11$0.06↓48%45.8s9.5s↓79%91↓89%
Tabs with Badges26,96837,326↑38%8269↓16%$0.02$0.06↑225%8.8s10.1s↑14%11
Team Switcher Dropdown26,93813,607↓49%11711↓91%$0.02$0.01↓57%13s6.2s↓52%10↓100%
Time Range Toggle26,98032,055↑19%139108↓22%$0.02$0.04↑110%11.2s10.1s↓10%11

To run the benchmark yourself, check out the benchmarks directory on GitHub.

How it impacts you

The best use case I've seen for React Grab is for low-entropy adjustments like: spacing, layout tweaks, or minor visual changes.

If you iterate on UI frequently, this can make everyday changes feel smoother. Instead of describing where the code is, you can select an element and give the agent an exact starting point.

We're finally moves things a bit closer to narrowing the intent to output gap (see Inventing on Principle).

What's next

There are a lot of improvements that can be made to this benchmark:

  • Different codebases (this benchmark used shadcn dashboard) - what happens with different frameworks/sizes/patterns? Need to run it on more repos.
  • Different agents/model providers
  • Multiple trials and sampling - decrease variance, since agents are non-deterministic

On the React Grab side - there's also a bunch of stuff that could make this even better. For example, grabbing error stack traces when things break, or building a Chrome extension so you don't need to modify your app at all. Maybe add screenshots of the element you're grabbing, or capture runtime state/props.

If you want to help out or have ideas, hit me up on Twitter or open an issue on GitHub.

Try it out

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