Skip to content

Instantly share code, notes, and snippets.

@tomschall
Created May 15, 2025 05:32
Show Gist options
  • Save tomschall/011d94ac46fc46e1fdb363ff778f2f18 to your computer and use it in GitHub Desktop.
Save tomschall/011d94ac46fc46e1fdb363ff778f2f18 to your computer and use it in GitHub Desktop.
JavaScript Runtime Hacking – 10 Powerful Methods

🔧 JavaScript Runtime Hacking – 10 Powerful Methods

A curated list of powerful techniques to manipulate JavaScript code at runtime – great for debugging, prototyping, or reverse engineering frontend behavior directly in the browser (yes, even on mobile).

These methods allow you to inspect, intercept, or override behavior in real time, without changing the actual source code or deploying anything new.


1. Monkey Patching 🐒

Modify existing functions or methods during runtime.

Use this to extend or replace functionality in third-party code or libraries.

const originalLog = console.log;
console.log = (...args) => {
  originalLog("[MonkeyLog]", ...args);
};

Useful for debugging, enhancing or hotfixing behavior live.


2. Object.defineProperty 🛠️

Intercept or override built-in properties.

This lets you manipulate core browser APIs like navigator, window, or DOM properties.

Object.defineProperty(navigator, 'userAgent', {
  get: () => "HACKED-BROWSER/1.0"
});

3. Proxy Objects 🧪

Gain full control over any object’s access and mutation.

A powerful way to observe or modify how objects are used.

const data = { secret: 42 };
const proxy = new Proxy(data, {
  get(target, prop) {
    console.log("Accessed:", prop);
    return target[prop];
  }
});

4. Override fetch / XHR 🌐

Patch network requests globally.

This allows you to intercept or fake responses, test error handling, or track API usage.

const originalFetch = window.fetch;
window.fetch = async (...args) => {
  console.log("[fetch]", ...args);
  return originalFetch(...args);
};

You can also patch XMLHttpRequest methods like open and send to intercept old-school XHR calls.


5. Eval and Function 🧬

Run dynamic code (use with caution).

Dynamically build and execute code in real time.

const fn = new Function("a", "b", "return a + b;");
console.log(fn(2, 3));

Note: Using eval or Function() can be dangerous and is discouraged in production code.


6. MutationObserver 👁️

Watch DOM changes in real-time.

Useful when working with dynamic SPAs or third-party widgets that modify the DOM after page load.

const observer = new MutationObserver(console.log);
observer.observe(document.body, { childList: true, subtree: true });

7. Timer Hijacking ⏱️

Intercept setTimeout, setInterval and analyze or log delays.

This is useful for detecting logic that depends on timing or to debug animations.

const originalTimeout = setTimeout;
window.setTimeout = (cb, delay) => {
  console.log(`Timeout set for ${delay}ms`);
  return originalTimeout(cb, delay);
};

8. DevTools Snippets / Bookmarklets 🧭

Reusable live code execution via browser bookmarks or DevTools.

Bookmarklets are JavaScript scripts saved as browser bookmarks. Ideal for mobile testing or quick toggles.

javascript:(function(){ alert('Hi from a Bookmarklet!'); })();

Use DevTools > Snippets to store and reuse complex tools across sessions.


9. getEventListeners (Chrome only) 🎧

Check which DOM elements are bound to which event handlers.

This only works in Chrome’s DevTools console.

getEventListeners(document.querySelector("button"));

Useful for reverse-engineering event logic or troubleshooting ghost interactions.


10. DOM Debug Panel 🧾

Log runtime data into the DOM directly when console isn't available (e.g. on mobile).

function log(msg) {
  const el = document.createElement('pre');
  el.textContent = msg;
  el.style = 'background: #eee; padding: 5px;';
  document.body.appendChild(el);
}
log("Hello from your monkey patch!");

Great fallback for environments where console.log() is inaccessible.


🧠 Bonus: Many more exist!

Other advanced and creative runtime hacks to explore:

🔹 Shadow DOM Manipulation

Access and patch Web Components or custom elements.

document.querySelector('custom-element').shadowRoot.querySelector('button').click();

🔹 Runtime CSS Injection

Change styles without touching the stylesheet.

const style = document.createElement('style');
style.textContent = 'body { background: hotpink !important; }';
document.head.appendChild(style);

🔹 Overwrite History APIs

Monitor or hijack navigation behavior.

const pushState = history.pushState;
history.pushState = function(...args) {
  console.log('Navigating to', args);
  return pushState.apply(history, args);
};

🔹 JS Memory Profiling

Inspect memory usage during runtime (experimental in most browsers).

console.log(performance.memory);

🔹 Dynamic Module Loading

Load JS modules at runtime – ideal for lazy loading or debugging.

import('https://cdn.jsdelivr.net/npm/lodash-es').then(_ => {
  console.log(_.chunk(['a','b','c','d'], 2));
});

Tom, these tools give you Jedi powers in any JS app – mobile or desktop. Use them wisely ⚔️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment