DEV Community

sakshsky
sakshsky

Posted on

I built reqscan — a zero-dependency CLI to manage your Node.js dependencies

Ever opened a Node.js project, ran it, and got hit with:

Error: Cannot find module 'axios'
Enter fullscreen mode Exit fullscreen mode

You check package.json. It's not there. You add it. Then five minutes later, a different file throws the same error for a different package. You repeat the process three more times before the app actually starts.

Or the opposite: your package.json has 40 entries and you're pretty sure half of them haven't been imported anywhere in months — but you don't want to manually grep through 200 files to find out.

I got tired of this. So I built reqscan.


What is reqscan?

reqscan is a zero-dependency CLI tool that scans your Node.js project, finds every package you're importing across all your source files, and compares it against your package.json. It tells you exactly what's missing, what's unused, and lets you fix everything in one command.

npx reqscan check
Enter fullscreen mode Exit fullscreen mode

That's it. Point it at any project and it gives you the full picture.


A real example

Say you have a project with these files scattered around:

// src/api.js
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';

// src/db.js
const mongoose = require('mongoose');

// lib/utils.ts
import { format } from 'date-fns';
import type { User } from '@myorg/types';
Enter fullscreen mode Exit fullscreen mode

And your package.json only declares mongoose and jest.

Running reqscan check gives you:

📦 Project: my-app
──────────────────────────────────────────────────
Summary
  Total imports found   : 5
  Declared in pkg.json  : 2
  Already installed     : 1
  Missing (not declared): 4

❌ Missing Packages (not in package.json)
──────────────────────────────────────────────────
  ✗ axios
  ✗ uuid
  ✗ date-fns
  ✗ @myorg/types

💡 Run this to install all missing packages:
   npm install axios uuid date-fns @myorg/types

✅ Already Declared Packages
──────────────────────────────────────────────────
  ✓ mongoose   ^7.0.0

⚠️  Declared but NOT imported in source (possibly unused)
──────────────────────────────────────────────────
  ~ jest (devDependencies)
Enter fullscreen mode Exit fullscreen mode

Then you just run:

npx reqscan install
Enter fullscreen mode Exit fullscreen mode

Done. All four packages installed in one shot.


The commands

Command What it does
reqscan check Scan and report — missing, present, unused
reqscan install Install all missing packages
reqscan clean Remove declared-but-never-imported packages
reqscan fix Install missing + clean unused in one go
reqscan audit Full health report with a score
reqscan list Every dependency with its current status

The one I use most day-to-day is reqscan fix. Drop into any project, run it, and your dependencies are clean.


What it detects

reqscan understands every import style you'd encounter in a modern JS/TS codebase:

// CommonJS
const express = require('express');
require.resolve('some-pkg');

// ESM
import something from 'lodash';
import * as ns from 'ramda';
import { useState } from 'react';

// Side-effect imports
import 'reflect-metadata';

// Dynamic imports
const mod = await import('dynamic-pkg');

// TypeScript type imports (still a real dependency!)
import type { User } from '@myorg/types';
export type { Config } from 'some-lib';

// Re-exports
export { helper } from 'shared-utils';
Enter fullscreen mode Exit fullscreen mode

It also strips comments before scanning, so commented-out imports don't generate false positives. Scoped packages (@babel/core) and subpath imports (date-fns/formatdate-fns) are both handled correctly.

Built-ins (fs, path, node:crypto, etc.) are filtered out automatically. So are node_modules, dist, .next, and the other usual suspects.


Flags that make it CI-friendly

# Preview what would change — no files touched
reqscan fix --dry-run

# Install missing packages as devDependencies
reqscan install --save-dev

# Remove unused without the confirmation prompt (great for scripts)
reqscan clean --force

# Machine-readable output for tooling
reqscan audit --json
Enter fullscreen mode Exit fullscreen mode

The --json flag is particularly useful if you want to build on top of reqscan — pipe it into another tool, write it to a file, diff it across branches, whatever.


Use it programmatically

reqscan also exposes a clean API if you want to integrate it into your own tooling:

const { scanProject } = require('reqscan');

const result = await scanProject('./my-app');

console.log(result.missing);   // ['axios', 'uuid']
console.log(result.unused);    // ['jest']
console.log(result.present);   // ['express', 'mongoose']
Enter fullscreen mode Exit fullscreen mode

Zero config, returns plain arrays. Easy to plug into a custom script, a GitHub Action, or a monorepo tool.


Zero dependencies

The whole thing is zero external dependencies. No third-party parsers, no commander, no chalk. The bundle is just the source files — under 300 lines of scanner logic, a small color helper that respects NO_COLOR and non-TTY environments, and the CLI entry point.

That means it installs instantly, works anywhere Node ≥ 14 runs, and won't pollute your node_modules with its own transitive deps.


Install it

Global (recommended for everyday use):

npm install -g reqscan
Enter fullscreen mode Exit fullscreen mode

Or just use npx — no install needed:

npx reqscan check
npx reqscan fix
Enter fullscreen mode Exit fullscreen mode

Or add it to a project for CI:

npm install --save-dev reqscan
Enter fullscreen mode Exit fullscreen mode
{
  "scripts": {
    "deps:check": "reqscan check",
    "deps:fix": "reqscan fix --force"
  }
}
Enter fullscreen mode Exit fullscreen mode

What's next

A few things on the roadmap:

  • reqscan outdated — surface packages with newer versions available
  • reqscan upgrade — update outdated packages interactively
  • .reqscanrc config file for per-project ignore lists
  • Monorepo / workspace support

If you have a use case reqscan doesn't handle, or hit a false positive/negative on a pattern it's not detecting, open an issue. Real-world projects have edge cases I haven't seen yet.


npm: npmjs.com/package/reqscan

Give it a try and let me know what you think in the comments. And if it saves you time, a ⭐ on GitHub goes a long way.

Top comments (0)