DEV Community

Cover image for Import and Export Statements in JavaScript and How to Use Them
Alex Devero
Alex Devero

Posted on • Originally published at blog.alexdevero.com

Import and Export Statements in JavaScript and How to Use Them

Import and export statements are two great features introduced ES6 (ES2015). These two statement allows you to export and import your code and use it whenever you need. This tutorial will show you what import and export statements are, how they work and how to use them.

A quick introduction

In the past, when JavaScript developers wanted to split their code into modules they had to use one of the three options. These options were AMD, CommonJS and UMD. There was built-in support for modules in JavaScript. Things changed when the ES2015 (ES6) specification was released.

One feature this specification brought to JavaScript was also a support for modules on a language-level. JavaScript developers were now able to work with native modules with the help of newly introduced import and export statements. Now, you as a JavaScript developer can split your code into multiple files.

Each of these files is a module. These modules can contain anything, from variables and functions to classes. In order to this code available to the outside you have to simply exporting it. When you want to use some of that exported code, you simply import it where you need. Now, let's take a look at both those new statements.

The export statement

When you want to export some variable, function or class you have to place the export keyword before it. This tells JavaScript two things. First, you want that "thing" to be available from the outside of the current file. Second, other parts of the program should be able to import that "thing" with the import statement.

When you export some code you can still change it and update it. However, you can that only at the place where you exported it. You can't do that when you import that exported code somewhere else. When you import some exported code you can only read it and use it, but not change it.

Two ways to export

When you want to export some code with export statement, there are two ways to do it. The first one is by exporting at the moment of declaration. In this case, you put the export statement on the same line right before the variable, function or class you are about to declare.

// Declare and export variables
export const MY_PASS = 'Some very important secret.'
export let name = 'Jack'
export var stack = 'JS'

// Declare and export functions
export function sayHi() {
  return 'Hi.'
}

export const sayBye = function() {
  return 'Bye.'
}

export const sayGoodBye = () => {
  return 'Good bye.'
}

// Declare and export class
export class Person {
  name = this.name
  age = this.age
  #my_secret = this.secret
}
Enter fullscreen mode Exit fullscreen mode

The second way to export code is by declaring it first and exporting it after that. In this case, you use the export statement followed by the "thing" you want to export.

// Declare variables
const MY_PASS = 'Some very important secret.'
let name = 'Jack'
var stack = 'JS'

// Export variables
export MY_PASS
export name
export stack

// Declare functions
function sayHi() {
  return 'Hi.'
}

const sayBye = function() {
  return 'Bye.'
}

const sayGoodBye = () => {
  return 'Good bye.'
}

// Declare and export functions
export sayHi
export sayBye
export sayGoodBye

// Declare class
class Person {
  name = this.name
  age = this.age
  #my_secret = this.secret
}

// Export class
export Person
Enter fullscreen mode Exit fullscreen mode

When you decide to use the second way there is another thing to do. Instead of export all those things individually, you can export them at once with a single export statement. For example, at the end of the file. To do this, you have to wrap everything you want to export with curly braces, separated by commas.

// Declare some stuff
const MY_PASS = 'Some very important secret.'

let name = 'Jack'

function sayHi() {
  return 'Hi.'
}

class Car {
  numOfWheels = this.numOfWheels
  typeOfFuel = this.typeOfFuel
}

// Export all the stuff at once
export { MY_PASS, sayHi, Car }
Enter fullscreen mode Exit fullscreen mode

Named and default export

There are also two types of exports you can use. One is called named export and the other default export. When it comes to named exports, you can create as many of them as you want. There is no limit. This doesn't apply to default exports. In JavaScript, you can have only one default export per module.

The first type, named export, is what you saw on the examples above. In these examples, you were using the export keyword along with the name of the thing you wanted to export. All these exports were named. When you want to export something as default you have to add default between the export statement and what you want to export.

// Named export
export const LANG = 'English'

// or
const favoriteFantasy = 'Discworld'
export favoriteFantasy


// Default export
export default const LANG = 'English'

// or
const favoriteFantasy = 'Discworld'
export default favoriteFantasy
Enter fullscreen mode Exit fullscreen mode

There is another way to export something as default. You can wrap the name of the thing you want to export with curly braces. Next, you add as keyword, followed by the default keyword. This will also export that thing as default.

// Another way to create default export
const FAVORITE_SEASON = 'Summer'

// Export FAVORITE_SEASON as default
export { FAVORITE_SEASON as default }
Enter fullscreen mode Exit fullscreen mode

Renaming exports

When you export something, and you don't want to use the variable, function or class name, you can rename it. To do that, you have to wrap the name with curly braces and add as keyword followed by new name, under which you want to export it. If you export multiple things, you can use this to rename all of them or just some.

// Declare a variable
let sillyJoke = 'Knock, knock.'

// Export the variable and rename it
export { sillyJoke as classicJoke }


// Declare multiple variables
const petOne = 'Dog'
const petTwo = 'Cat'
const petThree = 'Alligator'
const petFour = 'Dragon'

// Export all variables and rename some
// Note: line breaks are just for readability
export {
  petOne,
  petTwo as pet2, // rename export for petTwo
  petThree as pet3, // rename export for petThree
  petFour
}
Enter fullscreen mode Exit fullscreen mode

Re-exporting exports

The last thing you can do with export statement some import things and immediately export them again. During this process you can either keep their names or rename them. The syntax for re-exporting is similar to the syntax for importing. You will learn about that in a minute.

In case of re-exporting, you start with the export statement. What follows are curly braces with name of the module you want to export. This is followed by from keyword and name of the file from which that module is exported. If you want to rename the exported module add as keyword followed by new name after the module name, inside the curly braces.

// Re-export module
export { myExpModule } from './file.js'

// Re-export module and rename it
export { myExpModule as myRenamedExpModule } from './file.js'
Enter fullscreen mode Exit fullscreen mode

You use the same syntax also when you want to re-export default export. In that case, between the curly braces goes "default" instead of some module name. Otherwise, you can replace that with * and omit the curly braces.

// Re-export default module
export { default } from './file.js'

// Alternative
export * from './file.js'

// Re-export default module and rename it
export { default as defaultRenamed } from './file.js'
Enter fullscreen mode Exit fullscreen mode

The import statement

When you want to import some code you have to use the import statement. Remember that this will work only with code you exported with the export statement. You can't import something you didn't export. When you want to import something, there are two options from which you can choose. We will get to that in a minute.

In both cases, you have to start the line with the import keyword. Next, you specify the name of the exported module you want to import. This part of syntax will differ according to which of the two options you choose. After that follows from keyword, followed by the name of the file from which you want to import those modules.

// Example of import syntax
import { someModule } from 'file.js'
import someModule from 'file.js'
Enter fullscreen mode Exit fullscreen mode

Named imports

The first option is to import modules, those things you've exported, individually. If you choose this, you have to consider how you exported those modules. If you exported those modules with named exports you have to use exactly the names you used. If you used renaming, then, you have to use those new names.

When importing named exports, you have to wrap those names with curly braces. This is required when you import named exports. Similarly to exporting, you can also import all exports individually with multiple import statements. You can also import them all with single import statement. In that case, you have to separate those exported modules with commas.

// File 1: file-one.js
// Declare and export some stuff
// Use named export
export const age = 29

function sayHi() {
  return 'Hello'
}

// Use named export with renaming
export { sayHi as greeting }


// File 2: file-two.js
// Import only the "age" variable
import { age } from './file-one.js'

// Try to read imported "age" variable
console.log(age)
// Output:
// 29


// Import only the "greeting" function
// Note: you exported the sayHi as greeting
// so you have to import it as greeting, not as sayHi
import { age } from './file-one.js'

// Import both, "age" and "greeting"
import { age, greeting } from './file-one.js'

// Try to read imported "age" variable
console.log(age)
// Output:
// 29

// Try to call imported "greeting" function
console.log(greeting())
// Output:
// 'Hello'
Enter fullscreen mode Exit fullscreen mode

Default imports

If you exported some module as default, you can choose whatever name to import that module you want. And, don't wrap the module name with curly braces if you want to import default export. Otherwise, JavaScript will throw an error. One important thing. When you import something as default, you don't use the variable keyword.

// File 1: file-one.js
// Declare and export some stuff as default
// Note: omit the "const", "let" or "var" keywords
export default surname = 'Joe'


// File 2: file-two.js
// Import only default export "name"
// Note: no curly braces around the name
import surname from './file-one.js'

// Try to read imported "age" variable
console.log(surname)
// Output:
// 'Joe'
Enter fullscreen mode Exit fullscreen mode

When you export something as default, you don't have to use the same name to import it elsewhere. When you use default export JavaScript knows that that file contains only one export. So, it will figure out what you want to import even if you use different name to import that thing.

// File 1: file-one.js
// Declare and export some variable as default
export default secret = 'This is some very important secret.'


// File 2: file-two.js
// Import the default export using a different name
import password from './file-one.js'

// Try to read imported "age" variable
console.log(password)
// Output:
// This is some very important secret.
Enter fullscreen mode Exit fullscreen mode

Importing named modules at once

The second option is to import all the stuff at once. Remember that this will import everything you exported from the file you now want to import from. The syntax is similar to importing individual modules. The difference is two-fold. First, you replace the name of the module you want to import with * (asterisk).

Second, you have to add as keyword followed by the name through which you want to access those imported modules. This name can be anything you want.

// File 1: file-one.js
// Declare and export some stuff
export const pets = ['Dog', 'Shark', 'Tiger']
export const currentlyReading = 'Snow Crash'
export function add(a, b) {
  return a + b
}


// File 2: file-two.js
// Import everything exported from file-one.js
import * as myStuff from './file-one.js'

// Try to read the value of imported "pets" variable
console.log(myStuff.pets)
// Output:
// ["Dog", "Shark", "Tiger"]

// Try to read the value of imported "currentlyReading" variable
console.log(myStuff.currentlyReading)
// Output:
// "Snow Crash"

// Try to call the imported add() function
console.log(myStuff.add(89, 98))
// Output:
// 187
Enter fullscreen mode Exit fullscreen mode

Renaming imports

Similarly to the export statement, import statement also allows you to rename your imports. This can be handy when you want to import some module, but you want to use it through a different name. The syntax similar to the syntax for renaming exports. The only difference is that you will replace the export statement with import.

// File 1: file-one.js
// Declare and export some stuff
export const transpiler = 'Babel'
export const language = 'JavaScript'
export const syntax = 'jsx'
export const framework = 'React'


// File 2: file-two.js
// Import modules exported from file-one.js
// and rename some of those imports
// Note: line breaks are again just for readability
import {
  transpiler,
  language,
  syntax as fileExtension,  // rename export for syntax
  framework as library  // rename export for framework
} from './file-one.js'

// Try to read the value of imported "pets" variable
console.log(syntax)
// Output:
// "jsx"

// Try to read the value of imported "currentlyReading" variable
console.log(library  )
// Output:
// "React"
Enter fullscreen mode Exit fullscreen mode

Importing individual named exports and default export

One nice thing about import statement is that it can work with named and default exports at the same time. So, if you used both, named and default exports in the same file, you can still import those modules individually with a single import statement. To do this, there are two things you have to remember.

First, you have to import any default export without wrapping it with curly braces. Second, you have to wrap any remaining named exports with those curly braces. If you import two or more named exports, separate those exports with commas. Keep them all still inside that one pair of curly braces.

// File 1: file-one.js
// Declare and export some stuff
export default tvShow = 'Breaking Bad'
export const mainCharacter = 'Walter White'
export const subject = 'Chemistry'
export const rating = '9.5/10'


// File 2: file-two.js
// Import both named and default exports from file-one.js
// Note: the default export "tvShow" has to be first
// and outside of the curly braces
import tvShow, { mainCharacter, subject, rating } from './file-one.js'
Enter fullscreen mode Exit fullscreen mode

Dynamic imports

Now you know about import and export statements and how to use them. However, the import statement is not the only way to import modules. There is also an alternative called dynamic import. The main difference between the import statement and dynamic import is that the import statement is static.

This means that when you import something with import statement it will be imported at the moment you run your code. If you import some large module, or a lot of them, it can make your code slower. Dynamic import works differently. Dynamic imports are not loaded at the moment you run your code.

Well, they can, but only if you want that to happen. If not, you can delay their load. You can use dynamic imports also to load things only under certain condition. If this condition never happens that dynamic import will not be loaded. In that case, that additional module will logically have no effect on the performance of your code.

When you want to use dynamic import you use the import keyword. However, this time you call it as a function, and pass in path to the module as an argument. This function will return a promise. You can then consume that promise with the then handler. The loaded module is passed to then handler through parameter.

As an alternative to the then() handler, you can also use await keyword, and assign the module to a variable. Then, you can do whatever you want with that module.

// Example of dynamic import
import('./my-module.js')
  // Use then() handler to consume returned promise
  .then((module) => {
    // Do something with the module
    // returned by the promise
    // and passed through "module" parameter
  })

// Alternative with await
(async function() {
  // Assign the module to a variable
  const myModule = await import('./my-module.js')
  // Do something with that module
}())
Enter fullscreen mode Exit fullscreen mode

If you want to use await remember that you have to use async function. Well, unless you use top-level await which is another option. In that case, no need to use async function.

// Using top-level await
// Assign the module to a variable
const myModule = await import('./my-module.js')
// Do something with that module
Enter fullscreen mode Exit fullscreen mode

Conclusion: Import and export statements in JavaScript and how to use them

Import and export statements are two features that can be very handy. They can help you make your code clearer and easier to manage and maintain. What's more, they are both also very easy to learn and use. I hope that this tutorial helped you learn about what import and export statements are, how they work and how to use them.

Discussion (2)

Collapse
andrewbaisden profile image
Andrew Baisden

Well explained with many examples which makes it easy to learn.

Collapse
paras594 profile image
Paras 🧙‍♂️

Nice explanation with great examples !!