{"id":14320,"library":"watch-detector","title":"Watch Detector","description":"The `watch-detector` utility identifies and selects the optimal file watcher mechanism for use with the `sane` library. It prioritizes a valid `watchman` installation on the system, falling back to Node.js's built-in watcher if `watchman` is unavailable or not correctly configured. The current stable version is 1.0.2. Release cadence appears sporadic, with maintenance updates typically driven by upstream `sane` or `watchman` compatibility issues. Its primary differentiator is abstracting the complex logic for choosing between `watchman` and Node's native file system watchers, simplifying `sane` configuration for applications that require robust and performant file monitoring, such as build tools or development servers (e.g., Ember CLI). It aims to provide the best possible performance while offering a reliable fallback, enabling developers to integrate efficient file system observation without needing to implement manual detection logic.","status":"active","version":"1.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/chrmod/watch-detector","tags":["javascript"],"install":[{"cmd":"npm install watch-detector","lang":"bash","label":"npm"},{"cmd":"yarn add watch-detector","lang":"bash","label":"yarn"},{"cmd":"pnpm add watch-detector","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This library is designed to provide optimal watcher options specifically for the `sane` package.","package":"sane","optional":false}],"imports":[{"note":"While CommonJS `require` works, ES module `import` is preferred in modern Node.js environments. The library primarily provides a default export.","wrong":"const WatchDetector = require('watch-detector');","symbol":"WatchDetector","correct":"import WatchDetector from 'watch-detector';"}],"quickstart":{"code":"import WatchDetector from 'watch-detector';\nimport sane from 'sane';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst projectRoot = path.resolve(__dirname, 'temp-project'); // Replace with your actual project root\n\n// Ensure a directory exists for sane to watch\nimport fs from 'fs';\nif (!fs.existsSync(projectRoot)) {\n  fs.mkdirSync(projectRoot, { recursive: true });\n}\n\n// Instantiate the detector. Optional 'ui' and 'fs' instances can be passed.\n// For simplicity, we'll use defaults here.\nconst detector = new WatchDetector();\n\nconst saneOptions = {\n  glob: ['**/*.js', '**/*.css'], // Only watch JS and CSS files\n  ignored: ['node_modules/**'] // Ignore node_modules\n};\n\nasync function setupWatcher() {\n  try {\n    // findBestWatcherOption returns an object with `watcher` key (e.g., 'watchman' or 'node')\n    const options = await detector.findBestWatcherOption(saneOptions);\n    console.log(`Detected best watcher: ${options.watcher}`);\n\n    const watcher = sane(projectRoot, options);\n\n    watcher.on('change', function (filepath, root, stat) {\n      console.log('file changed', filepath, root, stat ? stat.mtime : '');\n    });\n\n    watcher.on('add', function (filepath, root, stat) {\n      console.log('file added', filepath, root, stat ? stat.mtime : '');\n    });\n\n    watcher.on('delete', function (filepath, root) {\n      console.log('file deleted', filepath, root);\n    });\n\n    console.log(`Watching ${projectRoot} with ${options.watcher} watcher...`);\n\n    // To demonstrate, create a file after a delay\n    setTimeout(() => {\n      const filePath = path.join(projectRoot, 'test-file.js');\n      fs.writeFileSync(filePath, '// This is a test file\\nconsole.log(\"Hello\");');\n      console.log(`Created ${filePath}`);\n    }, 2000);\n\n    // Clean up after 5 seconds\n    setTimeout(() => {\n      watcher.close();\n      console.log('Watcher closed.');\n      // fs.rmSync(projectRoot, { recursive: true, force: true }); // Uncomment to clean up temp dir\n    }, 5000);\n\n  } catch (error) {\n    console.error('Error setting up watcher:', error);\n  }\n}\n\nsetupWatcher();","lang":"javascript","description":"This quickstart demonstrates how to instantiate `WatchDetector`, use it to find the best `sane` watcher option, and then set up a `sane` instance to monitor a directory for changes. It includes a simple file creation to trigger the watcher."},"warnings":[{"fix":"Review `sane`'s error handling and events. Instead of relying on `watch-detector`'s internal warning, monitor the `sane` watcher's lifecycle and potential error events (e.g., 'error' event on the `sane` watcher instance) to detect `watchman` or other watcher failures.","message":"The warning message \"Could not start watchman\" was removed in version 1.0.0. Applications that previously relied on this specific warning for `watchman` failure detection will no longer receive it and may need to implement alternative error handling for `sane`'s watcher initialization.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Ensure `watchman` is installed, up-to-date, and correctly configured on the operating system. Check `watchman --version` and refer to the `watchman` documentation for troubleshooting common installation or permission issues. Monitor `sane`'s error events closely.","message":"This package acts as an intermediary for `sane`. While it detects the 'best' watcher, underlying `watchman` issues (e.g., outdated version, incorrect permissions, system limits) can still cause `sane` to fail or behave unexpectedly. `watch-detector` helps select, but doesn't guarantee, a flawless `watchman` setup.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Do not attempt to configure `watch-detector` to use `fs-events`. Rely on the `watchman` or `node` watcher options as provided by `findBestWatcherOption`. If `fs-events` is critical for your use case, you may need to use `sane` directly and configure `fs-events` manually, bypassing `watch-detector`.","message":"The README mentions `fs-events` as 'future options'. This indicates that `fs-events` is not currently supported as a watcher option by `watch-detector` and attempting to configure it will likely result in an unsupported watcher error or fallback to less efficient options.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"search_vec":"'1.0.2':53 'abstract':74 'aim':112 'appear':56 'applic':93 'back':32 'best':116 'build':103 'built':37 'built-in':36 'cadenc':55 'choos':79 'cli':110 'compat':68 'complex':76 'configur':47,91 'correct':46 'current':49 'detect':137 'detector':2,6 'develop':106,125 'differenti':72 'driven':62 'e.g':108 'effici':128 'ember':109 'enabl':124 'fall':31 'fallback':123 'file':13,86,99,129 'identifi':8 'implement':135 'instal':27 'integr':127 'issu':69 'javascript':139 'librari':21 'logic':77,138 'mainten':59 'manual':136 'mechan':15 'monitor':100 'nativ':85 'need':133 'node':83 'node.js':34 'observ':131 'offer':120 'optim':12 'perform':98,118 'possibl':117 'primari':71 'priorit':23 'provid':114 'releas':54 'reliabl':122 'requir':95 'robust':96 'sane':20,65,90 'select':10 'server':107 'simplifi':89 'sporad':57 'stabl':50 'system':30,87,130 'tool':104 'typic':61 'unavail':43 'updat':60 'upstream':64 'use':17 'util':7 'valid':25 'version':51 'watch':1,5 'watch-detector':4 'watcher':14,39,88 'watchman':26,41,67,81 'without':132","created_at":"2026-04-20T01:59:05.955922+00:00","updated_at":"2026-04-20T01:59:05.955922+00:00","problems":[{"fix":"Verify `watchman` is installed and running (`watchman --version`, `watchman status`). Check `watchman` logs for errors. Ensure sufficient system resources (e.g., increase `fs.inotify.max_user_watches` on Linux). Reinstall `watchman` if necessary.","cause":"The `watchman` daemon or client could not be initialized by `sane`, likely due to an issue with the `watchman` installation, configuration, or system resources (e.g., too many watches).","error":"Error: watchman watcher failed to start"},{"fix":"Increase the system limit for file watchers (e.g., on Linux: `echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`). Consider using `watchman` if not already, as it's more efficient with system resources for large watch sets.","cause":"The operating system's limit on the number of files that can be watched simultaneously has been exceeded, a common issue when `node`'s default watcher is used on large projects.","error":"Error: ENOSPC: System limit for number of file watchers reached"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/chrmod/watch-detector","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/watch-detector","openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}