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/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/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/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx
index 8c80ae5d9694711a50a3974aa2704883d57de76e..58ea1ca716b83195733d946c452c5eece51bfc8c 100644
--- a/src/lib/vm-listener-hoc.jsx
+++ b/src/lib/vm-listener-hoc.jsx
@@ -3,8 +3,6 @@ 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');
@@ -92,13 +90,12 @@ const vmListenerHOC = function (WrappedComponent) {
         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));
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/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;