{"id":13152,"library":"esniff","title":"esniff: Low Footprint JavaScript Parser","description":"esniff is a specialized, low-footprint JavaScript source code parser designed for use cases that require syntax-aware analysis without needing to construct a full Abstract Syntax Tree (AST). It excels at tasks like finding specific function calls or property accesses by navigating the code based on syntax rules, which is more robust than regular expression matching. The current stable version is 2.0.1, released in February 2024. The package maintains a relatively active release cadence, with several minor and patch updates and a major breaking change (v2.0.0) in early 2024. Its key differentiator is its focus on efficiency and targeted code fragment detection over comprehensive AST generation, making it suitable for performance-critical analysis where a full AST would be overkill.","status":"active","version":"2.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/medikoo/esniff","tags":["javascript","sniff","analyze","ast","parse","syntax","sniffer","detective","detect"],"install":[{"cmd":"npm install esniff","lang":"bash","label":"npm"},{"cmd":"yarn add esniff","lang":"bash","label":"yarn"},{"cmd":"pnpm add esniff","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While `require` syntax is shown in examples, modern Node.js applications should use ESM `import`. esniff primarily works with a functional `executor` pattern in v2.x.","wrong":"const esniff = require('esniff');","symbol":"esniff","correct":"import esniff from 'esniff';"},{"note":"Since v2.0.0, utility modules like `accessedProperties` and `function` were moved under the `utils/` subdirectory.","wrong":"import accessedProperties from 'esniff/accessed-properties';","symbol":"accessedProperties","correct":"import accessedProperties from 'esniff/utils/accessed-properties';"},{"note":"The `function` utility, used to find function invocations, was moved to `esniff/utils/function` in v2.0.0. The import is for a default export, often aliased for clarity.","wrong":"import findFunctionCalls from 'esniff/function';","symbol":"findFunctionCalls","correct":"import findFunctionCalls from 'esniff/utils/function';"}],"quickstart":{"code":"import esniff from 'esniff';\n\nconst parseRequires = (code) => {\n  return esniff(code, (emitter) => {\n    emitter.on('trigger:r', (accessor) => {\n      if (accessor.previousToken === '.') return; // Avoid 'foo.require'\n      if (!accessor.skipCodePart('require')) return;\n      accessor.skipWhitespace();\n      accessor.collectScope(); // Collects content within parentheses\n    });\n  });\n};\n\nconst codeExample = `\n  const dep1 = require('module-a');\n  var dep2 = global.require('module-b');\n  function foo() {\n    return require('module-c');\n  }\n  console.log('No require here');\n`;\n\nconst results = parseRequires(codeExample);\nconsole.log(results);\n/* Expected output for 'require('foo/bar')' example in README:\n[ { type: 'scope', point: 17, column: 17, line: 1, raw: \"'foo/bar'\" } ]\nNote: Actual output will vary based on the full codeExample above. */","lang":"javascript","description":"Demonstrates how to use `esniff` to parse all `require()` calls within a given code string, leveraging the `trigger` event and `accessor` methods."},"warnings":[{"fix":"Rewrite calls to `esniff` to use the new `executor` function signature, interacting with the provided `emitter` and `accessor` object. Refer to the v2.0.0 documentation for the updated API.","message":"The main `esniff` interface changed significantly in v2.0.0. It moved from `esniff(code, trigger, callback)` to `esniff(code, executor)`, where `executor` receives an `emitter` for controlling the parsing process.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review existing code analysis logic to ensure compatibility with modern ECMAScript identifier rules. No direct code fix for `esniff` itself, but the interpretation of results might change.","message":"In v2.0.0, the resolution of property and variable names now adheres to ES2015+ language rules, rather than the older ES5 rules. This may cause changes in how certain identifiers are recognized or handled, potentially leading to different analysis results for older or non-standard code.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Update import paths for all affected utility modules to include the `utils/` prefix. For example, `require('esniff/accessed-properties')` becomes `require('esniff/utils/accessed-properties')`.","message":"Several utility modules, such as `ensure-string-literal`, `is-string-literal`, `is-var-name-valid`, `accessed-properties`, and `function`, were relocated to a `utils/` subdirectory in v2.0.0. Direct imports to their previous paths will now fail.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure that code passed to `esniff` is syntactically valid. Consider pre-validating code with a linter or a more robust parser if syntax error detection is required.","message":"esniff assumes the input code is syntactically correct and will not report syntax errors. Providing malformed code may lead to unexpected or nonsensical results.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Be aware of this specific edge case. If such code patterns are expected, manual pre-processing or alternative parsing might be necessary for those specific code fragments. Most real-world code does not exhibit this pattern.","message":"esniff has a known limitation where a division operator (`/`) directly following an object literal (e.g., `x = { foo: 'bar' } / 14`) may be incorrectly interpreted as the start of a regular expression, producing incorrect results.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update your `esniff` calls to match the v2.0.0 `esniff(code, executor)` signature. The second argument should be a function that receives an `emitter`.","cause":"Attempting to use the pre-v2.0.0 API signature with a v2.x version of esniff.","error":"TypeError: esniff is not a function or esniff is not callable"},{"fix":"Change the import path to include the `utils/` subdirectory. For example, `require('esniff/accessed-properties')` should be `require('esniff/utils/accessed-properties')`.","cause":"Attempting to import a utility module from its old path after the v2.0.0 breaking change.","error":"Error: Cannot find module 'esniff/accessed-properties'"},{"fix":"For modern Node.js environments configured for ESM (e.g., `\"type\": \"module\"` in `package.json`), use `import esniff from 'esniff';` instead of `const esniff = require('esniff');`. If both ESM and CJS are needed, ensure dual-package authoring or use a bundler that handles interoperability.","cause":"Using CommonJS `require()` syntax in an ESM module context without proper configuration or transpilation.","error":"ReferenceError: require is not defined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}