← Back to archive

Repo of the Day

nolanlawson/fuite

Published: Jan 18, 2022

Open repository ↗

A tool for finding memory leaks in web apps

Summary

fuite is a JavaScript CLI tool that hunts for memory leaks in web applications by driving a real Chrome browser through scripted scenarios and comparing heap snapshots across repeated iterations. The default scenario clicks internal links and presses the back button, which catches leaks that often appear during client-side route changes. It also exposes a programmatic API for more custom testing setups.

What it is useful for

fuite helps front-end engineers catch memory regressions before users do. It specifically flags:

  • Objects captured via Chrome heap snapshots
  • Event listeners that aren't being cleaned up
  • DOM nodes that remain attached
  • Growing collections such as Arrays, Maps, Sets, and plain Objects

By repeating each action a prime number of times (7 by default), fuite filters out random noise and only reports things that leak consistently. This makes it practical for single-page apps, where navigating between routes is a common source of leaks.

The README lists a few limitations worth knowing: fuite focuses on the main frame, so it won't find leaks in cross-origin iframes or web workers, and it ignores native browser memory such as JIT overhead. It also relies on Chromium-specific tooling (heap snapshots, getEventListeners, queryObjects), so Safari and Firefox leaks are out of reach. Unminified source code produces more readable results.

How engineers can use it

The fastest way to start is running it against a local dev server:

npx fuite https://example.com

For more useful results, the README documents several options:

  • -o report.json writes a full JSON report, including the source line where a leaking event listener was declared.
  • -H saves the raw heap snapshot files in /tmp so you can open them in Chrome DevTools manually.
  • -i 13 or -i 17 raises the iteration count when the default of 7 produces false positives.
  • --setup ./login.mjs runs a Puppeteer-based setup function, which is the documented way to handle login flows.
  • --scenario ./myScenario.mjs lets you write a custom ES module exporting an iteration(page, data) function plus optional setup, teardown, and waitForIdle hooks. The README suggests examples like opening a modal and pressing Escape, or hovering a tooltip.

For programmatic use, import { findLeaks } from 'fuite' returns an async iterable, which fits naturally into a test suite or CI job. The output object's exact shape isn't fully specified yet, so the README points to the TypeScript types in the repo.

One practical note from the README: analyzing large heaps can exhaust Node's default memory. The documented workaround is NODE_OPTIONS=--max-old-space-size=8000 fuite <url>, but that requires installing fuite locally or globally with npm i -g fuite, since NODE_OPTIONS does not work with npx.