AuthonAuthon Blog
debugging6 min read

Your npm Package Is Leaking Source Code (And You Probably Don't Know It)

Source maps in npm packages can expose your entire original source code. Learn how to detect, prevent, and fix source map leaks in your packages.

AW
Alan West
Authon Team
Your npm Package Is Leaking Source Code (And You Probably Don't Know It)

So here's a fun scenario: you spend weeks building a polished CLI tool, carefully minify and bundle your TypeScript into a neat little package, publish it to npm... and then someone casually reconstructs your entire original source code in about thirty seconds.

This isn't hypothetical. It happened publicly in early 2025 when a well-known AI company shipped their CLI tool to npm with source map files included. The community had the full original TypeScript source, system prompts, and internal logic extracted before anyone on the team noticed.

Let's talk about why this happens and how to make sure it never happens to you.

What Are Source Maps and Why Are They Dangerous?

Source maps are JSON files (usually .js.map) that map your minified or bundled output back to the original source code. They exist so you can debug production builds in browser DevTools or Node.js without staring at a wall of mangled variable names.

Here's the thing most people miss: source maps don't just contain mappings. They contain your actual source code. The sourcesContent field is literally an array of your original files, verbatim.

json
{
  "version": 3,
  "sources": ["src/auth/middleware.ts", "src/config/secrets.ts"],
  "sourcesContent": [
    "// Your entire original file contents are right here\nimport { SECRET_KEY } from './env'...\n",
    "// And here too. Every. Single. Line.\nexport const API_ENDPOINT = ..."
  ],
  "mappings": "AAAA,SAAS..."
}

Anyone who downloads your npm package can just open these .map files and read your source. No reverse engineering needed. No decompilation. Just... JSON.parse() and done.

How This Happens

The typical build pipeline looks something like this:

  • You write TypeScript (or use a bundler like esbuild, webpack, rollup)
  • Your tsconfig.json has "sourceMap": true for local development
  • Your build step generates both .js and .js.map files in dist/
  • You run npm publish
  • npm grabs everything in dist/ and ships it
  • Step 4 is where the damage happens. By default, npm publishes almost everything that isn't in .gitignore. And since .map files are usually in your dist/ folder (which should be published), they ride along silently.

    The sneaky part? Your .gitignore probably excludes dist/ entirely, which means you've never even seen these files in your repo. They only exist after a build, and they go straight to npm.

    The Fix: A Layered Approach

    Don't rely on a single safeguard. Use all of these.

    1. Use the files Field in package.json (Allowlist > Blocklist)

    This is the single most effective thing you can do. Instead of trying to exclude bad files, explicitly include only what you want:

    json
    {
      "name": "your-package",
      "files": [
        "dist/**/*.js",
        "dist/**/*.d.ts",
        "README.md",
        "LICENSE"
      ]
    }

    Notice what's not in that list? *.map files. This is an allowlist approach, and it's fundamentally safer than blocklisting because you can't accidentally forget to exclude something new.

    2. Add .npmignore as a Safety Net

    Belt and suspenders. Even with the files field, add an .npmignore:

    bash
    # .npmignore
    *.map
    src/
    tsconfig.json
    .env
    *.test.js
    *.spec.js
    __tests__/
    coverage/

    One gotcha: if .npmignore exists, npm ignores your .gitignore for publishing purposes. So make sure your .npmignore is comprehensive.

    3. Disable Source Maps in Production Builds

    If you don't need source maps in your published package (you almost certainly don't), just don't generate them:

    json
    // tsconfig.build.json — separate config for production builds
    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "sourceMap": false,
        "declarationMap": false
      }
    }

    Then in your package.json:

    json
    {
      "scripts": {
        "build": "tsc -p tsconfig.build.json",
        "dev": "tsc --watch"
      }
    }

    Keep source maps for development, strip them for production. Simple.

    4. Add a Pre-Publish Check

    This is the one that would have caught the leak before it went live. Add a prepublishOnly script that verifies no .map files are in the package:

    json
    {
      "scripts": {
        "prepublishOnly": "npm pack --dry-run 2>&1 | grep -E '\\.map
    

    Or if you want something more robust, write a quick script:

    bash
    #!/bin/bash
    # scripts/check-publish.sh
    MAP_FILES=$(npm pack --dry-run 2>&1 | grep -cE '\.map
    

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    bash
    npm pack --dry-run

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    • Immediately publish a new version without the source maps
    • Rotate any secrets that were in your source (API keys, internal endpoints, etc.)
    • Audit what was exposed — was it just code structure, or were there hardcoded credentials?
    • Accept it — the code itself isn't usually the crown jewel. Your competitive advantage is in execution, not in hiding if statements

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    • .env files (yes, people have published these)
    • .git/ directories
    • node_modules/ (it happens more than you'd think)
    • Internal documentation, design docs, or TODO files with sensitive context
    • Test fixtures with real data
    • CI/CD configs that reveal infrastructure details

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    && echo 'ERROR: Source maps detected in package!' && exit 1 || true"
    } }

    Or if you want something more robust, write a quick script:

    __CODE_BLOCK_6__

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    __CODE_BLOCK_7__

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    • Immediately publish a new version without the source maps
    • Rotate any secrets that were in your source (API keys, internal endpoints, etc.)
    • Audit what was exposed — was it just code structure, or were there hardcoded credentials?
    • Accept it — the code itself isn't usually the crown jewel. Your competitive advantage is in execution, not in hiding if statements

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    • .env files (yes, people have published these)
    • .git/ directories
    • node_modules/ (it happens more than you'd think)
    • Internal documentation, design docs, or TODO files with sensitive context
    • Test fixtures with real data
    • CI/CD configs that reveal infrastructure details

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    )
    if [ "$MAP_FILES" -gt 0 ]; then echo "Found $MAP_FILES source map file(s) in package. Aborting publish." npm pack --dry-run 2>&1 | grep -E '\.map

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    __CODE_BLOCK_7__

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    • Immediately publish a new version without the source maps
    • Rotate any secrets that were in your source (API keys, internal endpoints, etc.)
    • Audit what was exposed — was it just code structure, or were there hardcoded credentials?
    • Accept it — the code itself isn't usually the crown jewel. Your competitive advantage is in execution, not in hiding if statements

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    • .env files (yes, people have published these)
    • .git/ directories
    • node_modules/ (it happens more than you'd think)
    • Internal documentation, design docs, or TODO files with sensitive context
    • Test fixtures with real data
    • CI/CD configs that reveal infrastructure details

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    && echo 'ERROR: Source maps detected in package!' && exit 1 || true"
    } }

    Or if you want something more robust, write a quick script:

    __CODE_BLOCK_6__

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    __CODE_BLOCK_7__

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    • Immediately publish a new version without the source maps
    • Rotate any secrets that were in your source (API keys, internal endpoints, etc.)
    • Audit what was exposed — was it just code structure, or were there hardcoded credentials?
    • Accept it — the code itself isn't usually the crown jewel. Your competitive advantage is in execution, not in hiding if statements

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    • .env files (yes, people have published these)
    • .git/ directories
    • node_modules/ (it happens more than you'd think)
    • Internal documentation, design docs, or TODO files with sensitive context
    • Test fixtures with real data
    • CI/CD configs that reveal infrastructure details

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    exit 1 fi echo "No source maps found. Safe to publish."

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    __CODE_BLOCK_7__

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    && echo 'ERROR: Source maps detected in package!' && exit 1 || true" } }

    Or if you want something more robust, write a quick script:

    __CODE_BLOCK_6__

    5. Audit Before Every Publish

    Get in the habit of running this before every npm publish:

    __CODE_BLOCK_7__

    This lists every file that will be included in the package. Actually read the output. It takes ten seconds and it could save you from a very public embarrassment.

    What If You Already Published Source Maps?

    Bad news: you can't delete a specific version from npm after 72 hours (and even within that window, it's complicated if anyone has installed it). The source is out there.

    Here's what you should do:

    Beyond Source Maps: Other Files That Leak

    While you're at it, check for these common stowaways in npm packages:

    The Takeaway

    Source map leaks are entirely preventable with about five minutes of configuration. The core principle is simple: treat npm publish like a deployment, not a file copy.

    Use an allowlist (files in package.json), disable source maps in production builds, and always run npm pack --dry-run before publishing. If you set up that prepublishOnly check, you can forget about this problem entirely.

    The developers who got burned by this weren't careless — they just had a build pipeline that generated source maps by default and a publish step that didn't filter them out. It's an easy mistake to make exactly once. Make sure you're not the one making it.

    Your npm Package Is Leaking Source Code (And You Probably Don't Know It) | Authon Blog