diff --git a/package.json b/package.json
index 4d41d6b2bdf4d0c61a84eb10f9ab9155f969e963..d2578d9a303014bad999ad5285f89da66263b8b9 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
     "enzyme": "^2.8.2",
     "eslint": "^3.16.1",
     "eslint-config-scratch": "^3.0.0",
+    "eslint-plugin-import": "^2.7.0",
     "eslint-plugin-react": "^7.0.1",
     "gh-pages": "github:rschamp/gh-pages#publish-branch-to-subfolder",
     "html-webpack-plugin": "2.28.0",
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
index 0abd74d675fae217d8745dcba17a049e96cc5fa5..e558dde263eb1f6970b0abcbf62e9f28ab655580 100644
--- a/src/.eslintrc.js
+++ b/src/.eslintrc.js
@@ -1,10 +1,16 @@
 module.exports = {
     root: true,
-    extends: ['scratch', 'scratch/es6', 'scratch/react'],
+    extends: ['scratch', 'scratch/es6', 'scratch/react', 'import'],
     env: {
         browser: true
     },
     globals: {
         process: true
+    },
+    rules: {
+        'import/no-mutable-exports': 'error',
+        'import/no-commonjs': 'error',
+        'import/no-amd': 'error',
+        'import/no-nodejs-modules': 'error'
     }
 };
diff --git a/src/components/asset-panel/asset-panel.jsx b/src/components/asset-panel/asset-panel.jsx
index 7432562940dd2351b40d7a23cd9e842c0b067cc0..a33c8d209c4ca41d7fec6197d6adf2c1d4449725 100644
--- a/src/components/asset-panel/asset-panel.jsx
+++ b/src/components/asset-panel/asset-panel.jsx
@@ -20,4 +20,4 @@ AssetPanel.propTypes = {
     ...Selector.propTypes
 };
 
-module.exports = AssetPanel;
+export default AssetPanel;
diff --git a/src/components/asset-panel/selector.jsx b/src/components/asset-panel/selector.jsx
index d37cca7572b1c7468e89a2fc8052402d646e6d60..51b1b6a82be265b1d2b67426d467ec025c782101 100644
--- a/src/components/asset-panel/selector.jsx
+++ b/src/components/asset-panel/selector.jsx
@@ -68,4 +68,4 @@ Selector.propTypes = {
     selectedItemIndex: PropTypes.number.isRequired
 };
 
-module.exports = Selector;
+export default Selector;
diff --git a/src/components/audio-trimmer/audio-trimmer.jsx b/src/components/audio-trimmer/audio-trimmer.jsx
index 840b240f5b7f0c13b63c2e20539fd8d237827458..d414f3ae25d6350e86f4e5e230e1a76f5ccaa7e4 100644
--- a/src/components/audio-trimmer/audio-trimmer.jsx
+++ b/src/components/audio-trimmer/audio-trimmer.jsx
@@ -67,4 +67,4 @@ AudioTrimmer.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = AudioTrimmer;
+export default AudioTrimmer;
diff --git a/src/components/blocks/blocks.jsx b/src/components/blocks/blocks.jsx
index 8afcad5e914d2a1e0cfded1e26cbdad40985810d..683da23c1f048eb39d84146cd72959a0593bc8d7 100644
--- a/src/components/blocks/blocks.jsx
+++ b/src/components/blocks/blocks.jsx
@@ -19,4 +19,4 @@ const BlocksComponent = props => {
 BlocksComponent.propTypes = {
     componentRef: PropTypes.func
 };
-module.exports = BlocksComponent;
+export default BlocksComponent;
diff --git a/src/components/box/box.jsx b/src/components/box/box.jsx
index cd4a202b06f76d308dec85efbf100b9ab8cfd7b2..4e9c8cdb8e0da81e3845400b9a71645014f19d1d 100644
--- a/src/components/box/box.jsx
+++ b/src/components/box/box.jsx
@@ -136,4 +136,4 @@ Box.defaultProps = {
     element: 'div',
     style: {}
 };
-module.exports = Box;
+export default Box;
diff --git a/src/components/buffered-input/buffered-input.jsx b/src/components/buffered-input/buffered-input.jsx
index b66d80eb9696a6afeaa3be167f6326328d225bda..13645956ea5ad1db4fb5e7b10dba5baf1bcd7736 100644
--- a/src/components/buffered-input/buffered-input.jsx
+++ b/src/components/buffered-input/buffered-input.jsx
@@ -49,4 +49,4 @@ BufferedInput.propTypes = {
     onSubmit: PropTypes.func.isRequired,
     value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
 };
-module.exports = BufferedInput;
+export default BufferedInput;
diff --git a/src/components/button/button.jsx b/src/components/button/button.jsx
index 59609cf76b55d7f5c9a891a994cb2235ef44f09b..ae322d10fbfcdf655a641e7e61fd40bf750af330 100644
--- a/src/components/button/button.jsx
+++ b/src/components/button/button.jsx
@@ -28,4 +28,4 @@ ButtonComponent.propTypes = {
     className: PropTypes.string,
     onClick: PropTypes.func.isRequired
 };
-module.exports = ButtonComponent;
+export default ButtonComponent;
diff --git a/src/components/close-button/close-button.jsx b/src/components/close-button/close-button.jsx
index 688e991b6da8a1a9b34c2fb28bbccf1d726c26a1..416adec8e279b7c185468b376e10fb46bf729416 100644
--- a/src/components/close-button/close-button.jsx
+++ b/src/components/close-button/close-button.jsx
@@ -37,4 +37,4 @@ CloseButton.defaultProps = {
     size: CloseButton.SIZE_LARGE
 };
 
-module.exports = CloseButton;
+export default CloseButton;
diff --git a/src/components/costume-canvas/costume-canvas.jsx b/src/components/costume-canvas/costume-canvas.jsx
index 5a4a0342e866e667279a276db9675f134d19fe93..eafe92930f7eaf5f4dbfcd246b93ef7d6796bb25 100644
--- a/src/components/costume-canvas/costume-canvas.jsx
+++ b/src/components/costume-canvas/costume-canvas.jsx
@@ -127,4 +127,4 @@ CostumeCanvas.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = CostumeCanvas;
+export default CostumeCanvas;
diff --git a/src/components/filter/filter.jsx b/src/components/filter/filter.jsx
index d88f2f3019dfec29c20881e92540f700a5970930..5363ef081b3f99808f63513e5cf1b9c65a79e270 100644
--- a/src/components/filter/filter.jsx
+++ b/src/components/filter/filter.jsx
@@ -54,4 +54,4 @@ FilterComponent.propTypes = {
 FilterComponent.defaultProps = {
     placeholderText: 'what are you looking for?'
 };
-module.exports = FilterComponent;
+export default FilterComponent;
diff --git a/src/components/green-flag/green-flag.jsx b/src/components/green-flag/green-flag.jsx
index 0e9267389ef6137923cea51f07cd27b7302d3c86..692a347cd1eac1b8c33a56973c50bf0ca256d7c6 100644
--- a/src/components/green-flag/green-flag.jsx
+++ b/src/components/green-flag/green-flag.jsx
@@ -34,4 +34,4 @@ GreenFlagComponent.defaultProps = {
     active: false,
     title: 'Go'
 };
-module.exports = GreenFlagComponent;
+export default GreenFlagComponent;
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index 3eafbb71cad9329889752b19d36be8918c37407b..f15a5c9a933f1d1814bd54ef8537b6589cdb6645 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -121,4 +121,4 @@ GUIComponent.propTypes = {
 GUIComponent.defaultProps = {
     basePath: './'
 };
-module.exports = GUIComponent;
+export default GUIComponent;
diff --git a/src/components/language-selector/language-selector.jsx b/src/components/language-selector/language-selector.jsx
index 6c6ffd829179397a2c32dd35fe96cafafc2d55ad..febf81645f75c9c86308fad77fe4571340799669 100644
--- a/src/components/language-selector/language-selector.jsx
+++ b/src/components/language-selector/language-selector.jsx
@@ -41,4 +41,4 @@ LanguageSelector.propTypes = {
     onChange: PropTypes.func
 };
 
-module.exports = LanguageSelector;
+export default LanguageSelector;
diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx
index d96ea02515ce992b2e5acc063c1d10c74488da0d..5e0fa5edccc905313fa9529ad083d9db9ec76683 100644
--- a/src/components/library-item/library-item.jsx
+++ b/src/components/library-item/library-item.jsx
@@ -56,4 +56,4 @@ LibraryItem.propTypes = {
     onSelect: PropTypes.func.isRequired
 };
 
-module.exports = LibraryItem;
+export default LibraryItem;
diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx
index e878ebc735715a29317c49d0ac214b8dffd260f5..f5c0ae30cf4522811a57c9a275f56237467c9868 100644
--- a/src/components/library/library.jsx
+++ b/src/components/library/library.jsx
@@ -97,4 +97,4 @@ LibraryComponent.propTypes = {
     visible: PropTypes.bool.isRequired
 };
 
-module.exports = LibraryComponent;
+export default LibraryComponent;
diff --git a/src/components/load-button/load-button.jsx b/src/components/load-button/load-button.jsx
index 37519e99300fa82ff2f039fadc3defa3e053de25..dd94a2a11358ba0726888c7ed77550b6511acaa5 100644
--- a/src/components/load-button/load-button.jsx
+++ b/src/components/load-button/load-button.jsx
@@ -33,4 +33,4 @@ LoadButtonComponent.propTypes = {
 LoadButtonComponent.defaultProps = {
     title: 'Load'
 };
-module.exports = LoadButtonComponent;
+export default LoadButtonComponent;
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index 35ced7049699bd314269d3491d12388645303be8..661153f8dbcb47e6ca815c5026a24b2eb2f06dc7 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -29,4 +29,4 @@ const MenuBar = function MenuBar () {
     );
 };
 
-module.exports = MenuBar;
+export default MenuBar;
diff --git a/src/components/meter/meter.jsx b/src/components/meter/meter.jsx
index de8f3da93013dc58c6dccdd231079b01d85a5f6f..b2878a8dda6ae68fa27d19f5960ae4c120e82a43 100644
--- a/src/components/meter/meter.jsx
+++ b/src/components/meter/meter.jsx
@@ -59,4 +59,4 @@ Meter.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = Meter;
+export default Meter;
diff --git a/src/components/modal/modal.jsx b/src/components/modal/modal.jsx
index da4c62027c958bc6878cd612efc640fffe57e2ea..4b2711f514aa1078e619ee46466a9e856b7c62dd 100644
--- a/src/components/modal/modal.jsx
+++ b/src/components/modal/modal.jsx
@@ -72,4 +72,4 @@ ModalComponent.propTypes = {
     visible: PropTypes.bool.isRequired
 };
 
-module.exports = ModalComponent;
+export default ModalComponent;
diff --git a/src/components/monitor-list/monitor-list.jsx b/src/components/monitor-list/monitor-list.jsx
index 36337e7c2813b45a9c2f7a780b62a66417948521..e28f8e09877006c5682f68a7727d454e82ae3d75 100644
--- a/src/components/monitor-list/monitor-list.jsx
+++ b/src/components/monitor-list/monitor-list.jsx
@@ -30,4 +30,4 @@ MonitorList.propTypes = {
     onMonitorChange: PropTypes.func.isRequired
 };
 
-module.exports = MonitorList;
+export default MonitorList;
diff --git a/src/components/monitor/monitor.jsx b/src/components/monitor/monitor.jsx
index dbd86226c0c83cb801216a0f9ecfd8595f75b902..5d03b1ee495b928e02b5f00bb812b97e1d398c44 100644
--- a/src/components/monitor/monitor.jsx
+++ b/src/components/monitor/monitor.jsx
@@ -53,4 +53,4 @@ MonitorComponent.defaultProps = {
     y: 0
 };
 
-module.exports = MonitorComponent;
+export default MonitorComponent;
diff --git a/src/components/prompt/prompt.jsx b/src/components/prompt/prompt.jsx
index 7ea82374f919be793c60de542f0906fd71cafb8d..d43002b41a06f51a82ccd4a6038a441c59cfed7d 100644
--- a/src/components/prompt/prompt.jsx
+++ b/src/components/prompt/prompt.jsx
@@ -53,4 +53,4 @@ PromptComponent.propTypes = {
     title: PropTypes.string.isRequired
 };
 
-module.exports = PromptComponent;
+export default PromptComponent;
diff --git a/src/components/record-modal/playback-step.jsx b/src/components/record-modal/playback-step.jsx
index 0eddd9142c92c26782539b00a5b430c04eb70249..636d2ac9972bb53aa361fe1114fb614f371858b8 100644
--- a/src/components/record-modal/playback-step.jsx
+++ b/src/components/record-modal/playback-step.jsx
@@ -83,4 +83,4 @@ PlaybackStep.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = PlaybackStep;
+export default PlaybackStep;
diff --git a/src/components/record-modal/record-modal.jsx b/src/components/record-modal/record-modal.jsx
index 92bc0e38e47d2eefc15f34b2ba2768fb56d1b734..b215ad17f9e2ef866ff4893c49de4ac4210f25a2 100644
--- a/src/components/record-modal/record-modal.jsx
+++ b/src/components/record-modal/record-modal.jsx
@@ -63,4 +63,4 @@ RecordModal.propTypes = {
     trimStart: PropTypes.number.isRequired
 };
 
-module.exports = RecordModal;
+export default RecordModal;
diff --git a/src/components/record-modal/recording-step.jsx b/src/components/record-modal/recording-step.jsx
index ef78768c4e36e724afd54ed17804cd5200ab2784..624a2e2b2ae319ad69dbc7a1dc61f7779ee3a498 100644
--- a/src/components/record-modal/recording-step.jsx
+++ b/src/components/record-modal/recording-step.jsx
@@ -80,4 +80,4 @@ RecordingStep.propTypes = {
     recording: PropTypes.bool
 };
 
-module.exports = RecordingStep;
+export default RecordingStep;
diff --git a/src/components/sprite-info/sprite-info.jsx b/src/components/sprite-info/sprite-info.jsx
index f9e3e73bd44aef9497020440eedb2257bff85712..73c550c2c5e4169a1f7331ba1125b552cf47c888 100644
--- a/src/components/sprite-info/sprite-info.jsx
+++ b/src/components/sprite-info/sprite-info.jsx
@@ -190,4 +190,4 @@ SpriteInfo.propTypes = {
     ])
 };
 
-module.exports = SpriteInfo;
+export default SpriteInfo;
diff --git a/src/components/sprite-selector-item/sprite-selector-item.jsx b/src/components/sprite-selector-item/sprite-selector-item.jsx
index f9e3b5b1b23a1e575c490dbcfe3eb0fb1842c9de..d1be3c3dc33bb57c697539daa384203b92ca4f05 100644
--- a/src/components/sprite-selector-item/sprite-selector-item.jsx
+++ b/src/components/sprite-selector-item/sprite-selector-item.jsx
@@ -46,4 +46,4 @@ SpriteSelectorItem.propTypes = {
     selected: PropTypes.bool.isRequired
 };
 
-module.exports = SpriteSelectorItem;
+export default SpriteSelectorItem;
diff --git a/src/components/sprite-selector/sprite-selector.jsx b/src/components/sprite-selector/sprite-selector.jsx
index b5c8ee84448f60b8680fc0e4dd29ecce7b7cc239..6fc0a5bbc99b18ce1a992adfe3ba9c41bca6283a 100644
--- a/src/components/sprite-selector/sprite-selector.jsx
+++ b/src/components/sprite-selector/sprite-selector.jsx
@@ -98,4 +98,4 @@ SpriteSelectorComponent.propTypes = {
     })
 };
 
-module.exports = SpriteSelectorComponent;
+export default SpriteSelectorComponent;
diff --git a/src/components/stage-selector/stage-selector.jsx b/src/components/stage-selector/stage-selector.jsx
index eabb692e3e902ba9c0ab55a2a1097d0d548a0504..09ddb9a23d6a54f4c6c1307314f4a09364746c15 100644
--- a/src/components/stage-selector/stage-selector.jsx
+++ b/src/components/stage-selector/stage-selector.jsx
@@ -53,4 +53,4 @@ StageSelector.propTypes = {
     selected: PropTypes.bool.isRequired,
     url: PropTypes.string
 };
-module.exports = StageSelector;
+export default StageSelector;
diff --git a/src/components/stage/stage.jsx b/src/components/stage/stage.jsx
index 63a27bf56d48a870be28a1a4d38825e0b9bd1cba..92ef79f21679eed6fe77ef4935e702349d0578c3 100644
--- a/src/components/stage/stage.jsx
+++ b/src/components/stage/stage.jsx
@@ -38,4 +38,4 @@ StageComponent.defaultProps = {
     width: 480,
     height: 360
 };
-module.exports = StageComponent;
+export default StageComponent;
diff --git a/src/components/stop-all/stop-all.jsx b/src/components/stop-all/stop-all.jsx
index 4d85e2c465744b171d3bbab0417e974c7a1396ca..aba3ed42415c51456610ea5a892ddaccd0927921 100644
--- a/src/components/stop-all/stop-all.jsx
+++ b/src/components/stop-all/stop-all.jsx
@@ -37,4 +37,4 @@ StopAllComponent.defaultProps = {
     title: 'Stop'
 };
 
-module.exports = StopAllComponent;
+export default StopAllComponent;
diff --git a/src/components/target-pane/target-pane.jsx b/src/components/target-pane/target-pane.jsx
index 0d48924af8db08ade585f6ec843d01095b088f83..a6b7f2368251791a7be6c1a6bd1b071cc348278d 100644
--- a/src/components/target-pane/target-pane.jsx
+++ b/src/components/target-pane/target-pane.jsx
@@ -166,4 +166,4 @@ TargetPane.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = TargetPane;
+export default TargetPane;
diff --git a/src/components/waveform/waveform.jsx b/src/components/waveform/waveform.jsx
index 502bbb2801655fcd69f0de28bdf85a5ff82ab20c..7b46760ac33130ff405e245085a24a7c464b4fb5 100644
--- a/src/components/waveform/waveform.jsx
+++ b/src/components/waveform/waveform.jsx
@@ -48,4 +48,4 @@ Waveform.propTypes = {
     width: PropTypes.number
 };
 
-module.exports = Waveform;
+export default Waveform;
diff --git a/src/containers/audio-trimmer.jsx b/src/containers/audio-trimmer.jsx
index d9409b22564e72c488a1b1b65130a6c52f55aa13..07ba2154dbecd3dd8905198226c2f91f18cfb8ac 100644
--- a/src/containers/audio-trimmer.jsx
+++ b/src/containers/audio-trimmer.jsx
@@ -69,4 +69,4 @@ AudioTrimmer.propTypes = {
     trimStart: PropTypes.number
 };
 
-module.exports = AudioTrimmer;
+export default AudioTrimmer;
diff --git a/src/containers/backdrop-library.jsx b/src/containers/backdrop-library.jsx
index 72e2a1c7676dbf10570f2a6da2186e48eeae818c..e455a0a259f54ae24ecbf710192520e9fc3a8eab 100644
--- a/src/containers/backdrop-library.jsx
+++ b/src/containers/backdrop-library.jsx
@@ -43,4 +43,4 @@ BackdropLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = BackdropLibrary;
+export default BackdropLibrary;
diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index bc8e3ff3841a49881b11c23ce4d5235ccd3fa718..c922b68855602429b0cdcb7534501a3425ac0513 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -263,4 +263,4 @@ Blocks.defaultProps = {
     options: Blocks.defaultOptions
 };
 
-module.exports = Blocks;
+export default Blocks;
diff --git a/src/containers/costume-library.jsx b/src/containers/costume-library.jsx
index 168d4b950b4dbd1d525ac3ca40b2a3c99d0fb5db..ee5526752ea6361250895e0b54773414a3cedb24 100644
--- a/src/containers/costume-library.jsx
+++ b/src/containers/costume-library.jsx
@@ -43,4 +43,4 @@ CostumeLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = CostumeLibrary;
+export default CostumeLibrary;
diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx
index dcef1fa1e0927f6662b2364a1587e36895336436..594f1a7b94c9c74d46517f4ae289ba3b13962acd 100644
--- a/src/containers/costume-tab.jsx
+++ b/src/containers/costume-tab.jsx
@@ -9,10 +9,10 @@ import addCostumeIcon from '../components/asset-panel/icon--add-costume-lib.svg'
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openCostumeLibrary,
     openBackdropLibrary
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class CostumeTab extends React.Component {
     constructor (props) {
@@ -134,7 +134,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(CostumeTab);
diff --git a/src/containers/green-flag.jsx b/src/containers/green-flag.jsx
index e4f8520531d0764658bfbd7260f6fefff0a4625b..b1f6acabf620c7b54f431f1f1e0e65821a580be5 100644
--- a/src/containers/green-flag.jsx
+++ b/src/containers/green-flag.jsx
@@ -69,4 +69,4 @@ GreenFlag.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = GreenFlag;
+export default GreenFlag;
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index 89f25163990a9b9cac64764da950c218d927a4ae..87f195aab83d5e1a70b7d33258babfeee7dd14a3 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -56,4 +56,4 @@ GUI.propTypes = {
 
 GUI.defaultProps = GUIComponent.defaultProps;
 
-module.exports = vmListenerHOC(GUI);
+export default vmListenerHOC(GUI);
diff --git a/src/containers/language-selector.jsx b/src/containers/language-selector.jsx
index 9412b0c539f37a651cd986731c995557301b9667..ae0d2405cffb888abd2d8500a93ea382f3b53c5b 100644
--- a/src/containers/language-selector.jsx
+++ b/src/containers/language-selector.jsx
@@ -14,7 +14,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(LanguageSelectorComponent);
diff --git a/src/containers/load-button.jsx b/src/containers/load-button.jsx
index d07e5e105857d6042bd244e89fbf7e26eb14e564..a7b78a638dcf87871ced71752a668beebe153f87 100644
--- a/src/containers/load-button.jsx
+++ b/src/containers/load-button.jsx
@@ -49,7 +49,7 @@ const mapStateToProps = state => ({
     loadProject: state.vm.fromJSON.bind(state.vm)
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(LoadButton);
diff --git a/src/containers/monitor-list.jsx b/src/containers/monitor-list.jsx
index adfc2ea5acf58f6a085672538f8802ddda813f87..d8becdc668f2110388071ee230e83325715cba7c 100644
--- a/src/containers/monitor-list.jsx
+++ b/src/containers/monitor-list.jsx
@@ -30,7 +30,7 @@ const mapStateToProps = state => ({
 });
 const mapDispatchToProps = () => ({});
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(MonitorList);
diff --git a/src/containers/monitor.jsx b/src/containers/monitor.jsx
index 297649fa6550c95415d819e5982a6d182c85c93f..cbacffe7dc4d041796cca59dcf535ad23cecb25f 100644
--- a/src/containers/monitor.jsx
+++ b/src/containers/monitor.jsx
@@ -39,4 +39,4 @@ Monitor.propTypes = {
     value: PropTypes.string.isRequired // eslint-disable-line react/no-unused-prop-types
 };
 
-module.exports = Monitor;
+export default Monitor;
diff --git a/src/containers/playback-step.jsx b/src/containers/playback-step.jsx
index 8b0ba283d751f9a3b267c1cd81ff9fa561dea65f..ce61bcc045a0edc011c955fdd74f5ff42bc29f5d 100644
--- a/src/containers/playback-step.jsx
+++ b/src/containers/playback-step.jsx
@@ -53,4 +53,4 @@ PlaybackStep.propTypes = {
     ...PlaybackStepComponent.propTypes
 };
 
-module.exports = PlaybackStep;
+export default PlaybackStep;
diff --git a/src/containers/prompt.jsx b/src/containers/prompt.jsx
index 556caf949a3aaf1006f037b9c6885fce79cc1fe5..78158fd0515502ebc292b56f0631f06ba5fcede9 100644
--- a/src/containers/prompt.jsx
+++ b/src/containers/prompt.jsx
@@ -51,4 +51,4 @@ Prompt.propTypes = {
     title: PropTypes.string.isRequired
 };
 
-module.exports = Prompt;
+export default Prompt;
diff --git a/src/containers/record-modal.jsx b/src/containers/record-modal.jsx
index a59adaafa70d74974be55981ca5fe9f6b3872581..2f7cff84cba3047715fcda794610be2bb4017537 100644
--- a/src/containers/record-modal.jsx
+++ b/src/containers/record-modal.jsx
@@ -7,9 +7,9 @@ import {connect} from 'react-redux';
 
 import RecordModalComponent from '../components/record-modal/record-modal.jsx';
 
-const {
+import {
     closeSoundRecorder
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class RecordModal extends React.Component {
     constructor (props) {
@@ -139,7 +139,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(RecordModal);
diff --git a/src/containers/recording-step.jsx b/src/containers/recording-step.jsx
index ed9601635912e5beec22acadd3e85a6d9c101077..d1fc3302b46835b54a018f4a83b7d847c0bf5272 100644
--- a/src/containers/recording-step.jsx
+++ b/src/containers/recording-step.jsx
@@ -68,4 +68,4 @@ class RecordingStep extends React.Component {
 
 RecordingStep.propTypes = RecordingStepComponent.propTypes;
 
-module.exports = RecordingStep;
+export default RecordingStep;
diff --git a/src/containers/save-button.jsx b/src/containers/save-button.jsx
index 08585d0f0dc263238566e6873301c104f670a7c2..12585ab70a2b3a3d4c63ad7017a61ca3d7d213d9 100644
--- a/src/containers/save-button.jsx
+++ b/src/containers/save-button.jsx
@@ -56,7 +56,7 @@ const mapStateToProps = state => ({
     saveProjectSb3: state.vm.saveProjectSb3.bind(state.vm)
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(SaveButton);
diff --git a/src/containers/sound-library.jsx b/src/containers/sound-library.jsx
index 3de7f70537698fc5b2978a1d3a1121e072c0172b..9c1608fb7e568442b0c38bfa92c7843def04e7c1 100644
--- a/src/containers/sound-library.jsx
+++ b/src/containers/sound-library.jsx
@@ -91,4 +91,4 @@ SoundLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = SoundLibrary;
+export default SoundLibrary;
diff --git a/src/containers/sound-tab.jsx b/src/containers/sound-tab.jsx
index d0c41fe73264e5aa90fc3cd60fa46bb1219fc2b0..4aa43db974043d0871e48232ae9fa4868972eccf 100644
--- a/src/containers/sound-tab.jsx
+++ b/src/containers/sound-tab.jsx
@@ -13,10 +13,10 @@ import RecordModal from './record-modal.jsx';
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openSoundLibrary,
     openSoundRecorder
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 class SoundTab extends React.Component {
     constructor (props) {
@@ -153,7 +153,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(SoundTab);
diff --git a/src/containers/sprite-info.jsx b/src/containers/sprite-info.jsx
index 1b63c2e004547e26ddd86ad5dea6ff2a866215c8..532fb37e5fdb8c9af94602ef825257b7bb1d64a9 100644
--- a/src/containers/sprite-info.jsx
+++ b/src/containers/sprite-info.jsx
@@ -48,4 +48,4 @@ SpriteInfo.propTypes = {
     y: PropTypes.number
 };
 
-module.exports = SpriteInfo;
+export default SpriteInfo;
diff --git a/src/containers/sprite-library.jsx b/src/containers/sprite-library.jsx
index 17befee57d062263f3771c5dc425fe4948a7a9ca..cb11264205b38bd48333a629897059c0703ae212 100644
--- a/src/containers/sprite-library.jsx
+++ b/src/containers/sprite-library.jsx
@@ -82,4 +82,4 @@ SpriteLibrary.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = SpriteLibrary;
+export default SpriteLibrary;
diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx
index d662b15f48e913736a36f19c9204864e402a778f..aa19efc1f6bb6f2180501fd378f10766de01932b 100644
--- a/src/containers/sprite-selector-item.jsx
+++ b/src/containers/sprite-selector-item.jsx
@@ -58,6 +58,6 @@ const mapStateToProps = (state, {assetId, costumeURL}) => ({
     costumeURL: costumeURL || (assetId && state.vm.runtime.storage.get(assetId).encodeDataURI())
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps
 )(SpriteSelectorItem);
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index 5bb779e320ebb460a60576df90309151c95fbdd3..1c2018584c7f83a51ec13179f2517ed148edd310 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -44,7 +44,7 @@ const mapStateToProps = (state, {assetId}) => ({
     url: assetId && state.vm.runtime.storage.get(assetId).encodeDataURI()
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     () => ({}) // omit dispatch prop
 )(StageSelector);
diff --git a/src/containers/stage.jsx b/src/containers/stage.jsx
index 0c161023be3384496b28fc15d2ea2a3c5dcb42e0..f0545c088dc422b39b61ea7aa8ee17eb342c0853 100644
--- a/src/containers/stage.jsx
+++ b/src/containers/stage.jsx
@@ -195,4 +195,4 @@ Stage.propTypes = {
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
-module.exports = Stage;
+export default Stage;
diff --git a/src/containers/stop-all.jsx b/src/containers/stop-all.jsx
index 4f80a2eaf6e1a1b504bb0fa39514d12463a90a1e..0f7641a20b7f9db5c0769ca89374cb1faeef1b4f 100644
--- a/src/containers/stop-all.jsx
+++ b/src/containers/stop-all.jsx
@@ -52,4 +52,4 @@ StopAll.propTypes = {
     vm: PropTypes.instanceOf(VM)
 };
 
-module.exports = StopAll;
+export default StopAll;
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index 0d8a3a15c528458dbc8528926a74f98d42179c60..3445e49efe91a9f43e60f28e958068e8d5a3e5ee 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -3,14 +3,14 @@ import React from 'react';
 
 import {connect} from 'react-redux';
 
-const {
+import {
     openBackdropLibrary,
     openSpriteLibrary,
     closeBackdropLibrary,
     closeCostumeLibrary,
     closeSoundLibrary,
     closeSpriteLibrary
-} = require('../reducers/modals');
+} from '../reducers/modals';
 
 import TargetPaneComponent from '../components/target-pane/target-pane.jsx';
 
@@ -117,7 +117,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-module.exports = connect(
+export default connect(
     mapStateToProps,
     mapDispatchToProps
 )(TargetPane);
diff --git a/src/lib/audio/audio-buffer-player.js b/src/lib/audio/audio-buffer-player.js
index ba333f1f90289b4478df0acc119b5be931f0f721..5d643c8463d199d6a0cab38371a71f61c780d307 100644
--- a/src/lib/audio/audio-buffer-player.js
+++ b/src/lib/audio/audio-buffer-player.js
@@ -50,4 +50,4 @@ class AudioBufferPlayer {
     }
 }
 
-module.exports = AudioBufferPlayer;
+export default AudioBufferPlayer;
diff --git a/src/lib/audio/audio-recorder.js b/src/lib/audio/audio-recorder.js
index ace2b9807768d91536110e55d65b3a754f9c7ff8..e10ff81ce1c7d48936e4aeb465489b9238db2cf4 100644
--- a/src/lib/audio/audio-recorder.js
+++ b/src/lib/audio/audio-recorder.js
@@ -136,4 +136,4 @@ class AudioRecorder {
     }
 }
 
-module.exports = AudioRecorder;
+export default AudioRecorder;
diff --git a/src/lib/audio/shared-audio-context.js b/src/lib/audio/shared-audio-context.js
index c76e7966788e1f467a98af71020b564fbec1cb0e..f0b5c3ccf39fffad10de75ac9272eb3156175acc 100644
--- a/src/lib/audio/shared-audio-context.js
+++ b/src/lib/audio/shared-audio-context.js
@@ -1,6 +1,6 @@
 // Wrap browser AudioContext because we shouldn't create more than one
 const AUDIO_CONTEXT = new (window.AudioContext || window.webkitAudioContext)();
 
-module.exports = function () {
+export default function () {
     return AUDIO_CONTEXT;
-};
+}
diff --git a/src/lib/blocks.js b/src/lib/blocks.js
index b966846a6cef979c79041247fa25415edbb11a30..7c6b10b21cafe7e06a0fa9e3e126cb597cb8dc1a 100644
--- a/src/lib/blocks.js
+++ b/src/lib/blocks.js
@@ -1,6 +1,6 @@
 import ScratchBlocks from 'scratch-blocks';
 
-module.exports = function (vm) {
+export default function (vm) {
 
     const jsonForMenuBlock = function (name, menuOptionsFn, colors, start) {
         return {
@@ -137,4 +137,4 @@ module.exports = function (vm) {
     };
 
     return ScratchBlocks;
-};
+}
diff --git a/src/lib/log.js b/src/lib/log.js
index 839dc372d04d3e1686c0b3e56eeb1e9dacc27bbe..6d1cb725f060dbaaba8e9506b41a2fd32f3fd5e1 100644
--- a/src/lib/log.js
+++ b/src/lib/log.js
@@ -1,4 +1,4 @@
 import minilog from 'minilog';
 minilog.enable();
 
-module.exports = minilog('gui');
+export default minilog('gui');
diff --git a/src/lib/monitor-adapter.js b/src/lib/monitor-adapter.js
index 0fc7efbc5ac23008ea4e521daa6c838a8500ba8f..4a05cf3282ba569e2afd96407f8a4a91dd7fac7e 100644
--- a/src/lib/monitor-adapter.js
+++ b/src/lib/monitor-adapter.js
@@ -10,7 +10,7 @@ const MONITOR_HEIGHT = 23;
 
 const isUndefined = a => typeof a === 'undefined';
 
-module.exports = function ({id, index, opcode, params, value, x, y}) {
+export default function ({id, index, opcode, params, value, x, y}) {
     let {label, category, labelFn} = OpcodeLabels(opcode);
 
     // Use labelFn if provided for dynamic labelling (e.g. variables)
@@ -23,4 +23,4 @@ module.exports = function ({id, index, opcode, params, value, x, y}) {
     if (isUndefined(y)) y = PADDING + (index * (PADDING + MONITOR_HEIGHT));
 
     return {id, label, category, value, x, y};
-};
+}
diff --git a/src/lib/opcode-labels.js b/src/lib/opcode-labels.js
index bebe14743630de643343e9b88318b88fdf312b07..6acc4109b3ca661cecb3bb2bf51b6d2cc7e01bf9 100644
--- a/src/lib/opcode-labels.js
+++ b/src/lib/opcode-labels.js
@@ -66,10 +66,10 @@ const opcodeMap = {
     }
 };
 
-module.exports = function (opcode) {
+export default function (opcode) {
     if (opcode in opcodeMap) return opcodeMap[opcode];
     return {
         category: 'data',
         label: opcode
     };
-};
+}
diff --git a/src/lib/project-loader.js b/src/lib/project-loader.js
index 5b15929dc729520c8b77295faec49c243898eb27..05060732065e890b13e99e0cb9e4b90fe47dff31 100644
--- a/src/lib/project-loader.js
+++ b/src/lib/project-loader.js
@@ -1,6 +1,7 @@
 import xhr from 'xhr';
 
 import log from './log';
+import emptyProject from './empty-project.json';
 
 class ProjectLoader {
     constructor () {
@@ -17,6 +18,6 @@ class ProjectLoader {
     }
 }
 
-ProjectLoader.DEFAULT_PROJECT_DATA = require('./empty-project.json');
+ProjectLoader.DEFAULT_PROJECT_DATA = emptyProject;
 
-module.exports = new ProjectLoader();
+export default new ProjectLoader();
diff --git a/src/lib/storage.js b/src/lib/storage.js
index 6b3f4877c1c2330c1c5b5e762855c1d0042902fb..e1dc91bd6277148f3102a47aca8b7afd2a5401c3 100644
--- a/src/lib/storage.js
+++ b/src/lib/storage.js
@@ -26,4 +26,4 @@ class Storage extends ScratchStorage {
     }
 }
 
-module.exports = Storage;
+export default Storage;
diff --git a/src/lib/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx
index 8cbf05c504205e523968583cd6e7048e3264f2b5..e0f2bcb5da13e5aed244bee641b8aec16b3497f5 100644
--- a/src/lib/vm-listener-hoc.jsx
+++ b/src/lib/vm-listener-hoc.jsx
@@ -113,4 +113,4 @@ const vmListenerHOC = function (WrappedComponent) {
     )(VMListener);
 };
 
-module.exports = vmListenerHOC;
+export default vmListenerHOC;
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index c08306e997751f6a9fa699eb8b6ef31bc81071eb..c83dd7fca45d3af7d5cbc186c12f4c84f148c81c 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -6,7 +6,7 @@ import targetReducer from './targets';
 import vmReducer from './vm';
 
 
-module.exports = combineReducers({
+export default combineReducers({
     intl: intlReducer,
     modals: modalReducer,
     monitors: monitorReducer,
diff --git a/src/reducers/intl.js b/src/reducers/intl.js
index 14fa64ef5ad657759b4e9ed79189ea0150adf174..dda310dfb7da9136e05d9f27fd8332ecbba387b4 100644
--- a/src/reducers/intl.js
+++ b/src/reducers/intl.js
@@ -22,4 +22,9 @@ const updateIntl = locale => superUpdateIntl({
     messages: messages[locale] || messages.en
 });
 
-export {intlReducer as default, IntlProvider, intlInitialState, updateIntl};
+export {
+    intlReducer as default,
+    IntlProvider,
+    intlInitialState,
+    updateIntl
+};
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index 2e59b144a81e62bed6ee950be26f2b414826e48f..e651f05172e52d5a83e5bd5373e2d9874d091f58 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -30,46 +30,58 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.openModal = function (modal) {
+const openModal = function (modal) {
     return {
         type: OPEN_MODAL,
         modal: modal
     };
 };
-reducer.closeModal = function (modal) {
+const closeModal = function (modal) {
     return {
         type: CLOSE_MODAL,
         modal: modal
     };
 };
-reducer.openBackdropLibrary = function () {
-    return reducer.openModal(MODAL_BACKDROP_LIBRARY);
+const openBackdropLibrary = function () {
+    return openModal(MODAL_BACKDROP_LIBRARY);
 };
-reducer.openCostumeLibrary = function () {
-    return reducer.openModal(MODAL_COSTUME_LIBRARY);
+const openCostumeLibrary = function () {
+    return openModal(MODAL_COSTUME_LIBRARY);
 };
-reducer.openSoundLibrary = function () {
-    return reducer.openModal(MODAL_SOUND_LIBRARY);
+const openSoundLibrary = function () {
+    return openModal(MODAL_SOUND_LIBRARY);
 };
-reducer.openSpriteLibrary = function () {
-    return reducer.openModal(MODAL_SPRITE_LIBRARY);
+const openSpriteLibrary = function () {
+    return openModal(MODAL_SPRITE_LIBRARY);
 };
-reducer.openSoundRecorder = function () {
-    return reducer.openModal(MODAL_SOUND_RECORDER);
+const openSoundRecorder = function () {
+    return openModal(MODAL_SOUND_RECORDER);
 };
-reducer.closeBackdropLibrary = function () {
-    return reducer.closeModal(MODAL_BACKDROP_LIBRARY);
+const closeBackdropLibrary = function () {
+    return closeModal(MODAL_BACKDROP_LIBRARY);
 };
-reducer.closeCostumeLibrary = function () {
-    return reducer.closeModal(MODAL_COSTUME_LIBRARY);
+const closeCostumeLibrary = function () {
+    return closeModal(MODAL_COSTUME_LIBRARY);
 };
-reducer.closeSpriteLibrary = function () {
-    return reducer.closeModal(MODAL_SPRITE_LIBRARY);
+const closeSpriteLibrary = function () {
+    return closeModal(MODAL_SPRITE_LIBRARY);
 };
-reducer.closeSoundLibrary = function () {
-    return reducer.closeModal(MODAL_SOUND_LIBRARY);
+const closeSoundLibrary = function () {
+    return closeModal(MODAL_SOUND_LIBRARY);
 };
-reducer.closeSoundRecorder = function () {
-    return reducer.closeModal(MODAL_SOUND_RECORDER);
+const closeSoundRecorder = function () {
+    return closeModal(MODAL_SOUND_RECORDER);
+};
+export {
+    reducer as default,
+    openBackdropLibrary,
+    openCostumeLibrary,
+    openSoundLibrary,
+    openSpriteLibrary,
+    openSoundRecorder,
+    closeBackdropLibrary,
+    closeCostumeLibrary,
+    closeSpriteLibrary,
+    closeSoundLibrary,
+    closeSoundRecorder
 };
-module.exports = reducer;
diff --git a/src/reducers/monitors.js b/src/reducers/monitors.js
index e1428c2c60d2b4a90e5a10cb69a3581732964309..1b1b1f43679b0b3441b1c9f5f35d60f2f0045a20 100644
--- a/src/reducers/monitors.js
+++ b/src/reducers/monitors.js
@@ -13,7 +13,7 @@ const reducer = function (state, action) {
     }
 };
 
-reducer.updateMonitors = function (monitors) {
+const updateMonitors = function (monitors) {
     return {
         type: UPDATE_MONITORS,
         monitors: monitors,
@@ -23,4 +23,7 @@ reducer.updateMonitors = function (monitors) {
     };
 };
 
-module.exports = reducer;
+export {
+    reducer as default,
+    updateMonitors
+};
diff --git a/src/reducers/targets.js b/src/reducers/targets.js
index 0ed67cf2de94ceadf32e143037321458c5347a68..6df9632d9d1cce0e73b5ed74c07399ec1271866a 100644
--- a/src/reducers/targets.js
+++ b/src/reducers/targets.js
@@ -29,7 +29,7 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.updateTargets = function (targetList) {
+const updateTargets = function (targetList) {
     return {
         type: UPDATE_TARGET_LIST,
         targets: targetList,
@@ -38,7 +38,7 @@ reducer.updateTargets = function (targetList) {
         }
     };
 };
-reducer.updateEditingTarget = function (editingTarget) {
+const updateEditingTarget = function (editingTarget) {
     return {
         type: UPDATE_EDITING_TARGET,
         target: editingTarget,
@@ -47,4 +47,8 @@ reducer.updateEditingTarget = function (editingTarget) {
         }
     };
 };
-module.exports = reducer;
+export {
+    reducer as default,
+    updateTargets,
+    updateEditingTarget
+};
diff --git a/src/reducers/vm.js b/src/reducers/vm.js
index 2ac5c1c923267da5d17c127e865a1e3881e96d23..5d0e6f91f0cf707557316d63778e406c58f606c8 100644
--- a/src/reducers/vm.js
+++ b/src/reducers/vm.js
@@ -15,10 +15,13 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.setVM = function (vm) {
+const setVM = function (vm) {
     return {
         type: SET_VM,
         vm: vm
     };
 };
-module.exports = reducer;
+export {
+    reducer as default,
+    setVM
+};