What is the difference between with and without curly bracket notation in export/import statements?

ES6 offers many ways to manage modules through import/export. But there are basically two main strategies:

  1. Default export/import with export default and import module from './module'
  2. Multiple exports/imports with export and import {member} from './module' or import * as module from './module'

(Mixing both is possible but not recommended.)


Module to export/import

function foo() {
  console.log('Foo');
}

function bar() {
  console.log('Bar');
}

Strategy #1: Default export/import

Export (module.js)

function foo() {
  console.log('Foo');
}

function bar() {
  console.log('Bar');
}

export default {foo, bar};

/*
  {foo, bar} is just an ES6 object literal that could be written like so:

  export default {
    foo: foo,
    bar: bar
  };

  It is the legacy of the "Revealing Module pattern"...
*/

Import (main.js)

import module from './module';

module.foo(); // Foo
module.bar(); // Bar

Strategy #2: Multiple exports/imports

Export (module.js)

export function foo() {
  console.log('Foo');
}

export function bar() {
  console.log('Bar');
}

Import (main.js)

import {foo, bar} from './module';

foo(); // Foo
bar(); // Bar

/*
  This is valid too:

  import * as module from './module';

  module.foo(); // Foo
  module.bar(); // Bar
*/

As I said previously, ES6 modules are much more complex than that. For further information, I recommend you to read Exploring ES6 by Dr. Axel Rauschmayer, especially this chapter: http://exploringjs.com/es6/ch_modules.html.