Skip to Content
React in a Week
Day 1 · JS → first component

Modules - import and export

Split code across files with export and import, and learn the difference between named and default exports.

A real React app has dozens or hundreds of files: one for each component, plus files for data and helpers. Each file needs a way to share some of its code with other files and to use code from them. JavaScript modules are that way.

You have already seen import { books } from './books.js' in the last lesson. Now you will learn what it means.

Named exports

In JavaScript, every file is its own module. Anything you create inside it is private to that file unless you export it. Put the word export in front of a const or function to share it.

Live code· Named exports

These are called named exports, because each one is exported under its own name. To import them, you list the names inside curly braces: import { books, countDone } from './books.js'. The names must match exactly.

The text after from is the path to the file. ./ means "in the same folder as this file". Paths to your own files always start with ./ or ../ (one folder up).

Default exports

A file can also have one default export. It is the file's main thing. You write export default in front of it.

Live code· Default exports

There are two differences when importing a default export:

  1. There are no curly braces: import formatBook from './formatBook.js'.
  2. You choose the name. The importing file can call it anything. import fmt from './formatBook.js' would also work.

Look at the last part of App.js: export default function App(). Every sandbox in this course works because the hidden entry file does import App from './App'. The App component is the default export of App.js.

Mixing both, and importing packages

A file can have one default export and any number of named exports. You import them in one line, default first:

import App, { books, countDone } from './App.js';

Packages you installed with npm are imported by their package name, without ./. This is how every React file gets React's tools:

import { useState } from 'react';
import { createRoot } from 'react-dom/client';

useState and createRoot are named exports of the react and react-dom/client packages. You saw createRoot in your Vite project's main.jsx, and you will meet useState on Day 3.

Deep diveWhich should I use, named or default?

Both are fine, and React projects use both. A common convention, and the one react.dev and Vite's starter use, is: one component per file, exported as the default, with the file named after the component (BookCard.jsx exports BookCard). Named exports are handy for files that share several things, like a data.js with several constants. Some teams prefer named exports everywhere so that names always match. Pick one style per project and stay consistent.

Try it

Split it into modules

All the code below is in App.js. Move shelf into shelf.js as a named export, and describe into describe.js as a default export. Then import both into App.js. The page should look the same when you are done.

Live code· Challenge: split into modules
Show solution
shelf.js
export const shelf = ['Dune', 'Emma', 'Beloved'];
describe.js
export default function describe(list) {
  return `${list.length} books: ${list.join(', ')}`;
}
App.js
import { shelf } from './shelf.js';
import describe from './describe.js';

console.log(describe(shelf));

export default function App() {
  return <p>{describe(shelf)}</p>;
}

shelf is a named export, so it is imported with braces. describe is a default export, so it is imported without them.

Quick check

utils.js contains export function slugify() and export default function format(). Which import is correct?

Quick check

Why does import { useState } from 'react' have no ./ in the path?

Day 1 progress

0/8
Next: What is React?

On this page