The Shadow Architecture of MouseHunt Improved

How a community project uses custom build pipelines and DOM interception to seamlessly modernize a 15-year-old legacy web app from the outside.

9 min read • View on GitHub • More from MHCommunity

A massive ancient stone fortress surrounded by modern steel scaffolding erected by autonomous robotic drones. The scaffolding contours perfectly to the old stone without piercing it, illustrating the concept of building modern infrastructure around a legacy monolith.
The extension builds a modern interface layer without altering the underlying legacy application.
MHCommunity

Enhance your MouseHunt experience with a variety of improvements and features. Each feature can be enabled or disabled individually to suit your preferences.

— Project Maintainers, GitHub README
Key Takeaways

Hacking the Monolith

The target is a 15-year-old browser game heavily reliant on legacy DOM structures and AJAX calls. For years, the community relied on fragmented userscripts to improve the interface. But traditional userscripts fail at scale. They suffer from style bleed, race conditions, and massive performance overhead when multiple scripts fight for control of the same DOM elements.

Enter mousehunt-improved. It is not just another script. It is a runtime patcher. By building a sophisticated shadow architecture, the maintainers managed to inject a modern, React-like user experience into a legacy PHP and JavaScript monolith without ever touching the original source code.

Compiling CSS into Executable Strings

The project uses a dual-target distribution model. It compiles into both a standard browser extension and a standalone userscript. Supporting both from a single codebase requires a highly customized esbuild pipeline.

The magic happens in the build script. A custom CSSMinifyTextPlugin intercepts CSS imports, minifies them, and returns them as pure text strings. This avoids external file dependencies entirely. By injecting these minified strings directly into the DOM before the page fully renders, the extension prevents the dreaded Flash of Unstyled Content. The legacy app never has a chance to show its original face.

A split-pane view illustrating the build pipeline. On the left
A close-up of a glass syringe filled with a tightly coiled glowing string of typographic characters injecting into a thick braided fiber-optic cable.
Stylesheets are minified into text strings and injected directly into the execution flow.

A Decentralized Micro-Module Architecture

Scaling a community project to over 150 features usually results in spaghetti code. Here, adding a feature is as simple as creating a new folder in the src/modules/ directory with an index.js and a styles.css file. An ImportGlobPlugin dynamically discovers and registers these modules at build time.

This decentralized approach extends to user settings. Each module exports its own configuration schema, which is automatically aggregated to generate the master settings interface.

Intercepting State Without Polling

Most external scripts rely on brittle MutationObserver traps or infinite setInterval loops to watch the DOM for changes. MouseHunt Improved takes a lower-level approach. It uses a companion library to intercept the game's native XMLHttpRequest and fetch events.

By reading the JSON payloads before the legacy application processes them, the extension can update its own UI modules instantaneously. It feels native because it reacts to the exact same network events as the host application.

A vintage telegraph wire running across the frame with a modern digital tap clamped onto it, reading the signals and displaying them on a clean digital readout.
Intercepting network requests provides real-time state awareness without DOM polling.

The End of the Userscript Era

The historical landscape of browser game modification was defined by standalone scripts that overwrote each other's CSS and fought for DOM priority. A unified framework approach solves this.

Feature Fragmented Userscripts Unified Framework (MHI)
State Management Brittle DOM polling (MutationObservers) Native XHR/Fetch interception
UI Consistency CSS collisions and global overrides Scoped CSS injection via text strings
Configuration Hardcoded variables in scripts Centralized, auto-generated settings UI
Contribution Forking entire standalone scripts Drop-in micro-modules

By centralizing the dispatcher, scoping CSS injection, and standardizing the settings API, MouseHunt Improved lowers the barrier to entry for new open-source contributors while delivering a seamless experience to end users.


Sources: MHCommunity/mousehunt-improved, MHCommunity Organization.