{"id":15052,"library":"watchjs","title":"Watch.js Object Observer","description":"Watch.js is a compact, browser-compatible JavaScript library designed to implement the Observer design pattern, allowing developers to monitor changes to JavaScript objects and their attributes without altering existing development methodologies. It enables watching single attributes, multiple attributes, or all attributes of an object, invoking a callback function upon detected mutations. The library, last updated around 9 years ago (with version 1.2.0 mentioned in its README but 0.0.0 on npm), primarily operates by polluting the global scope, exposing `watch` and `unwatch` functions, and a `WatchJS` object. While simple to integrate via a direct script inclusion, its reliance on global scope and direct object mutation for reactivity is largely superseded by modern JavaScript features like Proxies and reactive frameworks. It is considered abandoned, with no active maintenance or updates.","status":"abandoned","version":"0.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/melanke/Watch.JS","tags":["javascript","watch","object","changes"],"install":[{"cmd":"npm install watchjs","lang":"bash","label":"npm"},{"cmd":"yarn add watchjs","lang":"bash","label":"yarn"},{"cmd":"pnpm add watchjs","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Watch.js injects 'watch' and 'unwatch' as global functions (window.watch) and 'WatchJS' as a global object (window.WatchJS) when included via a script tag. It does not provide modern module exports like CommonJS or ESM.","wrong":"import { watch } from 'watchjs';","symbol":"watch","correct":"<script src=\"path/to/watch.js\"></script>\n// Then access as `window.watch` or simply `watch` if in global scope"},{"note":"See notes for the 'watch' function regarding global scope injection.","wrong":"import { unwatch } from 'watchjs';","symbol":"unwatch","correct":"<script src=\"path/to/watch.js\"></script>\n// Then access as `window.unwatch` or simply `unwatch` if in global scope"},{"note":"The global 'WatchJS' object contains utility properties like 'noMore' for controlling watcher behavior. See notes for the 'watch' function.","wrong":"import { WatchJS } from 'watchjs';","symbol":"WatchJS","correct":"<script src=\"path/to/watch.js\"></script>\n// Then access as `window.WatchJS` or simply `WatchJS` if in global scope"}],"quickstart":{"code":"// Include Watch.js via a script tag in your HTML:\n// <script src=\"https://raw.githubusercontent.com/melanke/Watch.JS/master/src/watch.js\"></script>\n\n// defining our object however we like\nvar myObject = {\n\tattribute1: \"initial value\",\n\tattribute2: 123\n};\n\n// defining a 'watcher' for a specific attribute\nwatch(myObject, \"attribute1\", function(prop, action, newValue, oldValue){\n\tconsole.log(`Attribute '${prop}' changed from '${oldValue}' to '${newValue}'. Action: ${action}`);\n});\n\n// defining a 'watcher' for all attributes on the object\nwatch(myObject, function(){\n    console.log(\"Any attribute of myObject changed!\");\n});\n\n// when changing the attribute, its watcher will be invoked\nmyObject.attribute1 = \"new value\";\n\n// changing another attribute will invoke the general object watcher\nmyObject.attribute2 = 456;","lang":"javascript","description":"Demonstrates how to add and trigger watchers for specific or all attributes on a JavaScript object using the global 'watch' function."},"warnings":[{"fix":"Migrate to a modern reactivity solution like ES6 Proxies or a maintained framework/library.","message":"Watch.js is an abandoned library and has not been updated in approximately 9 years. It relies on modifying global object prototypes to detect changes, which can lead to conflicts and unexpected behavior with other libraries or modern JavaScript features. There are no plans for future updates or security patches.","severity":"breaking","affected_versions":">=0.0.0"},{"fix":"Wrap the library in an IIFE or namespace if you must use it, though migration to a modern solution is strongly recommended.","message":"The library pollutes the global scope by exposing 'watch', 'unwatch', and 'WatchJS' as global variables (e.g., window.watch). This can lead to naming collisions and make it difficult to integrate into modular JavaScript environments.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Thoroughly test in target environments. Consider browser compatibility polyfills or, ideally, migrate to a modern, actively maintained library.","message":"Watch.js uses deprecated browser mechanisms for object observation and may have 'some bugs with older browsers' as stated in its original README. It does not leverage modern browser APIs like MutationObserver for DOM changes, focusing solely on plain JavaScript objects.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Carefully manage the `WatchJS.noMore` flag within the scope of your watcher functions and ensure it is reset appropriately if you intend for subsequent watchers to execute.","message":"The `WatchJS.noMore = true` flag is a global state mechanism intended to prevent recursive watcher calls. Incorrect usage or failure to understand its lifecycle can lead to watchers not firing when expected or unexpected side effects across different parts of your application.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the watch.js file is included via a <script> tag in your HTML, placed before any code that attempts to use 'watch' or 'unwatch', e.g., <script src=\"path/to/watch.js\"></script>.","cause":"The Watch.js script was not correctly loaded or executed before attempting to call the 'watch' function.","error":"ReferenceError: watch is not defined"},{"fix":"Check if `WatchJS.noMore` is inadvertently set to `true` in a preceding watcher. For deep observation, ensure the correct 'level' parameter is passed to the `watch` function, or consider the library's limitations with deeply nested or dynamically added properties.","cause":"Another watcher might have set `WatchJS.noMore = true;` or the object change is not being deeply observed as intended, or the 'level' parameter for deep watching is not set.","error":"Unexpected behavior: watcher not firing for attribute change."},{"fix":"Ensure the first argument passed to the 'watch' function is a valid, instantiated JavaScript object before attempting to observe it.","cause":"Attempting to watch an object that is null, undefined, or not a plain JavaScript object.","error":"TypeError: Cannot set property '<property>' of undefined"}],"ecosystem":"npm"}