JavaScript Filename Naming Convention: Hyphens vs CamelCase – Which Should You Use?

In the world of JavaScript development, even the smallest decisions can impact code readability, maintainability, and collaboration. One such decision is how to name your files. While it may seem trivial, inconsistent or poorly chosen filenames can confuse teammates, slow down onboarding, and even break tooling (e.g., bundlers, linters, or import systems).

Two of the most common filename conventions in JavaScript are hyphens (kebab-case) and CamelCase (including camelCase and PascalCase). Each has its own strengths, weaknesses, and ideal use cases. In this blog, we’ll dive deep into both conventions, compare their pros and cons, and help you decide which to use for your project.

Table of Contents#

  1. What Are Filename Naming Conventions?
  2. Hyphens (kebab-case): The "Spaced" Approach
  3. CamelCase: The "Concatenated" Approach
  4. Use Cases: When to Choose Hyphens vs. CamelCase
  5. Industry Practices: What Do Popular Projects Use?
  6. Comparison Table: Hyphens vs. CamelCase
  7. Conclusion: The Golden Rule
  8. References

What Are Filename Naming Conventions?#

Filename naming conventions are rules that define how to structure and format file names (e.g., user-profile.js vs. userProfile.js). They exist to:

  • Improve readability (e.g., quickly understanding a file’s purpose).
  • Ensure consistency across a codebase (critical for large teams).
  • Avoid conflicts with tooling (e.g., bundlers like Webpack, linters like ESLint).
  • Comply with cross-platform compatibility (e.g., case sensitivity in operating systems).

In JavaScript, two conventions dominate: hyphens (kebab-case) and CamelCase (camelCase/PascalCase). Let’s break them down.

Hyphens (kebab-case): The "Spaced" Approach#

Definition & Examples#

kebab-case (also called "spinal-case" or "dash-case") uses lowercase letters with words separated by hyphens (-). It mimics natural language spacing but with hyphens instead of spaces.

Examples of kebab-case filenames:

  • user-profile.js
  • api-client.js
  • error-handler.middleware.js
  • utils/date-formatter.js

Pros of Hyphens#

  1. High Readability: Hyphens clearly separate words, making filenames easy to parse at a glance (e.g., user-profile is instantly readable vs. userprofile).
  2. Avoids Reserved Words: Hyphenated names are less likely to clash with JavaScript reserved words (e.g., class.js is risky, but class-validator.js is safe).
  3. Cross-Platform Friendliness: Hyphens work seamlessly across operating systems (Windows, macOS, Linux) and are never misinterpreted (unlike spaces or special characters).
  4. Mixed Tech Stack Compatibility: Ideal for projects with HTML/CSS/JS, as kebab-case aligns with HTML attributes (<div class="user-profile">) and CSS classes (.error-handler), reducing cognitive load.

Cons of Hyphens#

  1. Incompatible with JavaScript Identifiers: Hyphens are invalid in JavaScript variable/function names (they’re interpreted as subtraction operators). For example, you can’t do:
    import user-profile from './user-profile.js'; // SyntaxError!  
    Instead, you must alias the import:
    import userProfile from './user-profile.js'; // Valid (aliased)  
  2. Less Common in Modern JS Ecosystems: Many modern JavaScript tools (e.g., React, TypeScript) prefer CamelCase for files that export a single component/module.

CamelCase: The "Concatenated" Approach#

CamelCase concatenates words without spaces, using uppercase letters to separate word boundaries. It has two variants:

camelCase vs. PascalCase#

  • camelCase: The first word is lowercase, and subsequent words start with uppercase (e.g., userProfile.js).
  • PascalCase (or "UpperCamelCase"): Every word starts with uppercase, including the first (e.g., UserProfile.js).

Examples#

  • camelCase: userProfile.js, apiClient.js, dateFormatter.js
  • PascalCase: UserProfile.js, ApiClient.js, DateFormatter.js

Pros of CamelCase#

  1. JS Identifier Compatibility: CamelCase filenames align with JavaScript variable/function naming conventions. This avoids aliasing when importing:
    // PascalCase example (React component)  
    import UserProfile from './UserProfile.js'; // No alias needed!  
  2. Widely Adopted in Component-Based Libraries: Tools like React, Vue, and Angular strongly prefer PascalCase for component files (e.g., Button.js, Modal.js), as it matches the component’s class/function name.
  3. ES Module Alignment: For ES6 modules that export a single default value (e.g., export default class UserProfile), a PascalCase filename (UserProfile.js) creates a clear 1:1 mapping between the file and its export.

Cons of CamelCase#

  1. Reduced Readability for Long Names: Long filenames can become hard to parse (e.g., userAuthenticationSessionManager.js vs. user-authentication-session-manager.js).
  2. Case Sensitivity Risks: While modern OSes (macOS, Windows) are case-insensitive (they treat UserProfile.js and userprofile.js as the same), Linux is case-sensitive. This can cause conflicts if filenames differ only by case (e.g., userProfile.js and UserProfile.js).
  3. Mismatch with Non-JS Files: If your project includes HTML/CSS, CamelCase filenames will clash with kebab-case HTML/CSS conventions (e.g., userProfile.css vs. .user-profile in CSS).

Use Cases: When to Choose Hyphens vs. CamelCase#

The "right" convention depends on your project’s context. Here are guidelines:

Choose Hyphens (kebab-case) When:#

  • Your project uses mixed tech (HTML/CSS/JS). Aligning JS filenames with HTML/CSS (e.g., header-nav.js with header-nav.css) reduces mental overhead.
  • You’re building Node.js utilities or APIs. Many Node.js ecosystems (e.g., Express middleware) use kebab-case for modules (e.g., morgan uses morgan.js, but community middleware often uses cors.js or helmet.js—though kebab-case is common here).
  • Readability for long filenames is critical. Hyphens prevent "word soup" in files like error-handler-middleware.js.

Choose CamelCase When:#

  • You’re working with component-based libraries (React, Vue, Svelte). Use PascalCase for components (e.g., UserProfile.js) to match the component’s class/function name (e.g., class UserProfile extends React.Component).
  • Your project uses ES6 modules with single exports. If a file exports one default value (e.g., export default function formatDate()), use camelCase (e.g., formatDate.js) for consistency.
  • Tooling enforces it. Frameworks like Next.js or Gatsby (React-based) auto-import components, and PascalCase filenames ensure smooth integration.

To ground our discussion, let’s look at how top JavaScript projects name their files:

ProjectConvention UsedExamples
ReactPascalCase for components, camelCase for utilitiesButton.js, useState.js
VuePascalCase for SFCs (Single-File Components)HelloWorld.vue, UserProfile.vue
Node.js CorecamelCase (rarely kebab-case)path.js, fs.js
ExpresscamelCase/kebab-case (mixed)router.js, query-parser.js
Airbnb Style GuidecamelCase for files (matches variable names)userProfile.js, dateFormatter.js
MDN Web Docskebab-case (for code examples)fetch-api-example.js, promise-chaining.js

Key takeaway: component-focused projects (React, Vue) prefer PascalCase, while utility/API projects (Node.js, Express) use a mix of camelCase and kebab-case.

Comparison Table: Hyphens vs. CamelCase#

FactorHyphens (kebab-case)CamelCase (camelCase/PascalCase)
ReadabilityHigh (hyphens separate words clearly)Moderate (depends on length; long names suffer)
JS Identifier CompatibilityIncompatible (requires aliasing)Compatible (no aliasing needed)
Tooling SupportGood (works with all tools)Excellent (React, Vue, TypeScript prefer it)
Cross-PlatformSafe (no case sensitivity issues)Risky (Linux is case-sensitive)
Common Use CasesMixed tech stacks, Node.js utilities, long filenamesReact/Vue components, ES6 single-export modules

Conclusion: The Golden Rule#

There’s no universal "best" convention, but consistency is critical. A codebase with both user-profile.js and userProfile.js is far worse than one that sticks to a "suboptimal" convention uniformly.

Recommendations:

  • For React/Vue/Svelte components: Use PascalCase (e.g., UserProfile.js).
  • For utilities/helpers with single exports: Use camelCase (e.g., formatDate.js).
  • For mixed tech stacks (HTML/CSS/JS): Use kebab-case (e.g., header-nav.js).
  • Always document your choice in a CONTRIBUTING.md or style guide (e.g., "We use PascalCase for React components and kebab-case for everything else").

References#

By following these guidelines, you’ll create a codebase that’s readable, consistent, and easy to maintain—no matter which convention you choose! 🚀