<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kevin patil </title>
    <description>The latest articles on DEV Community by kevin patil  (@kevinpatildxd).</description>
    <link>https://dev.to/kevinpatildxd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3962120%2F70904445-4e79-4f42-9740-b7a5fa66af7f.jpeg</url>
      <title>DEV Community: kevin patil </title>
      <link>https://dev.to/kevinpatildxd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevinpatildxd"/>
    <language>en</language>
    <item>
      <title>I built a free CLI that audits your Node.js + React project before you ship</title>
      <dc:creator>kevin patil </dc:creator>
      <pubDate>Mon, 01 Jun 2026 06:49:12 +0000</pubDate>
      <link>https://dev.to/kevinpatildxd/i-built-a-free-cli-that-audits-your-nodejs-react-project-before-you-ship-1peh</link>
      <guid>https://dev.to/kevinpatildxd/i-built-a-free-cli-that-audits-your-nodejs-react-project-before-you-ship-1peh</guid>
      <description>&lt;p&gt;Before shipping anything I'd run through the same mental checklist every time.&lt;/p&gt;

&lt;p&gt;Did I forget any .env keys? Are there packages I added and never used? Did I leave that useState inside an if block?&lt;/p&gt;

&lt;p&gt;Each check was a different tool. npm audit for vulns. depcheck for unused packages (unmaintained, misses a lot). React DevTools for re-renders (browser only, no CI). ESLint for hook violations (needs a whole config setup). Nothing for&lt;br&gt;
  .env files at all.&lt;/p&gt;

&lt;p&gt;So I built devguard. One command.&lt;/p&gt;

&lt;p&gt;npx @kevinpatil/devguard&lt;br&gt;
**  Env validation&lt;br&gt;
**&lt;br&gt;
  This one I needed personally. I've shipped with JWT_SECRET=secret in production before. Not something I want to repeat.&lt;/p&gt;

&lt;p&gt;devguard reads your .env against .env.example and flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing required keys&lt;/li&gt;
&lt;li&gt;Empty values you forgot to fill in&lt;/li&gt;
&lt;li&gt;Weak secrets (secret and changeme both count)&lt;/li&gt;
&lt;li&gt;Type mismatches like PORT=abc&lt;/li&gt;
&lt;li&gt;Malformed URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output looks like this:&lt;/p&gt;

&lt;p&gt;ERRORS (2)&lt;br&gt;
    ✗ DATABASE_URL   missing — required in .env.example&lt;br&gt;
    ✗ JWT_SECRET     insecure value: 'secret'&lt;/p&gt;

&lt;p&gt;WARNINGS (1)&lt;br&gt;
    ⚠ PORT           value 'abc' is not a valid number&lt;br&gt;
** Dependency audit&lt;br&gt;
**&lt;br&gt;
  Three things: unused packages, outdated versions, vulnerabilities.&lt;/p&gt;

&lt;p&gt;Unused detection is pure static analysis. It walks your source files, extracts every import, compares against package.json. No node_modules needed.&lt;/p&gt;

&lt;p&gt;For vulnerabilities it hits OSV.dev (Google's free vuln database) with a single batch POST — all packages at once, not one request per package. No API key required.&lt;/p&gt;

&lt;p&gt;UNUSED (3)&lt;br&gt;
    lodash, uuid, moment&lt;/p&gt;

&lt;p&gt;VULNERABILITIES (1)&lt;br&gt;
    &lt;a href="mailto:express@4.17.1"&gt;express@4.17.1&lt;/a&gt;  CVE-2024-29041  High&lt;/p&gt;

&lt;p&gt;ALTERNATIVES&lt;br&gt;
    moment → dayjs        saves 65KB, same API&lt;br&gt;
    lodash → native ES6   saves 71KB&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React audit&lt;br&gt;
**&lt;br&gt;
  Six checks, all static analysis, no browser needed.&lt;br&gt;
  **Dead imports&lt;/strong&gt; — walks your codebase, builds an import graph, finds components that are defined but used nowhere. Handles circular imports without hanging by tracking visited file paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Re-render risks&lt;/strong&gt; — finds inline objects and functions passed as props:&lt;/p&gt;

&lt;p&gt;// flagged — new object reference on every render&lt;br&gt;
   remove(id)} /&amp;gt;&lt;/p&gt;

&lt;p&gt;Use useMemo for objects, useCallback for functions passed as props.&lt;/p&gt;

&lt;p&gt;Hook violations — catches hooks inside if blocks, loops, and nested functions. The one that burns people most often:&lt;/p&gt;

&lt;p&gt;if (isLoggedIn) {&lt;br&gt;
    const [data, setData] = useState(null)  // violation&lt;br&gt;
  }&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bundle size **— flags heavy packages with alternatives. moment at 67KB, lodash at 71KB, jquery at 87KB.&lt;br&gt;
 **Accessibility&lt;/strong&gt; — static JSX scan. img without alt, div with onClick, anchor without href. Reports file path and line number for each.&lt;br&gt;
 &lt;strong&gt;RSC boundaries&lt;/strong&gt; — for Next.js App Router. Catches useState in server components, browser APIs like window in server components, and server-only imports inside client components.&lt;br&gt;
*&lt;em&gt;A few things I decided early on&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
  No API keys for the core features. Everything that can be done statically, is. The alternatives list is embedded in the source — no external lookup at runtime. Only two outbound APIs: npm registry and OSV.dev, both free with no key&lt;br&gt;
  required.&lt;br&gt;
  All API results are cached at ~/.devguard/cache.json with a 24hr TTL keyed by &lt;a href="mailto:name@version"&gt;name@version&lt;/a&gt;. Repeated runs are nearly instant and work offline.&lt;br&gt;
  No ESLint dependency. I wanted this to work on any project, not just ones with an existing lint setup. The hook violation checker is pure AST parsing via &lt;a class="mentioned-user" href="https://dev.to/babel"&gt;@babel&lt;/a&gt;/parser, which handles JSX and TSX with zero config.&lt;br&gt;
**  CI integration&lt;br&gt;
**&lt;br&gt;
  # Fail the build if any errors are found&lt;br&gt;
  npx @kevinpatil/devguard --strict&lt;/p&gt;

&lt;p&gt;# JSON output for custom pipelines&lt;br&gt;
  npx @kevinpatil/devguard --json&lt;/p&gt;

&lt;p&gt;# SARIF report for GitHub Code Scanning&lt;br&gt;
  npx @kevinpatil/devguard --sarif&lt;/p&gt;

&lt;p&gt;**  Try it&lt;br&gt;
**&lt;br&gt;
  npx @kevinpatil/devguard&lt;/p&gt;

&lt;p&gt;MIT licensed, free, actively maintained. If it catches something useful or misses something it should catch, open an issue — I read them all.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/kevinpatildxd/devguard" rel="noopener noreferrer"&gt;https://github.com/kevinpatildxd/devguard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@kevinpatil/devguard" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@kevinpatil/devguard&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>react</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
