React File Naming Conventions: The Only Rule That Actually Matters
React has no official naming convention. PascalCase, camelCase, and kebab-case are all used in production codebases. Here's what I've seen work and why consistency beats everything else.
Here is the thing React will never tell you: it has no opinion on how you name your files.
The official documentation does not define a convention. There is no react/naming rule in the ESLint plugin. Teams working on large React codebases at companies you have heard of use completely different systems and all of them work.
The only rule that matters is consistency. Pick one system, stick to it across every file in the project, and your codebase will be fine.
The Three Conventions You Will See
PascalCase for files: UserProfile.tsx, AuthButton.tsx. This mirrors the component name directly. When you see the file, you know the component name. Many teams that came from older React patterns (class components) still use this.
camelCase for files: userProfile.tsx, authButton.tsx. The import matches the variable name you will use inside the file. Some developers find this more natural coming from general JavaScript conventions.
kebab-case for files: user-profile.tsx, auth-button.tsx. This is what npm packages use. It avoids case sensitivity issues on case-insensitive file systems (Windows, some macOS setups). GitHub and most Linux servers are case-sensitive, so a casing mismatch that works locally can break in CI.
What Large Codebases Actually Use
Looking at popular open-source React projects and style guides:
The Airbnb React Style Guide uses PascalCase for component files. Many enterprise teams follow this.
npm packages almost universally use kebab-case. This is why libraries like react-router, react-query, and styled-components are all lowercase-hyphenated.
Next.js uses kebab-case for pages and app directory routes (because the filename becomes the URL slug), but PascalCase for components. That split convention is common in Next.js projects.
This codebase uses kebab-case for files and PascalCase for component names inside those files. That is the convention I have standardized on here and the one you will see throughout this series, starting with layout components.
Components Versus Files
There is an important distinction between the file name and the component name inside it.
The file name is a filesystem concern. The component name is a JavaScript and JSX concern.
// file: user-profile.tsx
export function UserProfile({ user }) {
return <div>{user.name}</div>;
}File: kebab-case. Component: PascalCase. They do not have to match exactly as long as your team agrees on both conventions independently.
JSX requires PascalCase for custom components. This is not a style preference. It is how JSX distinguishes a custom component from a built-in HTML element. <userProfile /> is treated as an unknown HTML tag. <UserProfile /> is a React component.
The Decision That Actually Matters
The bigger question is not camelCase vs kebab-case. It is whether your team makes the decision deliberately at the start and enforces it in code review.
A codebase with three different naming conventions is significantly harder to navigate than one with any single consistent convention, regardless of which one.
Pick one. Document it. Lint it if you can. Move on to the actual problems.
The Essentials
- React has no official file naming convention. All three conventions (PascalCase, camelCase, kebab-case) are used in large production codebases.
- Consistency matters more than which convention you choose.
- kebab-case avoids cross-platform case sensitivity bugs on Windows and some macOS setups.
- JSX requires PascalCase for component names regardless of what you name the file.
- The file name and the component name inside it can follow different conventions.
Further Reading and Watching
- Master React Design Patterns by CoderOne. While the focus is patterns, the code organization shown is a useful real-world reference.
- React docs: Writing Markup with JSX explains why JSX requires PascalCase for components, which is the one naming rule that is not optional.
Keep reading