{"id":13359,"library":"istanbul-lib-instrument","title":"Istanbul Library Instrument","description":"istanbul-lib-instrument serves as the core engine within the Istanbul.js ecosystem for transforming JavaScript source code into an instrumented form suitable for code coverage analysis. It injects tracking statements (for lines, functions, branches, and statements) into code. The library, currently at version 6.0.3 (released June 2024), is an active component of the `istanbuljs` monorepo, which receives regular updates across its packages to support modern JavaScript features and tooling. Its key differentiator is its reliance on Babel for its instrumentation process, providing two primary modes of operation: a direct programmatic API for straightforward source code transformation, and a `programVisitor` function designed for seamless integration within custom Babel plugins, which is the recommended approach for developers already utilizing Babel in their build pipelines.","status":"active","version":"6.0.3","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/istanbuljs/istanbuljs","tags":["javascript","coverage","istanbul","js","instrumentation"],"install":[{"cmd":"npm install istanbul-lib-instrument","lang":"bash","label":"npm"},{"cmd":"yarn add istanbul-lib-instrument","lang":"bash","label":"yarn"},{"cmd":"pnpm add istanbul-lib-instrument","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as a parameter ('types' object) for the `programVisitor` function when integrating with custom Babel plugins.","package":"@babel/types","optional":true}],"imports":[{"note":"This is the primary factory function for programmatic instrumentation. CommonJS `require` works but ESM `import` is preferred.","wrong":"const createInstrumenter = require('istanbul-lib-instrument').createInstrumenter;","symbol":"createInstrumenter","correct":"import { createInstrumenter } from 'istanbul-lib-instrument';"},{"note":"While `createInstrumenter` returns an `Instrumenter` instance, the class itself can be imported for extending or advanced use cases. It's a named export, not a default.","wrong":"import Instrumenter from 'istanbul-lib-instrument';","symbol":"Instrumenter","correct":"import { Instrumenter } from 'istanbul-lib-instrument';"},{"note":"Used for integration into Babel plugins. It expects a `babel-types` instance as an argument for its visitor functions.","wrong":"const { programVisitor } = require('istanbul-lib-instrument');","symbol":"programVisitor","correct":"import { programVisitor } from 'istanbul-lib-instrument';"}],"quickstart":{"code":"import { createInstrumenter } from 'istanbul-lib-instrument';\n\nconst codeToInstrument = `\nfunction calculate(a, b) {\n  if (a > 0) {\n    return a + b;\n  } else {\n    return b;\n  }\n}\nconst result = calculate(10, 5);\nconsole.log(result);\n`;\n\nconst filename = '/app/src/example.js'; // Crucial for unique coverage reporting\n\ntry {\n  const instrumenter = createInstrumenter({\n    coverageVariable: '__CUSTOM_COVERAGE_OBJ__', // Define a custom global variable\n    preserveComments: true,\n    compact: false, // Output human-readable instrumented code\n    esModules: true, // Enable ES module syntax support\n    produceSourceMap: true // Generate a source map for remapping coverage\n  });\n\n  const instrumentedCode = instrumenter.instrumentSync(codeToInstrument, filename);\n  const sourceMap = instrumenter.lastSourceMap();\n\n  console.log('--- Original Code ---');\n  console.log(codeToInstrument);\n  console.log('\\n--- Instrumented Code ---');\n  console.log(instrumentedCode);\n  console.log('\\n--- Generated Source Map (snippet) ---');\n  // Source map objects can be large, showing a snippet for brevity\n  console.log(JSON.stringify(sourceMap?.toJSON() || {}, null, 2).substring(0, 500) + '...');\n\n  // To obtain coverage, execute the instrumented code in a global context\n  // where the coverage variable is defined, then retrieve it.\n  // Example (Node.js):\n  // global.__CUSTOM_COVERAGE_OBJ__ = {};\n  // eval(instrumentedCode);\n  // console.log('\\n--- Coverage Object (after execution) ---');\n  // console.log(JSON.stringify(global.__CUSTOM_COVERAGE_OBJ__, null, 2));\n\n} catch (error) {\n  console.error('Instrumentation failed:', error);\n}","lang":"typescript","description":"Demonstrates how to use `createInstrumenter` and `instrumentSync` to programmatically instrument a JavaScript string, generate source maps, and log the resulting instrumented code. It also highlights options for customizing the instrumentation process."},"warnings":[{"fix":"Review `v0-changes.md` for specific migration steps. Update your codebase to align with Babel-based instrumentation practices, particularly if you were accessing internal APIs or custom parser options.","message":"Version 1.1.x introduced a fundamental architectural change by transitioning to Babel for JavaScript parsing and transformation. This replaced the previously used parser/generator, potentially breaking existing integrations that relied on internal AST structures or specific behaviors of the pre-Babel implementation. Consult `v0-changes.md` for detailed incompatibilities.","severity":"breaking","affected_versions":">=1.1.0"},{"fix":"Ensure you are using the latest stable version of `istanbul-lib-instrument` (>=6.0.3 for `importAttributes` support). If using `programVisitor` with your own Babel setup, ensure your Babel configuration includes all necessary plugins to parse your source code.","message":"`istanbul-lib-instrument` relies on Babel for parsing, meaning support for new JavaScript syntax features (e.g., decorators, pipeline operator, `importAttributes`) depends on the internal Babel version and its configured parser plugins. An older version might not correctly process modern syntax, leading to `SyntaxError`.","severity":"gotcha","affected_versions":"<6.0.3"},{"fix":"Always pass a valid `inputSourceMap` to `instrumentSync` if your code is already transpiled. Ensure your build process is correctly configured to generate and pass through source maps at each transformation step. Validate source map chains with tools like `source-map-explorer`.","message":"While `istanbul-lib-instrument` can generate source maps for instrumented code, achieving accurate coverage reporting with transpiled or bundled code (e.g., TypeScript, Webpack) heavily depends on correct input source maps and proper integration with `istanbul-lib-source-maps`. Misconfigured build tools or source map generation can lead to misaligned or incorrect coverage data.","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 `istanbul-lib-instrument` to its latest version to ensure support for newer JavaScript syntax. If using the `programVisitor` with your own Babel setup, verify that your Babel configuration (especially `parserPlugins`) includes the necessary plugins for the syntax in your source code.","cause":"The JavaScript code being instrumented contains syntax features (e.g., new ECMAScript proposals, TypeScript syntax) that are not supported by the internal Babel parser within `istanbul-lib-instrument` or by its default configuration.","error":"SyntaxError: Unexpected token '...', 'const' (or similar Babel parsing errors)"},{"fix":"Before executing instrumented code, ensure the global coverage object is defined. In Node.js, `global.__coverage__ = {};`. In browsers, `window.__coverage__ = {};`. Confirm the `coverageVariable` option used during instrumentation matches the variable you are checking.","cause":"The global coverage variable (default: `__coverage__`, or a custom name set via `coverageVariable` option) was not initialized or accessible in the JavaScript runtime environment before the instrumented code was executed.","error":"ReferenceError: __coverage__ is not defined (or custom variable name)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}