How to Import a CSS File in React: Step-by-Step Guide

Import a CSS file in React by using the ES module syntax import './styles.css' at the top of your component, which triggers the bundler to inject the styles as a side effect, then apply classes via the className attribute in JSX.

React does not include a built-in CSS-in-JS engine; instead, it delegates static asset handling to the underlying build toolchain. Whether you use Create React App, Vite, Next.js, or a custom Webpack configuration, the pattern for importing CSS remains consistent across the facebook/react repository and community best practices.

How Build Tools Handle CSS Imports in React

When you import a CSS file in React, the bundler (Webpack, Rollup, or Vite) processes the file through a CSS loader plugin. This loader extracts the styles and injects them into the DOM, either as a <style> tag during development or as an optimized external file in production builds. React itself never sees the CSS content; the import is purely a side-effect that signals the build system to include the asset.

Step-by-Step: Import CSS File in React

Follow these steps to import and apply CSS in your React components.

1. Create the Stylesheet

Place your CSS file in the same directory as the component or in a shared styles/ folder. Use standard CSS syntax:

/* src/components/Button.css */
.button-primary {
  background-color: #0069d9;
  color: white;
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

2. Import the CSS File

At the top of your component file, import the CSS using a relative path. This is a side-effect import—it does not export a value, but tells the bundler to process the file:

// src/components/Button.jsx
import './Button.css';

export default function Button({ children }) {
  return <button className="button-primary">{children}</button>;
}

3. Reference Classes with className

Always use the className attribute in JSX instead of HTML's class. React uses className to avoid conflicts with the JavaScript class keyword:

<div className="button-primary active">Click me</div>

4. Build and Run

When you start your development server (npm start or npm run dev), the bundler automatically processes the CSS import. In production builds, the CSS is typically extracted into a single optimized file or inlined for critical rendering.

Using CSS Modules for Scoped Styles

For component-scoped styles that avoid global namespace pollution, use CSS Modules. Rename your file with the .module.css extension and import it as an object:

// src/components/Card.jsx
import styles from './Card.module.css';

export default function Card({ title }) {
  return (
    <div className={styles.card}>
      <h2 className={styles.title}>{title}</h2>
    </div>
  );
}

The bundler automatically maps the CSS classes to unique identifiers (e.g., Card_card__3x7a2), preventing collisions between components.

Real-World Examples from the React Repository

The facebook/react repository demonstrates these patterns throughout its DevTools and internal packages.

In packages/react-devtools-shell/src/app/index.js, the shell application imports a global stylesheet at line 26:

import './styles.css';

This side-effect import ensures the DevTools shell receives its base styling before any components render.

Similarly, the Timeline component in packages/react-devtools-timeline/src/Timeline.js imports a scoped stylesheet at line 33:

import styles from './Timeline.css';

Note that while this uses the variable name styles, it imports a standard CSS file rather than a CSS Module, demonstrating that the naming convention is flexible based on your bundler configuration.

The DevTools view in packages/react-devtools-shared/src/devtools/views/DevTools.js (lines 49-51) imports multiple CSS files alongside third-party UI library styles:

import './DevTools.css';
import '@reach/menu-button/styles.css';

This pattern shows how to combine component-specific styles with external library CSS in a single React component file.

Summary

  • Import syntax: Use import './file.css' for global styles or import styles from './file.module.css' for scoped CSS Modules.
  • Side-effect imports: Standard CSS imports do not export values; they signal the bundler to inject styles.
  • className attribute: Always use className instead of class in JSX to apply CSS classes.
  • Build tool dependency: React delegates CSS handling to Webpack, Vite, or similar bundlers included in Create React App or Next.js.
  • Real-world validation: The facebook/react repository uses these exact patterns in packages/react-devtools-shell/src/app/index.js and packages/react-devtools-timeline/src/Timeline.js.

Frequently Asked Questions

Can I import a CSS file in React without a bundler?

No, React itself does not parse CSS files. You need a build tool like Webpack, Vite, Parcel, or the built-in systems in Create React App or Next.js to process the import statement and inject the styles into the DOM.

What is the difference between importing a regular CSS file and a CSS Module?

A regular CSS import (import './styles.css') applies styles globally to the entire application, which can lead to naming collisions. A CSS Module import (import styles from './styles.module.css') scopes the classes to the specific component, with the bundler automatically generating unique class names to prevent conflicts.

Why do I use className instead of class in React?

React uses className instead of the standard HTML class attribute because class is a reserved keyword in JavaScript. Using className avoids syntax errors and clearly distinguishes between CSS classes and JavaScript classes in your JSX code.

How does the React team handle CSS imports in the official repository?

The React team follows standard ES module import patterns in their DevTools packages. For example, they import global styles using import './styles.css' in packages/react-devtools-shell/src/app/index.js and component-specific styles using import styles from './Timeline.css' in packages/react-devtools-timeline/src/Timeline.js, demonstrating these patterns in production-grade code.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →