Monkey Patching: Fixing Code at Runtime

Lecture



In computer programming, monkey patching is a technique used to dynamically update the behavior of a piece of code at run time. It is used to extend or modify the runtime code of dynamic languages (such as Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.) without altering the original source code.

Etymology

The term «monkey patch» appears to have come from an earlier term, «guerrilla patch», which referred to changing code stealthily – and possibly incompatibly with other such patches – at run time. The word «guerrilla», almost a homophone of «gorilla», became «monkey», possibly to make the patch sound less intimidating.

An alternative etymology is that the word refers to «monkeying about» with the code (messing around with it).

Despite the name, monkey patching is sometimes an official way of extending a program. For example, web browsers such as Firefox and Internet Explorer used to encourage this, although modern browsers (including Firefox) now have an official extension system.

Definitions

The definition of the term varies depending on the community using it. In Ruby,, Python and many other dynamic programming languages, the term «monkey patch» refers only to dynamic modifications of a class or module at run time, motivated by the intent to patch existing third-party code as a workaround for a bug or a feature that does not behave as desired. Other forms of modifying classes at run time have different names, depending on their different purposes. For example, in Zope and Plone, security patches are often delivered using dynamic class modification, but they are called hot fixes.

Applications

Monkey patches are used to:

  • Replace methods / classes / attributes / functions at run time, for example to stub out a function during testing;
  • Modify or extend the behavior of a third-party product without maintaining a private copy of the source code;
  • Apply the result of a patch at run time to the state in memory instead of to the source code on disk;
  • Distribute security or behavioral fixes that live alongside the original source code (an example of this would be distributing a fix as a plugin for the Ruby on Rails platform);

Pitfalls

Malicious, incompetently written and/or poorly documented monkey patches can lead to problems:

  • They can cause upgrade problems when the patch makes assumptions about the patched object that are no longer true; a new release may well break the patch. For this reason, monkey patches are often made conditional and applied only when needed.
  • If two modules attempt to monkey patch the same method, one of them (whichever runs last) «wins» and the other patch has no effect, unless the monkey patches are written in a pattern such as alias_method_chain.
  • They create a discrepancy between the original source code and the observed behavior, which can confuse anyone unaware that the patch exists. For example, the Linux kernel detects proprietary and other third-party modules, such as the Nvidia driver, that tamper with kernel structures, so that developers do not waste time debugging a problem they cannot fix.
  • They can be written with malicious code to attack the host program or one another. For example, in 2009 Giorgio Maone, the developer of NoScript, attacked the Adblock Plus extension for Firefox by adding exceptions so that ads on his own sites would work. The offending code also ensured that if the user tried to remove the exceptions, they would be added again. The quarrel provoked widespread outrage, leading to a war between new ad-blocking rules that were offered to users, after which Maone sabotaged the new ones, eventually prompting Mozilla to step in and change its add-on policy.

Examples

The following Python example adjusts the value of pi from Python's standard math library so that it conforms to the Indiana Pi Bill.

>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 3.2   # monkey-patch the value of Pi in the math module
>>> math.pi
3.2 

Let's look at how you can build an interceptor for the Fetch API using monkey patching in JavaScript:

const { fetch: originalFetch } = window;

window.fetch = async (...args) => {
    let [resource, config ] = args;
    // request interceptor here
    const response = await originalFetch(resource, config);
    // response interceptor here
    return response;
};

See also

  • Polyfill
  • Aspect-oriented programming
  • Category in Objective-C
  • Dynamic loading
  • Extension method in C#
  • Self-modifying code
created: 2024-03-07
updated: 2026-03-09
190



Was this answer useful?
Choose a quick rating so we can improve the next answer for you.
How satisfied are you?


Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Software and information systems development"

Terms: Software and information systems development