Chrome Web Store Review Approval Guide: Dead Code Cleanup and Packaging Best Practices

Improve Chrome extension review approval by cleaning dead code, trimming packages, and ensuring policy compliance.
This guide covers three critical areas to help Chrome extension developers pass Web Store review on the first try: removing dead code (especially prohibited calls like eval that trigger static analysis flags), excluding node_modules and unnecessary files from submission packages, and self-auditing against Chrome Web Store policies including Manifest V3 requirements.
Developing a Chrome browser extension isn't hard — getting it through Chrome Web Store review is. Many developers face rejection after submission, often not because of functionality issues, but because they overlook easily missed code standards and packaging details. Based on real submission experience, this article outlines key strategies to improve your Chrome extension's review approval rate.
Cleaning Up Dead Code: The Hidden Minefield of Chrome Extension Reviews
Many developers assume that as long as their extension works correctly, it will pass review. That's not the case. Chrome Web Store review doesn't just focus on runtime behavior — it also performs static scanning of your code.
A classic example is dead code. Suppose your codebase contains a block of logic that will never execute, but it calls eval — a function explicitly prohibited by Chrome Web Store policy. Even though this code would never actually run, it can still cause your submission to be rejected.
Dead code is a common phenomenon in software engineering, typically originating from deprecated features during iterative development, changes in conditional branching logic, or redundant snippets introduced through copy-pasting from platforms like Stack Overflow. Many developers habitually comment out deprecated code or wrap it in conditional statements "just in case," forgetting to clean it up before release.

The review system won't give your code a pass just because it "won't execute." Chrome Web Store employs Static Analysis technology — a method that detects potential issues by parsing source code structure without actually running the program. Unlike dynamic analysis (which requires running the program and monitoring its behavior), static analysis traverses the code's Abstract Syntax Tree (AST), identifying all possible function calls and API usage regardless of whether those calls would be triggered at runtime. This means it scans the entire codebase for sensitive calls — eval, new Function(), and other dynamic code execution mechanisms are all high-priority targets.
To understand why eval() is strictly prohibited, consider the security risks: eval() can execute strings as JavaScript code, and new Function() allows dynamic construction of function bodies at runtime. In the context of browser extensions, this risk is dramatically amplified — extensions typically have higher privileges than regular web pages (such as accessing browsing history, reading content from any page, managing cookies, etc.). If an attacker could inject malicious code through dynamic code execution mechanisms, they could perform arbitrary operations at the extension's privilege level, compromising user data security. Chrome's Manifest V3 specification has already prohibited such dynamic code execution at the Content Security Policy level by default — this is a core defense line of Chrome's platform security model.

This reminds us: thoroughly clean up unused code before submission, especially logic left over from earlier versions, third-party snippets, or debugging phases. Even if they "seem harmless," they can become stumbling blocks on the road to approval.
Slim Down Your Submission Package: Don't Stuff the Entire node_modules In
The second common Chrome extension review issue occurs during packaging. It's common to see submissions that include the entire node_modules folder — even when developers have already used a bundler to generate the files that actually need to run.
For readers unfamiliar with frontend engineering, here's an explanation: node_modules is the directory created when Node.js package managers (npm/yarn/pnpm) install dependencies. It uses nested or flat structures to store all third-party libraries and their transitive dependencies required by the project. A medium-sized frontend project might have hundreds or even thousands of packages in its node_modules, easily reaching hundreds of MB in total size. One of the core jobs of modern bundlers is to precisely extract the code actually needed at runtime from these dependencies through techniques like Tree Shaking, generating minimally-sized output files. After bundling, useful code from node_modules has been inlined into the output bundle, making the original directory meaningless for execution.

This practice creates two direct problems:
Package Size Bloat
node_modules is typically massive, containing hundreds or thousands of dependency packages. Bundling them all into your submission multiplies the extension's size, wastes user download bandwidth, and slows down the installation experience. An extension that should only be a few hundred KB might balloon to tens of MB or more with node_modules included — completely unacceptable for a browser extension.

Increased Probability of Deep Review
More critically, redundant files significantly increase the probability of your submission entering further manual review. Chrome Web Store's review process combines automated scanning and manual review stages. The automated stage checks whether manifest.json permission declarations are reasonable, whether known violation patterns exist in the code, whether the extension package structure meets specifications, and more. If the automated stage detects suspicious content (such as abnormally large package sizes, numerous unused files, sensitive API calls, etc.), the submission gets escalated to the manual review queue for more detailed inspection. This not only extends the review cycle (from days to weeks) but also increases the risk of rejection.
The correct approach is: only submit the files ultimately generated by your bundler — the ones that will actually execute. When using modern bundlers like Webpack, Vite, or Rollup, ensure the output directory is clean, stripped of source maps (situationally), development dependencies, and anything beyond the build artifacts.
Specifically, Tree Shaking leverages the static structure of ES Modules (import/export declarations allow dependency relationships to be determined at compile time), analyzing which exported module members are actually referenced by other modules. Unreferenced code is eliminated from the final output. Combined with code minification (Terser/UglifyJS) and Scope Hoisting, bundlers can compress dozens of source files and dependencies into one or a few highly optimized bundle files. When building Chrome extensions, developers should ensure their build configuration is in production mode to fully enable these optimization capabilities.
How to Maximize Your Chrome Extension's First-Submission Approval Rate
Overall, the core philosophy for improving Chrome Web Store review approval rates can be summarized in three words: "clean, lean, compliant."
- Clean: Remove all dead code, especially fragments containing prohibited functions like
eval, even if they won't execute. - Lean: Only submit files needed for runtime — never package
node_modulesor other development assets. - Compliant: Self-audit against Chrome Web Store policy terms in advance, avoiding APIs or permissions that violate specifications.
Regarding compliance, it's worth noting that the Manifest V3 migration pushed by Google since 2020 has further tightened security requirements for extensions. Major changes include: prohibiting remotely hosted code (all logic must be contained within the extension package), restricting background scripts to the Service Worker model (persistent background pages are no longer supported), enforcing stricter Content Security Policy strategies, and replacing the more powerful but riskier webRequest blocking mode with the declarativeNetRequest API. These changes have raised the compliance bar, and developers need to ensure their extension architecture aligns with the latest specifications.
Before formally submitting, developers should manually extract their packaged artifact once, inspect each file within it, and confirm there's no extraneous content. While simple, this step can help you avoid the vast majority of rejections caused by "improper packaging." Additionally, consider adding automated check scripts to your CI/CD pipeline that scan the output directory for node_modules, .env files, source maps, or other content that shouldn't be present.
Summary
Chrome extension review mechanisms aren't mysterious, but they have clear requirements for code quality and packaging standards. Developers often fail on the details — a piece of non-executing violating code, an accidentally packaged dependency directory — either is enough to waste an entire submission.
Build the habit of pre-submission self-auditing, making "dead code cleanup" and "submission package streamlining" fixed steps in your release workflow. This will dramatically improve your first-submission approval rate and reduce the time cost of repeated modifications and review waiting. For developers who intend to maintain extensions long-term and continuously release updates, the value of these good habits only compounds over time.
Related articles

SKI: A Free Voice Coding Tool That Gives Claude Code a Voice
SKI is a free locally-run voice coding tool that adds bidirectional voice conversation to Claude Code and Codex. Supports Mac and Windows with hotkey activation for hands-free AI-driven programming.

AI Search Console: Track Your Brand's Visibility in ChatGPT/Claude/Gemini
AI Search Console is a GEO tool that tracks brand mentions, rankings, and citations across ChatGPT, Claude, Gemini, and Perplexity, turning AI visibility into quantifiable data.

Memmy Agent: Cross-Platform AI Memory Sharing Tool, A Local-First Personal Memory Hub
Memmy Agent is a local-first open-source AI memory hub enabling cross-platform memory sharing across Claude Code, Codex, and more. Free 2M tokens included.