What Is .cjs
Content on WhatAnswers is provided "as is" for informational purposes. While we strive for accuracy, we make no guarantees. Content is AI-assisted and should not be used as professional advice.
Last updated: April 10, 2026
Key Facts
- Node.js added native ES module support in v8.5.0 (August 2017), making .cjs extension necessary for explicit CommonJS declarations
- Package authors use .cjs files to publish dual-format packages, with statistics showing over 95% of npm packages support CommonJS compatibility
- Major frameworks like Express.js, Webpack, and Babel generate .cjs distribution files alongside .mjs for universal compatibility
- .cjs files can be imported in ES modules using dynamic import() syntax or through conditional exports in package.json
- As of 2024, .cjs remains the dominant distribution format in npm, with migration to pure ESM expected to take years due to ecosystem size
Overview
.cjs stands for CommonJS and is a file extension that explicitly designates Node.js modules as CommonJS format, regardless of package.json configuration. While CommonJS has been the default module system since Node.js was created in 2009, the introduction of native ES module support created ambiguity about which module system a .js file should use. The .cjs extension emerged as the solution, providing explicit clarity and enabling coexistence of both systems.
As of 2024, the JavaScript ecosystem is transitioning from CommonJS to ES modules, but this transition is gradual because millions of existing packages rely on CommonJS. The .cjs extension is critical infrastructure for this transition period, allowing package maintainers to distribute dual-format libraries and enabling teams to gradually migrate mixed codebases. Understanding .cjs is essential for package authors, Node.js developers, and anyone working with modern JavaScript infrastructure.
How It Works
The .cjs extension operates through Node.js module resolution, which automatically treats files with this extension as CommonJS regardless of how package.json is configured:
- Explicit Module Type Declaration: A .cjs file is always parsed as CommonJS, using require() and module.exports, even when package.json contains "type": "module" which would normally enforce ES modules for .js files.
- Dual-Module Publishing: Package authors create both .cjs and .mjs versions of their code, with package.json "exports" field automatically routing CommonJS consumers to .cjs files and ES module consumers to .mjs files.
- ES Module Interoperability: ES module files can import .cjs modules using dynamic import() syntax (returns a module namespace object), while .cjs files cannot directly import .mjs files through require() without conditional exports or wrapper logic.
- Build Tool Automation: Modern build tools like Webpack, Esbuild, and Rollup recognize .cjs files and compile source code into .cjs distribution files automatically, making dual-module support a standard feature for library builds.
- Node.js Version Compatibility: All Node.js versions support .cjs files since it's simply a file extension convention, though ES module interoperability with .cjs requires Node.js 12.20.0 or later for full functionality.
Key Comparisons
| Aspect | .cjs (CommonJS) | .mjs (ES Module) | .js (Context-Dependent) |
|---|---|---|---|
| File Extension | .cjs | .mjs | .js |
| Module Syntax | require() and module.exports | import and export statements | Determined by "type" field in package.json |
| Node.js Support | All versions since v0.1.0 | v12.20.0+ with stable support | All versions (behavior depends on config) |
| Static Analysis | Limited, requires runtime analysis | Full static analysis possible | Depends on determined module system |
| Primary Use Case | Legacy code, server packages, backward compatibility | Modern projects, browser-friendly code | General purpose files (config determines meaning) |
| Distribution Strategy | Used with .mjs for dual-module packages | Used with .cjs for dual-module packages | Single format (requires clear configuration) |
Why It Matters
- Ecosystem Stability: The .cjs extension prevented fragmentation of the npm ecosystem during the transition to ES modules, allowing millions of CommonJS packages to coexist peacefully with new ES-module-only projects without forcing immediate migration.
- Library Dual-Publishing: Package authors can maintain single source code while distributing .cjs versions for traditional Node.js applications and .mjs versions for modern consumers, maximizing reach and compatibility across different project types.
- Gradual Migration Path: Development teams can incrementally migrate from CommonJS to ES modules by using both .cjs and .mjs files in the same project, refactoring files one at a time rather than requiring complete rewrites.
- Build Tool Standardization: The .cjs convention became the industry standard for build outputs, allowing developers to understand code intent immediately and enabling IDEs, linters, and bundlers to handle module resolution correctly without configuration guessing.
Today, .cjs represents a pragmatic bridge between Node.js's past and future. While ES modules are now the recommended standard for new projects, .cjs ensures that the massive existing codebase remains functional and maintainable. Mastering .cjs is essential for anyone publishing packages, working with modern Node.js applications, or building tools in the JavaScript ecosystem, as it remains the dominant module format across npm for the foreseeable future.
More What Is in Daily Life
Also in Daily Life
More "What Is" Questions
Trending on WhatAnswers
Browse by Topic
Browse by Question Type
Sources
- Node.js Official Documentation - PackagesCC-BY-4.0
- MDN Web Docs - JavaScript ModulesCC-BY-SA-2.5
- Node.js Official Guide - Building ApplicationsCC-BY-4.0
Missing an answer?
Suggest a question and we'll generate an answer for it.