diff --git a/package.json b/package.json
index 7765b8dd74165a1be9eafcd6b8bcabc1d63c7a36..54d7f7f2f954ce07c745b544613aba57b2d3ad2d 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
     "react-dom": "^15"
   },
   "devDependencies": {
-    "autoprefixer": "6.7.7",
+    "autoprefixer": "7.1.0",
     "babel-core": "^6.23.1",
     "babel-eslint": "^7.1.1",
     "babel-loader": "^7.0.0",
@@ -32,11 +32,11 @@
     "babel-preset-react": "^6.22.0",
     "classnames": "2.2.5",
     "copy-webpack-plugin": "4.0.1",
-    "css-loader": "0.28.0",
+    "css-loader": "0.28.1",
     "eslint": "^3.16.1",
     "eslint-config-scratch": "^3.0.0",
-    "eslint-plugin-react": "^6.10.0",
-    "gh-pages": "^0.12.0",
+    "eslint-plugin-react": "^7.0.1",
+    "gh-pages": "^1.0.0",
     "html-webpack-plugin": "2.28.0",
     "lodash.bindall": "4.4.0",
     "lodash.defaultsdeep": "4.6.0",
@@ -45,26 +45,26 @@
     "lodash.pick": "4.4.0",
     "minilog": "3.1.0",
     "mkdirp": "^0.5.1",
-    "postcss-import": "9.1.0",
-    "postcss-loader": "1.3.3",
-    "postcss-simple-vars": "3.1.0",
-    "prop-types": "15.5.8",
+    "postcss-import": "^10.0.0",
+    "postcss-loader": "^2.0.5",
+    "postcss-simple-vars": "^4.0.0",
+    "prop-types": "^15.5.10",
     "react": "15.5.4",
     "react-dom": "15.5.4",
     "react-draggable": "2.2.6",
     "react-modal": "1.7.7",
-    "react-redux": "5.0.4",
+    "react-redux": "5.0.5",
     "react-style-proptype": "3.0.0",
-    "react-tabs": "0.8.3",
+    "react-tabs": "1.0.0",
     "redux": "3.6.0",
     "redux-throttle": "0.1.1",
     "rimraf": "^2.6.1",
     "scratch-audio": "^0.1.0-prerelease.0",
     "scratch-blocks": "^0.1.0-prerelease.0",
     "scratch-render": "^0.1.0-prerelease.0",
-    "scratch-storage": "^0.0.1-prerelease.0",
+    "scratch-storage": "^0.1.0",
     "scratch-vm": "^0.1.0-prerelease.0",
-    "style-loader": "0.16.1",
+    "style-loader": "^0.17.0",
     "svg-to-image": "1.1.3",
     "svg-url-loader": "2.0.2",
     "travis-after-all": "^1.4.4",
diff --git a/src/components/asset-panel/selector.jsx b/src/components/asset-panel/selector.jsx
index d0d076bab5b9be6ecc64a152cb8e3f6954021106..0ddc2bb51202771fc9861ac603174bb28716773f 100644
--- a/src/components/asset-panel/selector.jsx
+++ b/src/components/asset-panel/selector.jsx
@@ -27,6 +27,7 @@ const Selector = props => {
             <Box className={styles.listArea}>
                 {items.map((item, index) => (
                     <SpriteSelectorItem
+                        assetId={item.assetId}
                         className={styles.listItem}
                         costumeURL={item.url}
                         id={index}
diff --git a/src/components/button/button.css b/src/components/button/button.css
new file mode 100644
index 0000000000000000000000000000000000000000..44243650f970d16aa787b8a44da3763e595802ce
--- /dev/null
+++ b/src/components/button/button.css
@@ -0,0 +1,3 @@
+.button {
+    cursor: pointer;
+}
diff --git a/src/components/button/button.jsx b/src/components/button/button.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..dbc852395625e7e2b3fec55a7a71de91e5e1aa37
--- /dev/null
+++ b/src/components/button/button.jsx
@@ -0,0 +1,31 @@
+const classNames = require('classnames');
+const PropTypes = require('prop-types');
+const React = require('react');
+
+const styles = require('./button.css');
+
+const ButtonComponent = ({
+    className,
+    onClick,
+    children,
+    ...props
+}) => (
+    <span
+        className={classNames(
+            styles.button,
+            className
+        )}
+        role="button"
+        onClick={onClick}
+        {...props}
+    >
+        {children}
+    </span>
+);
+
+ButtonComponent.propTypes = {
+    children: PropTypes.node,
+    className: PropTypes.string,
+    onClick: PropTypes.func.isRequired
+};
+module.exports = ButtonComponent;
diff --git a/src/components/gui/gui.css b/src/components/gui/gui.css
index e2fe4db4333437657c6c3009fdde3c8df478b158..ebaf67d845cc1893abe6f63fc6fbfebcf04b19dd 100644
--- a/src/components/gui/gui.css
+++ b/src/components/gui/gui.css
@@ -47,7 +47,7 @@
     border-bottom: 0 !important;
 }
 
-.tab-list .tab {
+.tab {
     flex-grow: 1;
     height: 80%;
     margin-left: 1px;
@@ -63,9 +63,9 @@
     align-items: center;
 }
 
-
-.tab-list .tab[aria-selected="true"] {
+.tab.is-selected {
     color: #40B9F5;
+    background-color: #FFFFFF;
 }
 
 .tabs {
@@ -80,6 +80,10 @@
     position: relative;
     flex-grow: 1;
     flex-shrink: 0;
+    display: none;
+}
+
+.tab-panel.is-selected {
     display: flex;
 }
 
diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index 91ed77ec2ada63de1bcb53e85b0a6acd38989c89..47fb1b327a32a91fc25b4851a5e457b9364add5e 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -1,6 +1,10 @@
+const classNames = require('classnames');
 const PropTypes = require('prop-types');
 const React = require('react');
+const {Tab, Tabs, TabList, TabPanel} = require('react-tabs');
+const tabStyles = require('react-tabs/style/react-tabs.css');
 const VM = require('scratch-vm');
+
 const Blocks = require('../../containers/blocks.jsx');
 const CostumeTab = require('../../containers/costume-tab.jsx');
 const GreenFlag = require('../../containers/green-flag.jsx');
@@ -8,17 +12,20 @@ const TargetPane = require('../../containers/target-pane.jsx');
 const SoundTab = require('../../containers/sound-tab.jsx');
 const Stage = require('../../containers/stage.jsx');
 const StopAll = require('../../containers/stop-all.jsx');
-const MenuBar = require('../menu-bar/menu-bar.jsx');
-const {Tab, Tabs, TabList, TabPanel} = require('react-tabs');
 
 const Box = require('../box/box.jsx');
+const MenuBar = require('../menu-bar/menu-bar.jsx');
+
 const styles = require('./gui.css');
 
+
 const GUIComponent = props => {
     const {
         basePath,
         children,
         vm,
+        onTabSelect,
+        tabIndex,
         ...componentProps
     } = props;
     if (children) {
@@ -29,11 +36,13 @@ const GUIComponent = props => {
         );
     }
 
-    // @todo hack to resize blockly manually in case resize happened while hidden
-    const handleTabSelect = tabIndex => {
-        if (tabIndex === 0) {
-            setTimeout(() => window.dispatchEvent(new Event('resize')));
-        }
+    const tabClassNames = {
+        tabs: styles.tabs,
+        tab: classNames(tabStyles.reactTabsTab, styles.tab),
+        tabList: classNames(tabStyles.reactTabsTabList, styles.tabList),
+        tabPanel: classNames(tabStyles.reactTabsTabPanel, styles.tabPanel),
+        tabPanelSelected: classNames(tabStyles.reactTabsTabPanelSelected, styles.isSelected),
+        tabSelected: classNames(tabStyles.reactTabsTabSelected, styles.isSelected)
     };
 
     return (
@@ -46,19 +55,22 @@ const GUIComponent = props => {
                 <Box className={styles.flexWrapper}>
                     <Box className={styles.editorWrapper}>
                         <Tabs
-                            className={styles.tabs}
+                            className={tabClassNames.tabs}
                             forceRenderTabPanel={true} // eslint-disable-line react/jsx-boolean-value
-                            onSelect={handleTabSelect}
+                            selectedTabClassName={tabClassNames.tabSelected}
+                            selectedTabPanelClassName={tabClassNames.tabPanelSelected}
+                            onSelect={onTabSelect}
                         >
-                            <TabList className={styles.tabList}>
-                                <Tab className={styles.tab}>Scripts</Tab>
-                                <Tab className={styles.tab}>Costumes</Tab>
-                                <Tab className={styles.tab}>Sounds</Tab>
+                            <TabList className={tabClassNames.tabList}>
+                                <Tab className={tabClassNames.tab}>Scripts</Tab>
+                                <Tab className={tabClassNames.tab}>Costumes</Tab>
+                                <Tab className={tabClassNames.tab}>Sounds</Tab>
                             </TabList>
-                            <TabPanel className={styles.tabPanel}>
+                            <TabPanel className={tabClassNames.tabPanel}>
                                 <Box className={styles.blocksWrapper}>
                                     <Blocks
                                         grow={1}
+                                        isVisible={tabIndex === 0} // Scripts tab
                                         options={{
                                             media: `${basePath}static/blocks-media/`
                                         }}
@@ -66,10 +78,10 @@ const GUIComponent = props => {
                                     />
                                 </Box>
                             </TabPanel>
-                            <TabPanel className={styles.tabPanel}>
+                            <TabPanel className={tabClassNames.tabPanel}>
                                 <CostumeTab vm={vm} />
                             </TabPanel>
-                            <TabPanel className={styles.tabPanel}>
+                            <TabPanel className={tabClassNames.tabPanel}>
                                 <SoundTab vm={vm} />
                             </TabPanel>
                         </Tabs>
@@ -102,6 +114,8 @@ const GUIComponent = props => {
 GUIComponent.propTypes = {
     basePath: PropTypes.string,
     children: PropTypes.node,
+    onTabSelect: PropTypes.func,
+    tabIndex: PropTypes.number,
     vm: PropTypes.instanceOf(VM).isRequired
 };
 GUIComponent.defaultProps = {
diff --git a/src/components/library-item/library-item.css b/src/components/library-item/library-item.css
index 288b760546027f8308c5c579cec7ff7630602ba2..3102d3d2d2a29d5f58db70f638b3d15fc5404491 100644
--- a/src/components/library-item/library-item.css
+++ b/src/components/library-item/library-item.css
@@ -26,11 +26,6 @@
     border-color: #1dacf4;
 }
 
-.library-item.is-selected {
-    border-width: 2px;
-    border-color: #1dacf4;
-}
-
 .library-item-image-container {
     height: 100px;
 }
diff --git a/src/components/library-item/library-item.jsx b/src/components/library-item/library-item.jsx
index 31e722b0e8fd6cc9bb7d76cd24bd8fdf12cfe9e5..8e113c9be08af583a36272da486fe8afe31e0367 100644
--- a/src/components/library-item/library-item.jsx
+++ b/src/components/library-item/library-item.jsx
@@ -1,4 +1,3 @@
-const classNames = require('classnames');
 const bindAll = require('lodash.bindall');
 const PropTypes = require('prop-types');
 const React = require('react');
@@ -9,20 +8,29 @@ const styles = require('./library-item.css');
 class LibraryItem extends React.Component {
     constructor (props) {
         super(props);
-        bindAll(this, ['handleClick']);
+        bindAll(this, [
+            'handleClick',
+            'handleMouseEnter',
+            'handleMouseLeave'
+        ]);
     }
     handleClick (e) {
         this.props.onSelect(this.props.id);
         e.preventDefault();
     }
+    handleMouseEnter () {
+        this.props.onMouseEnter(this.props.id);
+    }
+    handleMouseLeave () {
+        this.props.onMouseLeave(this.props.id);
+    }
     render () {
         return (
             <Box
-                className={classNames({
-                    [styles.libraryItem]: true,
-                    [styles.isSelected]: this.props.selected
-                })}
+                className={styles.libraryItem}
                 onClick={this.handleClick}
+                onMouseEnter={this.handleMouseEnter}
+                onMouseLeave={this.handleMouseLeave}
             >
                 <Box className={styles.libraryItemImageContainer}>
                     <img
@@ -40,8 +48,9 @@ LibraryItem.propTypes = {
     iconURL: PropTypes.string.isRequired,
     id: PropTypes.number.isRequired,
     name: PropTypes.string.isRequired,
-    onSelect: PropTypes.func.isRequired,
-    selected: PropTypes.bool.isRequired
+    onMouseEnter: PropTypes.func.isRequired,
+    onMouseLeave: PropTypes.func.isRequired,
+    onSelect: PropTypes.func.isRequired
 };
 
 module.exports = LibraryItem;
diff --git a/src/components/library/library.jsx b/src/components/library/library.jsx
index 27cfe4116e404c87802b929b9063eacca6f84782..9b03b0b8dd03af8ef0e38bdf96087d122a917762 100644
--- a/src/components/library/library.jsx
+++ b/src/components/library/library.jsx
@@ -11,8 +11,10 @@ class LibraryComponent extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
-            'handleSelect',
-            'handleFilterChange'
+            'handleFilterChange',
+            'handleMouseEnter',
+            'handleMouseLeave',
+            'handleSelect'
         ]);
         this.state = {
             selectedItem: null,
@@ -20,16 +22,14 @@ class LibraryComponent extends React.Component {
         };
     }
     handleSelect (id) {
-        if (this.state.selectedItem === id) {
-            // Double select: select as the library's value.
-            this.props.onRequestClose();
-            this.props.onItemSelected(this.getFilteredData()[id]);
-        } else {
-            if (this.props.onItemChosen) {
-                this.props.onItemChosen(this.getFilteredData()[id]);
-            }
-        }
-        this.setState({selectedItem: id});
+        this.props.onRequestClose();
+        this.props.onItemSelected(this.getFilteredData()[id]);
+    }
+    handleMouseEnter (id) {
+        if (this.props.onItemMouseEnter) this.props.onItemMouseEnter(this.getFilteredData()[id]);
+    }
+    handleMouseLeave (id) {
+        if (this.props.onItemMouseLeave) this.props.onItemMouseLeave(this.getFilteredData()[id]);
     }
     handleFilterChange (event) {
         this.setState({
@@ -61,7 +61,8 @@ class LibraryComponent extends React.Component {
                                 id={index}
                                 key={`item_${index}`}
                                 name={dataItem.name}
-                                selected={this.state.selectedItem === index}
+                                onMouseEnter={this.handleMouseEnter}
+                                onMouseLeave={this.handleMouseLeave}
                                 onSelect={this.handleSelect}
                             />
                         );
@@ -84,7 +85,8 @@ LibraryComponent.propTypes = {
         })
         /* eslint-enable react/no-unused-prop-types, lines-around-comment */
     ),
-    onItemChosen: PropTypes.func,
+    onItemMouseEnter: PropTypes.func,
+    onItemMouseLeave: PropTypes.func,
     onItemSelected: PropTypes.func,
     onRequestClose: PropTypes.func,
     title: PropTypes.string.isRequired,
diff --git a/src/components/load-button/load-button.css b/src/components/load-button/load-button.css
new file mode 100644
index 0000000000000000000000000000000000000000..527718028aedbf6ec6636afe0df0625e2005c35c
--- /dev/null
+++ b/src/components/load-button/load-button.css
@@ -0,0 +1,3 @@
+.file-input {
+    display: none;
+}
diff --git a/src/components/load-button/load-button.jsx b/src/components/load-button/load-button.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..29b2962e5a6f2b6642c80ac9449f458f2ea70f85
--- /dev/null
+++ b/src/components/load-button/load-button.jsx
@@ -0,0 +1,36 @@
+const PropTypes = require('prop-types');
+const React = require('react');
+
+const ButtonComponent = require('../button/button.jsx');
+
+const styles = require('./load-button.css');
+
+const LoadButtonComponent = ({
+    inputRef,
+    onChange,
+    onClick,
+    title,
+    ...props
+}) => (
+    <span {...props}>
+        <ButtonComponent onClick={onClick}>{title}</ButtonComponent>
+        <input
+            className={styles.fileInput}
+            ref={inputRef}
+            type="file"
+            onChange={onChange}
+        />
+    </span>
+);
+
+LoadButtonComponent.propTypes = {
+    className: PropTypes.string,
+    inputRef: PropTypes.func.isRequired,
+    onChange: PropTypes.func.isRequired,
+    onClick: PropTypes.func.isRequired,
+    title: PropTypes.string
+};
+LoadButtonComponent.defaultProps = {
+    title: 'Load'
+};
+module.exports = LoadButtonComponent;
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index b34a2e1900a937ecba22f8d9944f48563136223f..4397b5002ea47789ed47cd3283a6ba917c24373d 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -2,6 +2,9 @@ const classNames = require('classnames');
 const React = require('react');
 
 const Box = require('../box/box.jsx');
+const LoadButton = require('../../containers/load-button.jsx');
+const SaveButton = require('../../containers/save-button.jsx');
+
 const styles = require('./menu-bar.css');
 const scratchLogo = require('./scratch-logo.svg');
 
@@ -18,7 +21,8 @@ const MenuBar = function MenuBar () {
                     src={scratchLogo}
                 />
             </div>
-            <div className={styles.menuItem} >Animation Playtest Prototype</div>
+            <SaveButton className={styles.menuItem} />
+            <LoadButton className={styles.menuItem} />
         </Box>
     );
 };
diff --git a/src/components/sprite-selector/sprite-selector.jsx b/src/components/sprite-selector/sprite-selector.jsx
index df48343745100b55e7f2a1334681b0aec65c3e58..3410c75809e683e67f664d11b01049f003fd0855 100644
--- a/src/components/sprite-selector/sprite-selector.jsx
+++ b/src/components/sprite-selector/sprite-selector.jsx
@@ -53,17 +53,15 @@ const SpriteSelectorComponent = function (props) {
                     {Object.keys(sprites)
                         // Re-order by list order
                         .sort((id1, id2) => sprites[id1].order - sprites[id2].order)
-                        .map(id => (
+                        .map(id => sprites[id])
+                        .map(sprite => (
                             <SpriteSelectorItem
+                                assetId={sprite.costume && sprite.costume.assetId}
                                 className={styles.sprite}
-                                costumeURL={
-                                    sprites[id].costume &&
-                                    sprites[id].costume.url
-                                }
-                                id={id}
-                                key={id}
-                                name={sprites[id].name}
-                                selected={id === selectedId}
+                                id={sprite.id}
+                                key={sprite.id}
+                                name={sprite.name}
+                                selected={sprite.id === selectedId}
                                 onClick={onSelectSprite}
                                 onDeleteButtonClick={onDeleteSprite}
                             />
diff --git a/src/components/target-pane/target-pane.jsx b/src/components/target-pane/target-pane.jsx
index 5d8fc1915cd185125ad12104a80c341590406895..c779f274713413e13d62851dae45c54223caadaa 100644
--- a/src/components/target-pane/target-pane.jsx
+++ b/src/components/target-pane/target-pane.jsx
@@ -1,5 +1,3 @@
-const isEqual = require('lodash.isequal');
-const omit = require('lodash.omit');
 const classNames = require('classnames');
 const PropTypes = require('prop-types');
 const React = require('react');
@@ -23,119 +21,106 @@ const addIcon = require('./icon--add.svg');
  * @param {object} props Props for the component
  * @returns {React.Component} rendered component
  */
-class TargetPane extends React.Component {
-    shouldComponentUpdate (nextProps) {
-        return (
-            // Do a normal shallow compare on all props except sprites
-            Object.keys(omit(nextProps, ['sprites']))
-                .reduce((all, k) => all || nextProps[k] !== this.props[k], false) ||
-            // Deep compare on sprites object
-            !isEqual(this.props.sprites, nextProps.sprites)
-        );
-    }
-    render () {
-        const {
-            editingTarget,
-            backdropLibraryVisible,
-            costumeLibraryVisible,
-            soundLibraryVisible,
-            spriteLibraryVisible,
-            onChangeSpriteDirection,
-            onChangeSpriteName,
-            onChangeSpriteRotationStyle,
-            onChangeSpriteVisibility,
-            onChangeSpriteX,
-            onChangeSpriteY,
-            onDeleteSprite,
-            onNewSpriteClick,
-            onNewBackdropClick,
-            onRequestCloseBackdropLibrary,
-            onRequestCloseCostumeLibrary,
-            onRequestCloseSoundLibrary,
-            onRequestCloseSpriteLibrary,
-            onSelectSprite,
-            stage,
-            sprites,
-            vm,
-            ...componentProps
-        } = this.props;
-        return (
-            <Box
-                className={styles.targetPane}
-                {...componentProps}
-            >
+const TargetPane = ({
+    editingTarget,
+    backdropLibraryVisible,
+    costumeLibraryVisible,
+    soundLibraryVisible,
+    spriteLibraryVisible,
+    onChangeSpriteDirection,
+    onChangeSpriteName,
+    onChangeSpriteRotationStyle,
+    onChangeSpriteVisibility,
+    onChangeSpriteX,
+    onChangeSpriteY,
+    onDeleteSprite,
+    onNewSpriteClick,
+    onNewBackdropClick,
+    onRequestCloseBackdropLibrary,
+    onRequestCloseCostumeLibrary,
+    onRequestCloseSoundLibrary,
+    onRequestCloseSpriteLibrary,
+    onSelectSprite,
+    stage,
+    sprites,
+    vm,
+    ...componentProps
+}) => (
+    <Box
+        className={styles.targetPane}
+        {...componentProps}
+    >
 
-                <SpriteSelectorComponent
-                    selectedId={editingTarget}
-                    sprites={sprites}
-                    onChangeSpriteDirection={onChangeSpriteDirection}
-                    onChangeSpriteName={onChangeSpriteName}
-                    onChangeSpriteRotationStyle={onChangeSpriteRotationStyle}
-                    onChangeSpriteVisibility={onChangeSpriteVisibility}
-                    onChangeSpriteX={onChangeSpriteX}
-                    onChangeSpriteY={onChangeSpriteY}
-                    onDeleteSprite={onDeleteSprite}
-                    onSelectSprite={onSelectSprite}
-                />
-                <Box className={styles.stageSelectorWrapper}>
-                    {stage.id && <StageSelector
-                        backdropCount={stage.costumeCount}
-                        id={stage.id}
-                        selected={stage.id === editingTarget}
-                        url={
-                            stage.costume &&
-                            stage.costume.url
-                        }
-                        onSelect={onSelectSprite}
-                    />}
-                    <Box>
+        <SpriteSelectorComponent
+            selectedId={editingTarget}
+            sprites={sprites}
+            onChangeSpriteDirection={onChangeSpriteDirection}
+            onChangeSpriteName={onChangeSpriteName}
+            onChangeSpriteRotationStyle={onChangeSpriteRotationStyle}
+            onChangeSpriteVisibility={onChangeSpriteVisibility}
+            onChangeSpriteX={onChangeSpriteX}
+            onChangeSpriteY={onChangeSpriteY}
+            onDeleteSprite={onDeleteSprite}
+            onSelectSprite={onSelectSprite}
+        />
+        <Box className={styles.stageSelectorWrapper}>
+            {stage.id && <StageSelector
+                assetId={
+                    stage.costume &&
+                    stage.costume.assetId
+                }
+                backdropCount={stage.costumeCount}
+                id={stage.id}
+                selected={stage.id === editingTarget}
+                onSelect={onSelectSprite}
+            />}
+            <Box>
 
-                        <button
-                            className={classNames(styles.addButtonWrapper, styles.addButtonWrapperSprite)}
-                            onClick={onNewSpriteClick}
-                        >
-                            <img
-                                className={styles.addButton}
-                                src={addIcon}
-                            />
-                        </button>
+                <button
+                    className={classNames(styles.addButtonWrapper, styles.addButtonWrapperSprite)}
+                    onClick={onNewSpriteClick}
+                >
+                    <img
+                        className={styles.addButton}
+                        src={addIcon}
+                    />
+                </button>
 
-                        <button
-                            className={classNames(styles.addButtonWrapper, styles.addButtonWrapperStage)}
-                            onClick={onNewBackdropClick}
-                        >
-                            <img
-                                className={styles.addButton}
-                                src={addIcon}
-                            />
-                        </button>
+                <button
+                    className={classNames(styles.addButtonWrapper, styles.addButtonWrapperStage)}
+                    onClick={onNewBackdropClick}
+                >
+                    <img
+                        className={styles.addButton}
+                        src={addIcon}
+                    />
+                </button>
 
-                        <SpriteLibrary
-                            visible={spriteLibraryVisible}
-                            vm={vm}
-                            onRequestClose={onRequestCloseSpriteLibrary}
-                        />
-                        <CostumeLibrary
-                            visible={costumeLibraryVisible}
-                            vm={vm}
-                            onRequestClose={onRequestCloseCostumeLibrary}
-                        />
-                        <SoundLibrary
-                            visible={soundLibraryVisible}
-                            vm={vm}
-                            onRequestClose={onRequestCloseSoundLibrary}
-                        />
-                        <BackdropLibrary
-                            visible={backdropLibraryVisible}
-                            vm={vm}
-                            onRequestClose={onRequestCloseBackdropLibrary}
-                        />
-                    </Box>
-                </Box>
+                <SpriteLibrary
+                    visible={spriteLibraryVisible}
+                    vm={vm}
+                    onRequestClose={onRequestCloseSpriteLibrary}
+                />
+                <CostumeLibrary
+                    visible={costumeLibraryVisible}
+                    vm={vm}
+                    onRequestClose={onRequestCloseCostumeLibrary}
+                />
+                <SoundLibrary
+                    visible={soundLibraryVisible}
+                    vm={vm}
+                    onRequestClose={onRequestCloseSoundLibrary}
+                />
+                <BackdropLibrary
+                    visible={backdropLibraryVisible}
+                    vm={vm}
+                    onRequestClose={onRequestCloseBackdropLibrary}
+                />
             </Box>
-        );
-    }
-}
+        </Box>
+    </Box>
+);
+
 const spriteShape = PropTypes.shape({
     costume: PropTypes.shape({
         url: PropTypes.string,
diff --git a/src/containers/backdrop-library.jsx b/src/containers/backdrop-library.jsx
index b19921b4c77605d0f1f8700d1e70e7e814aea283..62e9cd473a21a9db548868af3bd1d273bcc18359 100644
--- a/src/containers/backdrop-library.jsx
+++ b/src/containers/backdrop-library.jsx
@@ -4,7 +4,7 @@ const React = require('react');
 const VM = require('scratch-vm');
 
 const backdropLibraryContent = require('../lib/libraries/backdrops.json');
-const LibaryComponent = require('../components/library/library.jsx');
+const LibraryComponent = require('../components/library/library.jsx');
 
 
 class BackdropLibrary extends React.Component {
@@ -26,7 +26,7 @@ class BackdropLibrary extends React.Component {
     }
     render () {
         return (
-            <LibaryComponent
+            <LibraryComponent
                 data={backdropLibraryContent}
                 title="Backdrop Library"
                 visible={this.props.visible}
diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index ecd816204ee5a7d760e04a67d0f34599065eb1f6..487bed48078b808835bc7209ae5696913fa2d784 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -52,7 +52,21 @@ class Blocks extends React.Component {
         this.attachVM();
     }
     shouldComponentUpdate (nextProps, nextState) {
-        return this.state.prompt !== nextState.prompt;
+        return this.state.prompt !== nextState.prompt || this.props.isVisible !== nextProps.isVisible;
+    }
+    componentDidUpdate (prevProps) {
+        if (this.props.isVisible === prevProps.isVisible) {
+            return;
+        }
+
+        // @todo hack to resize blockly manually in case resize happened while hidden
+        if (this.props.isVisible) { // Scripts tab
+            window.dispatchEvent(new Event('resize'));
+            this.workspace.setVisible(true);
+            this.workspace.toolbox_.refreshSelection();
+        } else {
+            this.workspace.setVisible(false);
+        }
     }
     componentWillUnmount () {
         this.detachVM();
@@ -60,10 +74,11 @@ class Blocks extends React.Component {
     }
     attachVM () {
         this.workspace.addChangeListener(this.props.vm.blockListener);
-        this.workspace
+        this.flyoutWorkspace = this.workspace
             .getFlyout()
-            .getWorkspace()
-            .addChangeListener(this.props.vm.flyoutBlockListener);
+            .getWorkspace();
+        this.flyoutWorkspace.addChangeListener(this.props.vm.flyoutBlockListener);
+        this.flyoutWorkspace.addChangeListener(this.props.vm.monitorBlockListener);
         this.props.vm.addListener('SCRIPT_GLOW_ON', this.onScriptGlowOn);
         this.props.vm.addListener('SCRIPT_GLOW_OFF', this.onScriptGlowOff);
         this.props.vm.addListener('BLOCK_GLOW_ON', this.onBlockGlowOn);
@@ -146,6 +161,7 @@ class Blocks extends React.Component {
         const {
             options, // eslint-disable-line no-unused-vars
             vm, // eslint-disable-line no-unused-vars
+            isVisible, // eslint-disable-line no-unused-vars
             ...props
         } = this.props;
         return (
@@ -169,11 +185,12 @@ class Blocks extends React.Component {
 }
 
 Blocks.propTypes = {
+    isVisible: PropTypes.bool.isRequired,
     options: PropTypes.shape({
         media: PropTypes.string,
         zoom: PropTypes.shape({
-            controls: PropTypes.boolean,
-            wheel: PropTypes.boolean,
+            controls: PropTypes.bool,
+            wheel: PropTypes.bool,
             startScale: PropTypes.number
         }),
         colours: PropTypes.shape({
diff --git a/src/containers/costume-library.jsx b/src/containers/costume-library.jsx
index 1fea39a2dda106f7941084469c81fb0886f32130..d0a004ba674e37c4710c581ef1c72bd7658d798d 100644
--- a/src/containers/costume-library.jsx
+++ b/src/containers/costume-library.jsx
@@ -4,7 +4,7 @@ const React = require('react');
 const VM = require('scratch-vm');
 
 const costumeLibraryContent = require('../lib/libraries/costumes.json');
-const LibaryComponent = require('../components/library/library.jsx');
+const LibraryComponent = require('../components/library/library.jsx');
 
 
 class CostumeLibrary extends React.Component {
@@ -26,7 +26,7 @@ class CostumeLibrary extends React.Component {
     }
     render () {
         return (
-            <LibaryComponent
+            <LibraryComponent
                 data={costumeLibraryContent}
                 title="Costume Library"
                 visible={this.props.visible}
diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx
index 2c6c04a7e65e777d575a9e009555a5543ecbce10..af73857e75f5a2427da74c69e9f2ebc5b65769be 100644
--- a/src/containers/costume-tab.jsx
+++ b/src/containers/costume-tab.jsx
@@ -23,28 +23,25 @@ class CostumeTab extends React.Component {
         this.state = {selectedCostumeIndex: 0};
     }
 
+    componentWillReceiveProps (nextProps) {
+        const {
+            editingTarget,
+            sprites,
+            stage
+        } = nextProps;
+
+        const target = editingTarget && sprites[editingTarget] ? sprites[editingTarget] : stage;
+        if (target && target.costumes && this.state.selectedCostumeIndex > target.costumes.length - 1) {
+            this.setState({selectedCostumeIndex: target.costumes.length - 1});
+        }
+    }
+
     handleSelectCostume (costumeIndex) {
         this.setState({selectedCostumeIndex: costumeIndex});
     }
 
     handleDeleteCostume (costumeIndex) {
-        // @todo the VM should handle all of this logic
-        const {editingTarget} = this.props.vm;
-
-        if (costumeIndex === editingTarget.currentCostume) {
-            editingTarget.setCostume(costumeIndex - 1);
-        }
-
-        editingTarget.sprite.costumes = editingTarget.sprite.costumes
-            .slice(0, costumeIndex)
-            .concat(editingTarget.sprite.costumes.slice(costumeIndex + 1));
-        this.props.vm.runtime.spriteInfoReport(editingTarget);
-        // @todo not sure if this is getting redrawn correctly
-        this.props.vm.runtime.requestRedraw();
-
-        this.setState({
-            selectedCostumeIndex: this.state.selectedCostumeIndex % editingTarget.sprite.costumes.length
-        });
+        this.props.vm.deleteCostume(costumeIndex);
     }
 
     render () {
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index dec5c6c6d671587f28259b64f9f2841d8527af7f..fbc11d7da672f36029eb3a5c8373b17ac5e44fbe 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -1,12 +1,20 @@
 const PropTypes = require('prop-types');
 const React = require('react');
 const VM = require('scratch-vm');
+const bindAll = require('lodash.bindall');
 
 const vmListenerHOC = require('../lib/vm-listener-hoc.jsx');
 
 const GUIComponent = require('../components/gui/gui.jsx');
 
 class GUI extends React.Component {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'handleTabSelect'
+        ]);
+        this.state = {tabIndex: 0};
+    }
     componentDidMount () {
         this.props.vm.loadProject(this.props.projectData);
         this.props.vm.setCompatibilityMode(true);
@@ -20,6 +28,9 @@ class GUI extends React.Component {
     componentWillUnmount () {
         this.props.vm.stopAll();
     }
+    handleTabSelect (tabIndex) {
+        this.setState({tabIndex});
+    }
     render () {
         const {
             projectData, // eslint-disable-line no-unused-vars
@@ -28,7 +39,9 @@ class GUI extends React.Component {
         } = this.props;
         return (
             <GUIComponent
+                tabIndex={this.state.tabIndex}
                 vm={vm}
+                onTabSelect={this.handleTabSelect}
                 {...componentProps}
             />
         );
diff --git a/src/containers/load-button.jsx b/src/containers/load-button.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..dcbd4fe016094c04c940428758c6c858b682deb0
--- /dev/null
+++ b/src/containers/load-button.jsx
@@ -0,0 +1,55 @@
+const bindAll = require('lodash.bindall');
+const PropTypes = require('prop-types');
+const React = require('react');
+const {connect} = require('react-redux');
+
+const LoadButtonComponent = require('../components/load-button/load-button.jsx');
+
+class LoadButton extends React.Component {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'setFileInput',
+            'handleChange',
+            'handleClick'
+        ]);
+    }
+    handleChange (e) {
+        const reader = new FileReader();
+        reader.onload = () => this.props.loadProject(reader.result);
+        reader.readAsText(e.target.files[0]);
+    }
+    handleClick () {
+        this.fileInput.click();
+    }
+    setFileInput (input) {
+        this.fileInput = input;
+    }
+    render () {
+        const {
+            loadProject, // eslint-disable-line no-unused-vars
+            ...props
+        } = this.props;
+        return (
+            <LoadButtonComponent
+                inputRef={this.setFileInput}
+                onChange={this.handleChange}
+                onClick={this.handleClick}
+                {...props}
+            />
+        );
+    }
+}
+
+LoadButton.propTypes = {
+    loadProject: PropTypes.func.isRequired
+};
+
+const mapStateToProps = state => ({
+    loadProject: state.vm.fromJSON.bind(state.vm)
+});
+
+module.exports = connect(
+    mapStateToProps,
+    () => ({}) // omit dispatch prop
+)(LoadButton);
diff --git a/src/containers/save-button.jsx b/src/containers/save-button.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..f5e7ab018681e8008171ac64e8964db3e77a59ec
--- /dev/null
+++ b/src/containers/save-button.jsx
@@ -0,0 +1,62 @@
+const bindAll = require('lodash.bindall');
+const PropTypes = require('prop-types');
+const React = require('react');
+const {connect} = require('react-redux');
+
+const ButtonComponent = require('../components/button/button.jsx');
+
+class SaveButton extends React.Component {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'handleClick'
+        ]);
+    }
+    handleClick () {
+        const json = this.props.saveProjectSb3();
+
+        // Download project data into a file - create link element,
+        // simulate click on it, and then remove it.
+        const saveLink = document.createElement('a');
+        document.body.appendChild(saveLink);
+
+        const data = new Blob([json], {type: 'text'});
+        const url = window.URL.createObjectURL(data);
+        saveLink.href = url;
+
+        // File name: project-DATE-TIME
+        const date = new Date();
+        const timestamp = `${date.toLocaleDateString()}-${date.toLocaleTimeString()}`;
+        saveLink.download = `project-${timestamp}.json`;
+        saveLink.click();
+        window.URL.revokeObjectURL(url);
+        document.body.removeChild(saveLink);
+    }
+    render () {
+        const {
+            saveProjectSb3, // eslint-disable-line no-unused-vars
+            ...props
+        } = this.props;
+        return (
+            <ButtonComponent
+                onClick={this.handleClick}
+                {...props}
+            >
+                Save
+            </ButtonComponent>
+        );
+    }
+}
+
+SaveButton.propTypes = {
+    saveProjectSb3: PropTypes.func.isRequired
+};
+
+const mapStateToProps = state => ({
+    saveProjectSb3: state.vm.saveProjectSb3.bind(state.vm)
+});
+
+module.exports = connect(
+    mapStateToProps,
+    () => ({}) // omit dispatch prop
+)(SaveButton);
diff --git a/src/containers/sound-library.jsx b/src/containers/sound-library.jsx
index d478d141a7f6d8c538a03830b7583d4d39ad990c..53aa6bde02f9d54e0d394691549bd04416c7bce5 100644
--- a/src/containers/sound-library.jsx
+++ b/src/containers/sound-library.jsx
@@ -3,7 +3,7 @@ const PropTypes = require('prop-types');
 const React = require('react');
 const VM = require('scratch-vm');
 const AudioEngine = require('scratch-audio');
-const LibaryComponent = require('../components/library/library.jsx');
+const LibraryComponent = require('../components/library/library.jsx');
 
 const soundIcon = require('../components/asset-panel/icon--sound.svg');
 
@@ -14,14 +14,19 @@ class SoundLibrary extends React.Component {
         super(props);
         bindAll(this, [
             'handleItemSelected',
-            'handleItemChosen'
+            'handleItemMouseEnter',
+            'handleItemMouseLeave'
         ]);
     }
     componentDidMount () {
         this.audioEngine = new AudioEngine();
         this.player = this.audioEngine.createPlayer();
     }
-    handleItemChosen (soundItem) {
+    componentWillReceiveProps (newProps) {
+        // Stop playing sounds if the library closes without a mouseleave (e.g. by using the escape key)
+        if (this.player && !newProps.visible) this.player.stopAllSounds();
+    }
+    handleItemMouseEnter (soundItem) {
         const md5ext = soundItem._md5;
         const idParts = md5ext.split('.');
         const md5 = idParts[0];
@@ -39,6 +44,9 @@ class SoundLibrary extends React.Component {
             this.player.playSound(soundItem._md5);
         });
     }
+    handleItemMouseLeave () {
+        this.player.stopAllSounds();
+    }
     handleItemSelected (soundItem) {
         const vmSound = {
             format: soundItem.format,
@@ -64,11 +72,12 @@ class SoundLibrary extends React.Component {
         });
 
         return (
-            <LibaryComponent
+            <LibraryComponent
                 data={soundLibraryThumbnailData}
                 title="Sound Library"
                 visible={this.props.visible}
-                onItemChosen={this.handleItemChosen}
+                onItemMouseEnter={this.handleItemMouseEnter}
+                onItemMouseLeave={this.handleItemMouseLeave}
                 onItemSelected={this.handleItemSelected}
                 onRequestClose={this.props.onRequestClose}
             />
diff --git a/src/containers/sound-tab.jsx b/src/containers/sound-tab.jsx
index 227919dff524a8fee93616b2f1ba427feceef92a..70dfbdef7f6430f52dbb0d826e38cbfd58778fd8 100644
--- a/src/containers/sound-tab.jsx
+++ b/src/containers/sound-tab.jsx
@@ -23,6 +23,20 @@ class SoundTab extends React.Component {
         this.state = {selectedSoundIndex: 0};
     }
 
+    componentWillReceiveProps (nextProps) {
+        const {
+            editingTarget,
+            sprites,
+            stage
+        } = nextProps;
+
+        const target = editingTarget && sprites[editingTarget] ? sprites[editingTarget] : stage;
+
+        if (target && target.sounds && this.state.selectedSoundIndex > target.sounds.length - 1) {
+            this.setState({selectedSoundIndex: target.sounds.length - 1});
+        }
+    }
+
     handleSelectSound (soundIndex) {
         const sound = this.props.vm.editingTarget.sprite.sounds[soundIndex];
         this.props.vm.editingTarget.audioPlayer.playSound(sound.md5);
@@ -30,17 +44,7 @@ class SoundTab extends React.Component {
     }
 
     handleDeleteSound (soundIndex) {
-        // @todo the VM should handle all of this logic
-        const {editingTarget} = this.props.vm;
-        editingTarget.sprite.sounds = editingTarget.sprite.sounds
-            .slice(0, soundIndex)
-            .concat(editingTarget.sprite.sounds.slice(soundIndex + 1));
-        this.props.vm.emitTargetsUpdate();
-        this.props.vm.runtime.requestRedraw();
-
-        this.setState({
-            selectedSoundIndex: this.state.selectedSoundIndex % editingTarget.sprite.sounds.length
-        });
+        this.props.vm.deleteSound(soundIndex);
     }
 
     render () {
diff --git a/src/containers/sprite-library.jsx b/src/containers/sprite-library.jsx
index c08748eb2337728cd862fe051b78b0da03dfe22e..0a1bcaa3ebcad309733aa10c5f98faf25c68f56a 100644
--- a/src/containers/sprite-library.jsx
+++ b/src/containers/sprite-library.jsx
@@ -5,7 +5,7 @@ const VM = require('scratch-vm');
 
 const spriteLibraryContent = require('../lib/libraries/sprites.json');
 
-const LibaryComponent = require('../components/library/library.jsx');
+const LibraryComponent = require('../components/library/library.jsx');
 
 class SpriteLibrary extends React.Component {
     constructor (props) {
@@ -19,7 +19,7 @@ class SpriteLibrary extends React.Component {
     }
     render () {
         return (
-            <LibaryComponent
+            <LibraryComponent
                 data={spriteLibraryContent}
                 title="Sprite Library"
                 visible={this.props.visible}
diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx
index a9182996e171321066dc8cf52233816b32b6aa4f..d6c738cb3002688b3d812367f30b8cd8e27a1406 100644
--- a/src/containers/sprite-selector-item.jsx
+++ b/src/containers/sprite-selector-item.jsx
@@ -2,6 +2,8 @@ const bindAll = require('lodash.bindall');
 const PropTypes = require('prop-types');
 const React = require('react');
 
+const {connect} = require('react-redux');
+
 const SpriteSelectorItemComponent = require('../components/sprite-selector-item/sprite-selector-item.jsx');
 
 class SpriteSelectorItem extends React.Component {
@@ -24,9 +26,12 @@ class SpriteSelectorItem extends React.Component {
     }
     render () {
         const {
-            id, // eslint-disable-line no-unused-vars
-            onClick, // eslint-disable-line no-unused-vars
-            onDeleteButtonClick, // eslint-disable-line no-unused-vars
+            /* eslint-disable no-unused-vars */
+            assetId,
+            id,
+            onClick,
+            onDeleteButtonClick,
+            /* eslint-enable no-unused-vars */
             ...props
         } = this.props;
         return (
@@ -40,6 +45,7 @@ class SpriteSelectorItem extends React.Component {
 }
 
 SpriteSelectorItem.propTypes = {
+    assetId: PropTypes.string,
     costumeURL: PropTypes.string,
     id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
     name: PropTypes.string,
@@ -48,4 +54,10 @@ SpriteSelectorItem.propTypes = {
     selected: PropTypes.bool
 };
 
-module.exports = SpriteSelectorItem;
+const mapStateToProps = (state, {assetId, costumeURL}) => ({
+    costumeURL: costumeURL || (assetId && state.vm.runtime.storage.get(assetId).encodeDataURI())
+});
+
+module.exports = connect(
+    mapStateToProps
+)(SpriteSelectorItem);
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index d37a4437c51d2c6c8b6b631005fc5a938e3f7256..9b4b83d0d7a3efcdd98697915af2da8c51ba6a62 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -2,6 +2,8 @@ const bindAll = require('lodash.bindall');
 const PropTypes = require('prop-types');
 const React = require('react');
 
+const {connect} = require('react-redux');
+
 const StageSelectorComponent = require('../components/stage-selector/stage-selector.jsx');
 
 class StageSelector extends React.Component {
@@ -18,6 +20,7 @@ class StageSelector extends React.Component {
     render () {
         const {
             /* eslint-disable no-unused-vars */
+            assetId,
             id,
             onSelect,
             /* eslint-enable no-unused-vars */
@@ -36,4 +39,12 @@ StageSelector.propTypes = {
     id: PropTypes.string,
     onSelect: PropTypes.func
 };
-module.exports = StageSelector;
+
+const mapStateToProps = (state, {assetId}) => ({
+    url: assetId && state.vm.runtime.storage.get(assetId).encodeDataURI()
+});
+
+module.exports = connect(
+    mapStateToProps,
+    () => ({}) // omit dispatch prop
+)(StageSelector);
diff --git a/src/lib/blocks.js b/src/lib/blocks.js
index cfd64d98f555686606109b458eefdaefa4ff692e..c0cf9e3ef107c1bbcbd22986d04ad9c6adfcd13d 100644
--- a/src/lib/blocks.js
+++ b/src/lib/blocks.js
@@ -9,7 +9,9 @@ module.exports = function (vm) {
                 {
                     type: 'field_dropdown',
                     name: name,
-                    options: start.concat(menuOptionsFn())
+                    options: function () {
+                        return start.concat(menuOptionsFn());
+                    }
                 }
             ],
             inputsInline: true,
diff --git a/src/lib/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx
index 8c80ae5d9694711a50a3974aa2704883d57de76e..e49de705e5aa5174d91d37829a6b483ba5ea7351 100644
--- a/src/lib/vm-listener-hoc.jsx
+++ b/src/lib/vm-listener-hoc.jsx
@@ -3,11 +3,10 @@ const PropTypes = require('prop-types');
 const React = require('react');
 const VM = require('scratch-vm');
 
-const Storage = require('./storage');
-
 const {connect} = require('react-redux');
 
 const targets = require('../reducers/targets');
+const monitors = require('../reducers/monitors');
 
 /*
  * Higher Order Component to manage events emitted by the VM
@@ -29,7 +28,8 @@ const vmListenerHOC = function (WrappedComponent) {
             // If the wrapped component uses the vm in componentDidMount, then
             // we need to start listening before mounting the wrapped component.
             this.props.vm.on('targetsUpdate', this.props.onTargetsUpdate);
-            this.props.vm.on('SPRITE_INFO_REPORT', this.props.onSpriteInfoReport);
+            this.props.vm.on('MONITORS_UPDATE', this.props.onMonitorsUpdate);
+
         }
         componentDidMount () {
             if (this.props.attachKeyboardEvents) {
@@ -76,7 +76,7 @@ const vmListenerHOC = function (WrappedComponent) {
                 attachKeyboardEvents,
                 onKeyDown,
                 onKeyUp,
-                onSpriteInfoReport,
+                onMonitorsUpdate,
                 onTargetsUpdate,
                 /* eslint-enable no-unused-vars */
                 ...props
@@ -88,24 +88,23 @@ const vmListenerHOC = function (WrappedComponent) {
         attachKeyboardEvents: PropTypes.bool,
         onKeyDown: PropTypes.func,
         onKeyUp: PropTypes.func,
-        onSpriteInfoReport: PropTypes.func,
+        onMonitorsUpdate: PropTypes.func,
         onTargetsUpdate: PropTypes.func,
         vm: PropTypes.instanceOf(VM).isRequired
     };
-    const defaultVM = new VM('vm-listener-hoc');
-    defaultVM.attachStorage(new Storage());
     VMListener.defaultProps = {
-        attachKeyboardEvents: true,
-        vm: defaultVM
+        attachKeyboardEvents: true
     };
-    const mapStateToProps = () => ({});
+    const mapStateToProps = state => ({
+        vm: state.vm
+    });
     const mapDispatchToProps = dispatch => ({
         onTargetsUpdate: data => {
             dispatch(targets.updateEditingTarget(data.editingTarget));
             dispatch(targets.updateTargets(data.targetList));
         },
-        onSpriteInfoReport: spriteInfo => {
-            dispatch(targets.updateTarget(spriteInfo));
+        onMonitorsUpdate: monitorList => {
+            dispatch(monitors.updateMonitors(monitorList));
         }
     });
     return connect(
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index bde1a2f3f1c6a02d9a8e1a7131754ef91ee3f33d..9b1cf60671fd255e31ba620dbdff2dd1d6f280ef 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -2,6 +2,7 @@ const {combineReducers} = require('redux');
 
 module.exports = combineReducers({
     modals: require('./modals'),
+    monitors: require('./monitors'),
     targets: require('./targets'),
-    monitors: require('./monitors')
+    vm: require('./vm')
 });
diff --git a/src/reducers/targets.js b/src/reducers/targets.js
index c2f6219acea9de791eedbbe496bc0926448fe48f..0ed67cf2de94ceadf32e143037321458c5347a68 100644
--- a/src/reducers/targets.js
+++ b/src/reducers/targets.js
@@ -1,8 +1,5 @@
-const defaultsDeep = require('lodash.defaultsdeep');
-
 const UPDATE_EDITING_TARGET = 'scratch-gui/targets/UPDATE_EDITING_TARGET';
 const UPDATE_TARGET_LIST = 'scratch-gui/targets/UPDATE_TARGET_LIST';
-const UPDATE_TARGET = 'scratch/targets/UPDATE_TARGET';
 
 const initialState = {
     sprites: {},
@@ -12,39 +9,19 @@ const initialState = {
 const reducer = function (state, action) {
     if (typeof state === 'undefined') state = initialState;
     switch (action.type) {
-    case UPDATE_TARGET:
-        if (action.target.id === state.stage.id) {
-            return Object.assign({}, state, {
-                stage: Object.assign({}, state.stage, action.target)
-            });
-        }
-        return Object.assign({}, state, {
-            sprites: defaultsDeep(
-                {[action.target.id]: action.target},
-                state.sprites
-            )
-        });
     case UPDATE_TARGET_LIST:
         return Object.assign({}, state, {
             sprites: action.targets
                 .filter(target => !target.isStage)
                 .reduce(
-                    (targets, target, listId) => defaultsDeep(
-                        {[target.id]: {order: listId, ...target}},
-                        {[target.id]: state.sprites[target.id]},
-                        targets
+                    (targets, target, listId) => Object.assign(
+                        targets,
+                        {[target.id]: {order: listId, ...target}}
                     ),
                     {}
                 ),
             stage: action.targets
-                .filter(target => target.isStage)
-                .reduce(
-                    (stage, target) => {
-                        if (target.id !== stage.id) return target;
-                        return defaultsDeep(target, stage);
-                    },
-                    state.stage
-                )
+                .filter(target => target.isStage)[0] || {}
         });
     case UPDATE_EDITING_TARGET:
         return Object.assign({}, state, {editingTarget: action.target});
@@ -52,15 +29,6 @@ const reducer = function (state, action) {
         return state;
     }
 };
-reducer.updateTarget = function (target) {
-    return {
-        type: UPDATE_TARGET,
-        target: target,
-        meta: {
-            throttle: 30
-        }
-    };
-};
 reducer.updateTargets = function (targetList) {
     return {
         type: UPDATE_TARGET_LIST,
diff --git a/src/reducers/vm.js b/src/reducers/vm.js
new file mode 100644
index 0000000000000000000000000000000000000000..1fd0eb4a2f199b7329783d825445adcf550b6176
--- /dev/null
+++ b/src/reducers/vm.js
@@ -0,0 +1,24 @@
+const VM = require('scratch-vm');
+const Storage = require('../lib/storage');
+
+const SET_VM = 'scratch-gui/vm/SET_VM';
+const defaultVM = new VM();
+defaultVM.attachStorage(new Storage());
+const initialState = defaultVM;
+
+const reducer = function (state, action) {
+    if (typeof state === 'undefined') state = initialState;
+    switch (action.type) {
+    case SET_VM:
+        return action.vm;
+    default:
+        return state;
+    }
+};
+reducer.setVM = function (vm) {
+    return {
+        type: SET_VM,
+        vm: vm
+    };
+};
+module.exports = reducer;