On Sunday morning, 11 October, REA was number one on GitHub's daily trending page, with 25,793 stars gained in a single day. The repo showed 76,998 stars and 16,440 forks. The pitch is simple: "Reverse engineer anything with agents." You install an MCP server, and your coding agent can take apart native binaries, Electron apps, websites, Android APKs and more, then show you the evidence.
I'm wary of anything that gets that famous that fast, so I skipped the README demos. I installed it on a plain Linux box, pointed it at a real 100 MB Electron app, and then built a tiny app where I know every right answer, to see how well it grades itself.
Short version: the static JavaScript analysis is genuinely good and fast. It also missed something I could see with grep, and what it asks of an agent is heavy. Details below.
What I tested and what I didn't
The box is Debian 13 with 8 vCPUs and no GPU. There was no Claude Code, Codex or cloud API key on it, so no agent drove REA. I called it from its own CLI and from a small script that speaks raw MCP over stdio. That tests the tools, not an agent's judgment about when to use them.
REA lists a lot of targets: native binaries, .NET, APKs, firmware, websites, process capture. Native work needs Hopper, Ghidra or IDA, and I had none of the three on this Linux box (the Hopper features are Mac-only). So I stuck to the one target that needs only Node: JavaScript and Electron apps, analyzed statically.
The real target was PI-Desktop v0.16.1, the Electron app from my previous article. Its app.asar is 100 MB and holds 459 relevant files. I also built a five-file toy Electron app, because I can't grade a tool on an app whose source I haven't read.
Install: fast, with one Node catch
REA wants Node 22.19+, 24.11+ or 26+. The box shipped Node 20, so I grabbed 22.20 from nodejs.org. The box has no xz, so I unpacked the tarball with Python. Then:
npm install rea-agents@latest
# added 144 packages, and audited 145 packages in 3s (node_modules: 96 MB)
npx rea --version
# 6.4.0
The version matters. npm lists 31 versions since the package appeared in July, and GitHub shows releases 6.1, 6.2 and 6.3 all on 9 October. 6.4.0 landed on 11 October, the day I tested. The README itself says it "changes quickly", so pin a version.
Then rea doctor:
healthy: false
node ok 22.20.0
host FAIL unsupported_host debian 13
hopper FAIL missing_analysis_engine
ghidra FAIL GHIDRA_INSTALL_DIR is not set
The supported hosts are macOS 12+, Ubuntu 24.04+, Fedora 41+, Nobara, Arch, CachyOS and Omarchy, so Debian 13 gets a red mark. It didn't stop anything I ran. Static JavaScript analysis worked fine on the "unsupported" host. I also ran it once under Node 20, where doctor flagged the version, and the analysis still ran. I wouldn't rely on that, but it's good to know the check is stricter than the code.
I didn't want setup touching the box's real config, so I ran it against a throwaway home directory:
HOME=/tmp/fakehome npx rea setup --client claude_code --dry-run # prints the plan
HOME=/tmp/fakehome npx rea setup --client claude_code --yes
# appliedActions[2]: configured_claude_code, installed_skill
The dry run listed exactly two changes before anything was written. The result was a small mcpServers.rea entry (npx -y rea-agents@6.4.0 mcp) and a skill folder with a SKILL.md and references. Small, clear and reversible. That's how I like setup to behave.
The scan: 52 seconds, 3.1 million AST nodes
time npx rea analyze-javascript-application app.asar --format json > out.json
# real 0m52.2s out.json: 59.2 MB
REA read 459 files (24.2 MB of text), parsed 421 JavaScript files, walked 3,114,427 AST nodes and had zero parse failures. For a 100 MB bundle, 52 seconds is fine.
Then I checked its Electron summary against the unpacked source, using plain grep:
Here is where it matched:
-
Browser windows: REA said 5. There are five
new BrowserWindow(calls (four in one chunk, one inindex.js). -
contextBridge APIs: REA said 2. The preload scripts call
exposeInMainWorldforpiDesktopandpluginBridge. -
IPC: REA said 4 main-process handlers, 6 renderer transmissions and 5 renderer listeners. My grep counts for
ipcMain.handle/on,ipcRenderer.invoke/send/sendSyncandipcRenderer.oncome to the same numbers: 4, 6 and 5. - Sender checks: it reported 4 places where the main process looks at the sender of an IPC message. I didn't verify each of those by hand, so I'm only passing the number along.
And here is what it got wrong:
-
Preload entrypoints: REA said 0. The app has two preload files,
preload/index.cjsandpreload/plugin-panel.js. The windows load them through code likejoin(getModuleDirectory(import.meta.url), "../preload/index.cjs"). My guess is that this helper call is the reason REA couldn't resolve the path statically, but I haven't confirmed that. - Exposed API members: REA said 0. Both bridges obviously expose members, so this zero follows from the missing preload link.
REA is also candid about what it dropped. The result carries 744 limitations. For 365 of them, the text says: "Expanded application relationships for [file] exceed the parent's result budget; complete static facts were retained on the file node." In plain terms, on a big app it keeps counts and per-file facts but throws away some of the connections between them.
That cost me the most useful feature on the real app. I asked it to trace anything touching the channel pi-plugin-panel:
seed_matches: []
coverage.status: no-match
"No graph entity matched the literal seed; this is not evidence that the feature is absent."
The string pi-plugin-panel-drop is right there in the source. The graph just didn't have channel nodes for it. The tool says so, which I respect, but you'd still be stuck.
The toy app: where it shines
So I wrote a five-file Electron app (main.js, preload.js, index.html, renderer.js, package.json) with known contents:
- one window with a preload script
- one
contextBridgeAPI with four members - three literal IPC channels:
notes:read,notes:write,open-external - one loop that registers
job:syncandjob:exportfrom a variable, and a preload call that builds"job:" + topic - two handlers that check the sender, through a small helper function
I analyzed it as written, then again after esbuild --minify, which squashes main.js into one 732-byte line with one-letter variable names.
On both versions, REA's counts were identical, and nearly all of them were right: 1 window, 1 preload, 1 bridge API with 4 members, 3 literal channels, 2 dynamic channel operations, 4 main handlers, 4 renderer transmissions, 3 of them paired with their handlers (the fourth is the dynamic one). Each run took about two seconds.
The tracer is the highlight. I fed the evidence back in with trace-application-feature and a seed of channel: "notes:read". It returned the chain I wanted, on the minified bundle: preload.js invokes the channel notes:read, and the channel is handled by the notes:read handler. It even kept the dynamic channel honest. In the minified code the label is "job:"+e, the actual expression with the renamed variable, rather than a made-up string.
The one miss on the toy: sender validation. I wrote two handlers that call a checkSender(e) helper, which looks at e.senderFrame.url. REA reported 0 sender-validation observations. That's the kind of check you'd want a security-minded tool to notice. A check hidden behind a helper function got past it.
The part nobody puts in the README: what it costs an agent
REA exposes 170 MCP tools. I opened a stdio session, sent initialize and tools/list, and measured the reply:
init: 1.4 s serverInfo: {"name":"rea","version":"6.4.0"}
tools/list: 170 tools in 0.3 s
payload: 1,954,704 bytes
That's about 1.95 MB of JSON before the agent does anything. By the usual rule of thumb of four characters per token, that's roughly half a million tokens, though that's my estimate and clients may defer or trim tool lists. For scale, I run the local model I use for tests with a 16k context. The project's own docs mention a related problem: GitHub Copilot CLI with gpt-4.1 can block chat with REA's full schema profile, and they suggest a "compact" profile. I tried it with REA_MCP_INPUT_SCHEMA_PROFILE=compact. The list shrank to 1,772,775 bytes, which is 9% smaller. Helpful, not a cure.
This is why I didn't try to drive it with a small local model. The tool list alone wouldn't fit in the context window, so any result would say more about my setup than about REA.
The tool call itself is heavy too. I called analyze_javascript_application on the same app.asar over MCP with detail: "summary":
call: 60.5 s response: 1,350,868 bytes (text part: 672 KB)
A "summary" that is 672 KB of text is a lot for an agent to read. If you use REA through an agent, I'd expect the agent to spend a lot of its budget on REA's output. I'd test it with your exact client before you commit.
Native binaries: stopped at the door
I did try the native path, to see how it fails. Pointing rea analyze at PI-Desktop's 20 MB Rust host binary:
code: provider_unavailable
candidate_ids: ghidra, hopper, ida
That's a clear message with a clear fix, and I'd have been disappointed by anything vaguer. rea inspect-artifact on the same file still worked without a provider. In 1.7 seconds it returned the format (ELF) and a SHA-256 that matches what sha256sum printed, plus a suggested next step: open_binary, which needs one of the three engines. So you get identification, not understanding, until you install a disassembler. I didn't, so I can't tell you how good the native side is.
What worked and what didn't
What worked:
- Install in 3 seconds, and a setup that shows its plan before writing anything
- Static analysis of a 100 MB Electron app in about 52 seconds, with zero parse failures
- Counts for windows, bridges and IPC that matched my grep on the real app
- Identical, correct results on plain and minified code in my toy app
- An honest evidence trail: limitations listed, "no match" is not claimed as "absent"
What didn't:
- Missed both preload files on the real app, which zeroed out the exposed-API count
- Dropped connections on 365 files because of its own result budget, so the trace on a real channel found nothing
- Missed a sender check hidden behind a helper function
- A 1.95 MB tool list and a 672 KB "summary", which an agent has to carry
-
doctorgoes red on Debian 13 even though the JavaScript path ran fine
What I didn't test: Hopper, Ghidra or IDA, websites and browser capture, APKs, firmware, runtime capture, and above all an agent actually using the tools to "build a similar feature", which is the headline pitch. That claim needs a frontier model and a real session, and I didn't have one.
Should you try it?
If you work with Electron or bundled JavaScript, yes. The pairing of fast static analysis and a graph you can trace is useful, and the toy-app result on minified code impressed me more than any star count. Run it on an app you already understand first, the way I did, so you learn where it's blind before you trust it on one you don't.
If you plan to hand it to an agent, go in with care. Count the tokens in the tool list, try the compact profile, and keep an eye on how much an analysis result takes from the context window.
As for the trending page: stars tell you people are curious, not whether the tool matches a given job. I couldn't check the claim that it jumped from about 9k stars in four days, because GitHub only gives star timestamps to signed-in API calls. What I could check is that on Sunday morning it was real, MIT-licensed, released four times in three days (6.1 to 6.4), and good at most of the job I gave it. It also missed two files that grep found in a second.
I'd like to see this on a Mac with Hopper and a frontier model driving it. If you've run REA that way, tell me what held up.




Top comments (0)