mrkeyoor.com_
Wed 23 Sept 00:36 UTC
npmUtilsupdated 22 Sept 2026

detective-vue2 review

detective-vue2 3.0.1 takes the source text of one Vue single-file component and lists import specifiers found in its script blocks and in Sass, SCSS, Less, or Stylus styles. It parses the container with @vue/compiler-sfc, then hands each block to a language-specific detective. The output is a flat array such as ['vue', './UserCard.vue', './tokens.scss']; it does no path resolution or recursive graph building. The name is historical because the README covers Vue 2 and Vue 3 syntax. Release 3.0.1 fixed calls that omit the options object, while the 3.x line also requires modern Node and ships as ESM.

Verdict

detective-vue2 3.0.1 took 5.3 seconds and 39 MB across 49 installed packages in our sandbox, then failed a browser-targeted bundle, so it fits Node-based SFC analysis inside a larger graph pipeline. Install it only if script and preprocessor imports cover your dependency model; templates, plain CSS, external blocks, and path resolution remain your work.

We installed it

Lab card: what happened when we installed detective-vue2Screenshot of detective-vue2 documentation
Install✓ · 5.3s49 packages on disk · 39 MB
ImportESM import works · require() works · ESM package with exports map
Browsern/acould not be bundled for the browser (Node-only code, most likely)
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does detective-vue2 install cleanly?

Yes. In a fresh container with an empty cache, npm install detective-vue2 finished in 5 seconds, leaving 49 packages and 39 MB on disk. npm audit reported no known vulnerabilities.

Can detective-vue2 run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does detective-vue2 work with both ESM and CommonJS?

Yes. Both import 'detective-vue2' and require('detective-vue2') worked in Node 22 in our run. The package is published as ESM with an exports map.

Does detective-vue2 include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

detective-vue2 or @vue/compiler-sfc: which should you use?

@vue/compiler-sfc: Choose it when you need to inspect templates, external src blocks, or custom SFC metadata yourself. detective-vue2 3.0.1 took 5.3 seconds and 39 MB across 49 installed packages in our sandbox, then failed a browser-targeted bundle, so it fits Node-based SFC analysis inside a larger graph pipeline.

When should you not use detective-vue2?

You need a ready-to-query project graph; the return value contains unresolved strings from one component and has no recursion or cycle detection

API stability4/5Version 3.0.1 exposes one synchronous function that accepts component text plus an optional options object and returns an array of strings. The patch release specifically added a default value for omitted options, while 3.0 moved the package to ESM and dropped Node versions below 20.19. Its small public surface is easy to wrap, but delegated parser options and errors remain part of the practical contract without a local compatibility layer.
Docs2/5The README is 31 lines long and covers installation, ESM import, CommonJS loading, and claimed Vue 2 and Vue 3 support. It says an AST is accepted even though index.js throws 'content is not a string' for non-string input. Readers must inspect source or dependency documentation to learn about supported style languages, forwarded options, duplicate results, ignored plain CSS and templates, or the lack of file resolution.
Maintenance5/5Version 3.0.1 was published on June 6, 2026, and the repository received dependency updates through August 12, 2026. Recent commits include the ESM migration, the Node 20 floor, a Vitest switch, and fixes to option forwarding. GitHub currently reports 0 open issues and PRs, though that quiet queue and one star also mean there is little public user discussion to reveal edge cases.
Ecosystem3/5The npm endpoint counted 3,805,319 downloads in the week ending August 24, 2026, while the GitHub repository has one star. Much of its usefulness comes from compatibility with the Dependents scanner family and consumers such as precinct or dependency-tree. There are no bundled TypeScript types, plugins, resolver layer, or browser build, so the surrounding ecosystem supplies more of the finished tool than this package does.

Use it if

  • You are adding Vue SFC awareness to precinct, dependency-tree, or your own multi-language dependency indexer
  • You need imports from both script and script setup, including blocks marked lang="ts"
  • Your scan must include Sass, SCSS, Less, or Stylus imports embedded in Vue components
  • A list of module strings is the right intermediate result because a later stage already handles aliases and file resolution
Skip it if

Setup reality

Our fresh install of detective-vue2 3.0.1 finished in 5.3 seconds on Node 22. It left 49 packages and 39 MB on disk, with seven direct dependencies plus one TypeScript peer. npm audit reported 0 known vulnerabilities. The package itself was 20 KB unpacked under the MIT license, so most of the installed footprint comes from @vue/compiler-sfc and the delegated scanners.

There are no credentials, config files, postinstall scripts, or native build steps to prepare. Pass the complete component text to the default export. Version 3.0.1 accepts a missing options object, which was the change after 3.0.0. Its engine declaration requires Node 20.19+ or 22.12+, and TypeScript must satisfy the declared peer range when npm installs the package.

The package declares ESM and has an exports map. Both require() and ESM import worked in our sandbox, although CommonJS receives the default export through the package's ESM shape. No declaration files were present. A browser-targeted esbuild bundle failed, so plan to run the scanner in a Node process rather than shipping it to a client bundle.

Parsing is synchronous and accepts only a string. Results keep block order and may contain duplicates when the same path appears in script and script setup. Options flow into the JavaScript, TypeScript, Sass, SCSS, and Less detectives; Stylus receives none. A malformed component or delegated parser error interrupts the call, so batch scanners should catch errors per file and attach the component path.

Patterns

Extract imports from one Vue file scan-component

import {readFile} from 'node:fs/promises';
import detective from 'detective-vue2';

const source = await readFile('src/App.vue', 'utf8');
const imports = detective(source);
console.log(imports);

The argument is source text, not a filename. Version 3.0.1 throws when the value is missing or is not a string.

Use it from CommonJS require-package

const {default: detective} = require('detective-vue2');

const imports = detective('<script>import x from \'./x.js\'</script>');

The package is ESM, but require() worked in our Node 22 sandbox. The callable function is on the default property.

Read imports from script setup scan-script-setup

const imports = detective(`
<script setup lang="ts">
import {ref} from 'vue';
import Card from './Card.vue';
</script>
`);

// ['vue', './Card.vue']

Both script and script setup are scanned. A component tag that appears only in the template produces no result.

Combine normal and setup script imports scan-two-scripts

const imports = detective(`
<script>import config from './config.js'</script>
<script setup>import view from './view.js'</script>
`);

// ['./config.js', './view.js']

Normal script results come before script setup results because index.js visits the blocks in that order.

Deduplicate repeated specifiers remove-duplicates

const imports = detective(`
<script>import x from './shared.js'</script>
<script setup>import y from './shared.js'</script>
`);

const unique = [...new Set(imports)];

The package appends scanner output without deduplication, so the same path can occur more than once.

Exclude TypeScript type imports skip-type-imports

const imports = detective(`
<script setup lang="ts">
import type {Account} from './types';
import {load} from './api';
</script>
`, {skipTypeImports: true});

// ['./api']

skipTypeImports is forwarded to the TypeScript detective. detective-vue2 does not document the delegated option itself.

Find require calls in TypeScript include-require-calls

const imports = detective(`
<script lang="ts">
import api from './api';
const oldClient = require('./old-client');
</script>
`, {mixedImports: true});

mixedImports belongs to detective-typescript and applies when the SFC block has the exact lang="ts" attribute.

Ignore lazy imports exclude-dynamic-imports

const imports = detective(`
<script setup>
import eager from './eager.js';
const load = () => import('./lazy.js');
</script>
`, {skipAsyncImports: true});

// ['./eager.js']

Set skipAsyncImports when your graph should represent eager imports only. Dynamic import paths are otherwise eligible for extraction.

Collect style dependencies scan-preprocessor-styles

const imports = detective(`
<style lang="scss">@import './tokens';</style>
<style lang="less">@import './theme.less';</style>
<style lang="stylus">@require './mixins.styl'</style>
`);

Only Sass, SCSS, Less, and Stylus blocks have scanners. An unlabelled CSS block is skipped.

Include URLs from SCSS include-style-assets

const imports = detective(`
<style lang="scss">
@import './tokens';
.hero { background: url('./hero.webp'); }
</style>
`, {url: true});

The url option reaches the Sass, SCSS, and Less detectives. Stylus is called without the options object.

Index Vue files under a source directory scan-directory

import {readFile, readdir} from 'node:fs/promises';
import {join} from 'node:path';

const graph = {};
for (const name of await readdir('src', {recursive: true})) {
  if (!name.endsWith('.vue')) continue;
  const file = join('src', name);
  graph[file] = detective(await readFile(file, 'utf8'));
}

This maps files to unresolved strings. Alias rules, extension lookup, traversal, and cycle detection need a separate graph layer.

Keep one bad component from stopping a scan isolate-parser-errors

async function inspect(file) {
  try {
    return detective(await readFile(file, 'utf8'));
  } catch (error) {
    return {file, error: error.message};
  }
}

Parsing and extraction are synchronous after the file read. Catch at file scope so a malformed SFC retains its filename in the report.

Alternatives

PackageRegistryPick it when
@vue/compiler-sfcnpmChoose it when you need to inspect templates, external src blocks, or custom SFC metadata yourself
dependency-treenpmChoose it when the deliverable is a recursively resolved file graph instead of raw specifiers
precinctnpmChoose it when one dispatcher must recognize dependencies across several source languages
madgenpmChoose it for project graphs, visual output, and circular dependency reports

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.