108

I have referred all the questions in stackoverflow. But none of the suggested why and when to use default export.

I just saw that default can be metioned "When there is only one export in a file"

Any other reason for using default export in es6 modules?

bvakiti
  • 3,243
  • 4
  • 17
  • 26
  • Named exports are useful to export several values. During the import, it is mandatory to use the same name of the corresponding object. But a default export can be imported with any name for example: export default k = 12; // in file test.js import m from './test' // note that we got the freedom to use import m instead of import k, because k was default export console.log(m); // will log 12 https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export – Ferhat BAŞ Oct 24 '17 at 15:07
  • 3
    http://2ality.com/2014/09/es6-modules-final.html has a decent explanation imho. Use default when you want to import an entire module, you don't need to know the names of the methods of that module. Use the named exports to import specific things inside the module. – Shilly Oct 24 '17 at 15:10

8 Answers8

75

It's somewhat a matter of opinion, but there are some objective aspects to it:

  • You can have only one default export in a module, whereas you can have as many named exports as you like.

  • If you provide a default export, the programmer using it has to come up with a name for it. This can lead to inconsistency in a codebase, where Mary does

    import example from "./example";
    

    ...but Joe does

    import ex from "./example";
    

    In contrast, with a named export, the programmer doesn't have to think about what to call it unless there's a conflict with another identifier in their module.¹ It's just

    import { example } from "./example";
    
  • With a named export, the person importing it has to specify the name of what they're importing. They get a nice early error if they try to import something that doesn't exist.

  • If you consistently only use named exports, programmers importing from modules in the project don't have to think about whether what they want is the default or a named export.


¹ If there is a conflict (for instance, you want example from two different modules), you can use as to rename:

import { example as widgetExample } from "./widget/example";
import { example as gadgetExample } from "./gadget/example";
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
56

Some differences that might make you choose one over the other:

Named Exports

  • Can export multiple values
  • MUST use the exported name when importing

Default Exports

  • Export a single value
  • Can use any name when importing

This article does a nice job of explaining when it would be a good idea to use one over the other.

Ben
  • 5,079
  • 2
  • 20
  • 26
  • 25
    Named export doesn't have to use the same name: `import { OriginalName as CustomName } from './file'`. – Martin Nuc Jul 13 '19 at 07:18
  • 11
    You still must use the exported name when importing. But true, you can alias that exported name to something else of your choosing. – Ben Jul 15 '19 at 22:51
  • 1
    @Ben what? No, you don't need to use the exported name of the default export. It's completely transparent. – Robo Robok Jan 27 '20 at 04:32
  • 1
    I thought you talk about named default export for some reason. – Robo Robok Jan 27 '20 at 15:16
  • thanks for the link. So default export is only a useful transitional refactoring between CommonJS and ES Modules. But in practice it is considered an Anti-pattern – pref Jul 28 '22 at 15:15
  • One major drawback about working with default exports (having worked on large projects) is that complicate thing on a developer experience point of view, i.e while searching for dependencies of those exports. People might call whatever name and that makes it difficult to track. – Hernan Pintos Jan 05 '23 at 10:27
35

You should almost always favour named exports, default exports have many downsides

Problems with default exports:

  1. Difficult to refactor or ensure consistency since they can be named anything in the codebase other than what its actually called
  2. Difficult to analyze by automated tools or provide code intellisense and autocompletion
  3. They break tree shaking as instead of importing the single function you want to use you're forcing webpack to import the entire file with whatever other dead code it has leading to bigger bundle sizes
  4. You can't export more than a single export per file
  5. You lose faster/direct access to imports

checkout these articles for a more detailed explanation:

https://blog.neufund.org/why-we-have-banned-default-exports-and-you-should-do-the-same-d51fdc2cf2ad

https://humanwhocodes.com/blog/2019/01/stop-using-default-exports-javascript-module/

https://rajeshnaroth.medium.com/avoid-es6-default-exports-a24142978a7a

Khaled Osman
  • 1,251
  • 12
  • 17
  • 1
    Do you have any reference to prove that named export is faster than default export? Because that would be great. – jave.web Apr 07 '22 at 00:44
  • 1
    @jave.web its not necessarily that the export itself is faster, its that it allows bundlers like webpack to make use of a feature called tree-shaking see https://webpack.js.org/guides/tree-shaking/ which is a way to eliminate dead code from your project, so using named exports makes tools like webpack able to statically analyse your code and see what you're importing from that file.. named exports however forcefully import the entire file than part of it which breaks tree-shaking. so ofcourse smaller bundle means better rendering performance, less network delay and parsing times. – Khaled Osman Apr 07 '22 at 10:47
  • 1
    @jave.web this is also why alot of libraries recently publish new versions of their libraries with different import syntax to make it more tree-shakable and therefore reducing the bundle sizes allowing consumers to only import the functionalities that they need. for example imports like "material-ui/Button" which internally points to a "Button/index.js" file that only exports the Button component as opposed to a default "material-ui" import pointing to "src/index.js" which imports and exports all components in the library which would lead to a much bigger bundle size. – Khaled Osman Apr 07 '22 at 10:53
  • Oh, you mean it like that - great explanation, thank you :-) I like it for code maintainability anyways and this is just one more reason to teach others, thank you :-) – jave.web Apr 08 '22 at 14:15
18

With named exports, one can have multiple named exports per file. Then import the specific exports they want surrounded in braces. The name of imported module has to be the same as the name of the exported module.

// imports
// ex. importing a single named export
import { MyComponent } from "./MyComponent";

// ex. importing multiple named exports
import { MyComponent, MyComponent2 } from "./MyComponent";

// ex. giving a named import a different name by using "as":
import { MyComponent2 as MyNewComponent } from "./MyComponent";

// exports from ./MyComponent.js file
export const MyComponent = () => {}
export const MyComponent2 = () => {}

You can also alias named imports, assign a new name to a named export as you import it, allowing you to resolve naming collisions, or give the export a more informative name.

import MyComponent as MainComponent from "./MyComponent";

You can also Import all the named exports onto an object:

import * as MainComponents from "./MyComponent";
// use MainComponents.MyComponent and MainComponents.MyComponent2 here

One can have only one default export per file. When we import we have to specify a name and import like:

// import

import MyDefaultComponent from "./MyDefaultExport";

// export

const MyComponent = () => {}

export default MyComponent;

The naming of import is completely independent in default export and we can use any name we like.

From MDN: Named exports are useful to export several values. During the import, one will be able to use the same name to refer to the corresponding value. Concerning the default export, there is only a single default export per module. A default export can be a function, a class, an object or anything else. This value is to be considered as the “main” exported value since it will be the simplest to import.

Afaq Ahmed Khan
  • 2,164
  • 2
  • 29
  • 39
11

There aren't any definitive rules, but there are some conventions that people use to make it easier to structure or share code.

When there is only one export in the entire file, there is no reason to make it named. Also, when your module has one main purpose, it could make sense to make that your default export. In those cases you can extra named exports

In react for example, React is the default export, since that is often the only part that you need. You don't always Component, so that's a named export that you can import when needed.

import React, {Component} from 'react';

In the other cases where one module has multiple equal (or mostly equal) exports, it's better to use named exports

import { blue, red, green } from 'colors';
Vinno97
  • 516
  • 3
  • 11
8

1st Method:-

export foo; //so that this can be used in other file

import {foo} from 'abc'; //importing data/fun from module

2nd Method:-

export default foo;  //used in one file

import foo from 'blah'; //importing data/fun from module

3rd Method:-

export = foo;

import * as foo from 'blah';

The above methods roughly compile to the following syntax below:-

//all export methods

exports.foo = foo; //1st method
exports['default'] = foo; //2nd method
module.exports = foo; //3rd method

//all import methods

var foo = require('abc').foo; //1st method
var foo = require('abc')['default']; //2nd method
var foo = require('abc'); //3rd method

For more information, visit to Default keyword explaination

Note:- There can be only one export default in one file.

So whenever we are exporting only 1 function, then it's better to use default keyword while exporting

VIKAS KOHLI
  • 8,164
  • 4
  • 50
  • 61
0

EASIEST DEFINITION TO CLEAR CONFUSIONS

Let us understand the export methods, first, so that we can analyze ourselves when to use what, or why do we do what we do.

Named exports: One or more exports per module. When there are more than one exports in a module, each named export must be restructured while importing. Since there could be either export in the same module and the compiler will not know which one is required unless we mention it.

//Named export , exporting:

export const xyz = () =>{
}

// while importing this
import {xyx} from 'path'
or
const {xyz} = require(path)

The braces are just restructuring the export object.

On the other hand , default exports are only one export per module , so they are pretty plain.

//exporting default

const xyz =() >{
};

export default xyz

//Importing
import xyz from 'path'

or

const xyz = require(path)

I hope this was pretty simple to understand, and by now you can understand why you import React modules within braces...

-2

Named Export: (export)

With named exports, one can have multiple named exports per file. Then import the specific exports they want surrounded in braces. The name of imported module has to be the same as the name of the exported module.

// imports

// ex. importing a single named export

import { MyComponent } from "./MyComponent";

// ex. importing multiple named exports

import { MyComponent, MyComponent2 } from "./MyComponent";

// ex. giving a named import a different name by using "as":

import { MyComponent2 as MyNewComponent } from "./MyComponent";

// exports from ./MyComponent.js file

export const MyComponent = () => {} export const MyComponent2 = () => {}

Import all the named exports onto an object: // use MainComponents.MyComponent and MainComponents.MyComponent2 here

import * as MainComponents from "./MyComponent";

Default Export: (export default)

One can have only one default export per file. When we import we have to specify a name and import like:

// import

import MyDefaultComponent from "./MyDefaultExport";

// export

const MyComponent = () => {} export default MyComponent;

Note: The naming of import is completely independent in default export and we can use any name we like.

Here's a great answer that explains default and named imports in ES6

Rohit
  • 7
  • 2
  • This explains *what* a default export is, not *why* to use it and the use cases of it, as the OP asked – Teodoro Nov 05 '21 at 15:02