Follow a feature
across the app.

Use a CSV export to see how REA connects JavaScript files, exposed APIs and Electron process boundaries.

Where does “Export notes” go?

This guide uses a small Electron app. Clicking Export notes calls an API in the page, crosses into the main process, and writes a CSV. The behavior is spread across several files.

A feature across two processes

  1. Renderer → preloadnotes.exportCsv()renderer.js calls the API exposed by preload.js.
  2. Between processesnotes:exportThe preload invokes an IPC channel: a named message to the main process.
  3. Main processAn export handlermain.js handles that channel and calls the CSV writer.

csv.js formats the notes → main.js writes downloads/notes.csv.

REA matches the literal IPC call to its handler and identifies the exposed API. The path is inferred from code; a runtime capture can check what executes.

Give your agent one feature

Connect your agent to REA and give it the app directory or ASAR file:

Your coding agent

Use REA to find what happens when I export notes in this app. Where is the CSV created?

Example prompt. Include the absolute path to the application folder or app.asar.

REA reads the application files and builds a map of entrypoints, modules and process boundaries. Your agent uses that map to narrow the investigation to the export feature.

Connect the pieces

The page calls a small API

renderer.js · example source
document.querySelector("#export").addEventListener("click", async () => {
  const destination = await window.notes.exportCsv();
  document.querySelector("#status").textContent = `Saved to ${destination}`;
});

The page knows the method name. The implementation lives in the preload, which exposes it to the renderer.

preload.js · example source
contextBridge.exposeInMainWorld("notes", {
  exportCsv: () => ipcRenderer.invoke("notes:export"),
});

REA records notes.exportCsv and the literal channel notes:export. It pairs that invocation with the single matching handler in the main process.

main.js · example source
ipcMain.handle("notes:export", () => {
  const destination = path.join(app.getPath("downloads"), "notes.csv");
  writeFileSync(destination, toCsv(notes), "utf8");
  return destination;
});

Reading the handler answers the original question: csv.js formats the notes, and the main process writes notes.csv into the user's Downloads folder.

REA result · summary.ipc excerpt
{
  "literal_channels": 1,
  "renderer_transmissions": 1,
  "main_handlers": 1,
  "paired_renderer_transmissions": 1,
  "ambiguous_renderer_transmissions": 0
}

Recorded by REA 4.1.0 on the downloadable example below. Source locations accompany the API, channel and handler findings.

Analyze the example yourself

Save these six files together in a folder named notes-example. Static analysis needs Node.js and npm; you can inspect the code without installing or launching Electron.

Static application analysis
npx -y rea-agents@latest analyze-javascript-application \
  /absolute/path/to/notes-example --json

Replace the path with the folder you saved. Look for normalized_result.summary.ipc and the source locations in normalized_result.graph. The example has one channel and one paired invocation.

For your own app, use the same command with its directory or ASAR path. An agent can follow a literal string, API name or IPC channel with REA's feature tracing tools.

Ask the next question

Follow notes:export to its handler. Which inputs reach the CSV writer, and what happens if writing the file fails?

Use the source locations to inspect those details. Computed channel names and ambiguous handlers can remain unresolved; runtime observations give you another way to investigate them.