diff --git a/package.json b/package.json
index c43fb30c03283d3ec1519601f6d88823dae46c46..de36d129ef07eb4f938a077d1efb7ad37290ba5d 100644
--- a/package.json
+++ b/package.json
@@ -100,7 +100,7 @@
     "scratch-l10n": "3.0.20180824134256",
     "scratch-paint": "0.2.0-prerelease.20180823231354",
     "scratch-render": "0.1.0-prerelease.20180824141819",
-    "scratch-storage": "1.0.0",
+    "scratch-storage": "1.0.2",
     "scratch-svg-renderer": "0.2.0-prerelease.20180817005452",
     "scratch-vm": "0.2.0-prerelease.20180824135031",
     "selenium-webdriver": "3.6.0",
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
index 14b082cdfe7746734f72a2bb5cc2cefa6a0096d2..4b05b2d2747dc3a876f3938d2a8f70df4ed4f8fa 100644
--- a/src/.eslintrc.js
+++ b/src/.eslintrc.js
@@ -12,7 +12,10 @@ module.exports = {
         'import/no-commonjs': 'error',
         'import/no-amd': 'error',
         'import/no-nodejs-modules': 'error',
-        'react/jsx-no-literals': 'error'
+        'react/jsx-no-literals': 'error',
+        'no-confusing-arrow': ['error', {
+            'allowParens': true
+        }]
     },
     settings: {
         react: {
diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css
index de2854c5006508276a78718b87d337301e162094..662c0e1ae6fe2e403367d2d68194b81b83a0f409 100644
--- a/src/components/menu-bar/menu-bar.css
+++ b/src/components/menu-bar/menu-bar.css
@@ -189,3 +189,16 @@
 .disabled {
     opacity: 0.5;
 }
+
+.save-in-progress {
+  animation: hue-rotate 3s linear infinite;
+}
+
+@keyframes hue-rotate {
+  from {
+    filter: hue-rotate();
+  }
+  to {
+    filter: hue-rotate(360deg);
+  }
+}
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index 5a9ca128b661de840e82c8492ee095fe739d40be..d88e67f555d3ac1cce2efc4aef87df9b81fd68e4 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -140,6 +140,7 @@ class MenuBar extends React.Component {
             'handleRestoreOption',
             'restoreOptionMessage'
         ]);
+        this.state = {projectSaveInProgress: false};
     }
     handleLanguageMouseUp (e) {
         if (!this.props.languageMenuOpen) {
@@ -152,6 +153,18 @@ class MenuBar extends React.Component {
             this.props.onRequestCloseEdit();
         };
     }
+    handleUpdateProject (updateFun) {
+        return () => {
+            this.props.onRequestCloseFile();
+            this.setState({projectSaveInProgress: true},
+                () => {
+                    updateFun().then(() => {
+                        this.setState({projectSaveInProgress: false});
+                    });
+                }
+            );
+        };
+    }
     restoreOptionMessage (deletedItem) {
         switch (deletedItem) {
         case 'Sprite':
@@ -182,8 +195,19 @@ class MenuBar extends React.Component {
         }
     }
     render () {
+        const saveNowMessage = (
+            <FormattedMessage
+                defaultMessage="Save now"
+                description="Menu bar item for saving now"
+                id="gui.menuBar.saveNow"
+            />
+        );
         return (
-            <Box className={styles.menuBar}>
+            <Box
+                className={classNames(styles.menuBar, {
+                    [styles.saveInProgress]: this.state.projectSaveInProgress
+                })}
+            >
                 <div className={styles.mainMenu}>
                     <div className={styles.fileGroup}>
                         <div className={classNames(styles.menuBarItem)}>
@@ -246,18 +270,20 @@ class MenuBar extends React.Component {
                                     </MenuItem>
                                 </MenuItemTooltip>
                                 <MenuSection>
-                                    <MenuItemTooltip
-                                        id="save"
-                                        isRtl={this.props.isRtl}
-                                    >
-                                        <MenuItem>
-                                            <FormattedMessage
-                                                defaultMessage="Save now"
-                                                description="Menu bar item for saving now"
-                                                id="gui.menuBar.saveNow"
-                                            />
-                                        </MenuItem>
-                                    </MenuItemTooltip>
+                                    <ProjectSaver>{(saveProject, updateProject) => (
+                                        this.props.canUpdateProject ? (
+                                            <MenuItem onClick={this.handleUpdateProject(updateProject)}>
+                                                {saveNowMessage}
+                                            </MenuItem>
+                                        ) : (
+                                            <MenuItemTooltip
+                                                id="save"
+                                                isRtl={this.props.isRtl}
+                                            >
+                                                <MenuItem>{saveNowMessage}</MenuItem>
+                                            </MenuItemTooltip>
+                                        )
+                                    )}</ProjectSaver>
                                     <MenuItemTooltip
                                         id="copy"
                                         isRtl={this.props.isRtl}
@@ -284,10 +310,9 @@ class MenuBar extends React.Component {
                                             {renderFileInput()}
                                         </MenuItem>
                                     )}</ProjectLoader>
-                                    <ProjectSaver>{(saveProject, saveProps) => (
+                                    <ProjectSaver>{saveProject => (
                                         <MenuItem
                                             onClick={saveProject}
-                                            {...saveProps}
                                         >
                                             <FormattedMessage
                                                 defaultMessage="Save to your computer"
@@ -475,6 +500,7 @@ class MenuBar extends React.Component {
 }
 
 MenuBar.propTypes = {
+    canUpdateProject: PropTypes.bool,
     editMenuOpen: PropTypes.bool,
     enableCommunity: PropTypes.bool,
     fileMenuOpen: PropTypes.bool,
@@ -492,6 +518,7 @@ MenuBar.propTypes = {
 };
 
 const mapStateToProps = state => ({
+    canUpdateProject: typeof (state.session && state.session.session && state.session.session.user) !== 'undefined',
     fileMenuOpen: fileMenuOpen(state),
     editMenuOpen: editMenuOpen(state),
     isRtl: state.locales.isRtl,
diff --git a/src/containers/backpack.jsx b/src/containers/backpack.jsx
index e90fe1dff10b4d767596e7509b7ac1cb4d5106cb..3f9b2dd5966bd66d0f991e22f28c0be874ff362d 100644
--- a/src/containers/backpack.jsx
+++ b/src/containers/backpack.jsx
@@ -134,7 +134,7 @@ Backpack.propTypes = {
 
 const getTokenAndUsername = state => {
     // Look for the session state provided by scratch-www
-    if (state.session && state.session.session) {
+    if (state.session && state.session.session && state.session.session.user) {
         return {
             token: state.session.session.user.token,
             username: state.session.session.user.username
diff --git a/src/containers/gui.jsx b/src/containers/gui.jsx
index 33d8fe58b247c28a3760529ecdbaefcd31190599..6e5d96070b77135abfeb28b64101928a4c00b4c6 100644
--- a/src/containers/gui.jsx
+++ b/src/containers/gui.jsx
@@ -72,12 +72,10 @@ class GUI extends React.Component {
                 `Failed to load project from server [id=${window.location.hash}]: ${this.state.errorMessage}`);
         }
         const {
-            assetHost, // eslint-disable-line no-unused-vars
             children,
             fetchingProject,
             loadingStateVisible,
             projectData, // eslint-disable-line no-unused-vars
-            projectHost, // eslint-disable-line no-unused-vars
             vm,
             ...componentProps
         } = this.props;
@@ -94,7 +92,6 @@ class GUI extends React.Component {
 }
 
 GUI.propTypes = {
-    assetHost: PropTypes.string,
     children: PropTypes.node,
     fetchingProject: PropTypes.bool,
     importInfoVisible: PropTypes.bool,
@@ -102,7 +99,6 @@ GUI.propTypes = {
     onSeeCommunity: PropTypes.func,
     previewInfoVisible: PropTypes.bool,
     projectData: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
-    projectHost: PropTypes.string,
     vm: PropTypes.instanceOf(VM)
 };
 
diff --git a/src/containers/project-saver.jsx b/src/containers/project-saver.jsx
index c594421eca357181919dd021310d9b1703118d12..13be33da808b1fa2cf9e10c6d2db2644112ef2e0 100644
--- a/src/containers/project-saver.jsx
+++ b/src/containers/project-saver.jsx
@@ -2,6 +2,7 @@ import bindAll from 'lodash.bindall';
 import PropTypes from 'prop-types';
 import React from 'react';
 import {connect} from 'react-redux';
+import storage from '../lib/storage';
 
 /**
  * Project saver component passes a saveProject function to its child.
@@ -21,14 +22,17 @@ class ProjectSaver extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
-            'saveProject'
+            'createProject',
+            'updateProject',
+            'saveProject',
+            'doStoreProject'
         ]);
     }
     saveProject () {
         const saveLink = document.createElement('a');
         document.body.appendChild(saveLink);
 
-        this.props.vm.saveProjectSb3().then(content => {
+        this.props.saveProjectSb3().then(content => {
             // TODO user-friendly project name
             // File name: project-DATE-TIME
             const date = new Date();
@@ -49,27 +53,48 @@ class ProjectSaver extends React.Component {
             document.body.removeChild(saveLink);
         });
     }
+    doStoreProject (id) {
+        return this.props.saveProjectSb3()
+            .then(content => {
+                const assetType = storage.AssetType.Project;
+                const dataFormat = storage.DataFormat.SB3;
+                const body = new FormData();
+                body.append('sb3_file', content, 'sb3_file');
+                return storage.store(
+                    assetType,
+                    dataFormat,
+                    body,
+                    id
+                );
+            });
+    }
+    createProject () {
+        return this.doStoreProject();
+    }
+    updateProject () {
+        return this.doStoreProject(this.props.projectId);
+    }
     render () {
         const {
-            /* eslint-disable no-unused-vars */
-            children,
-            vm,
-            /* eslint-enable no-unused-vars */
-            ...props
+            children
         } = this.props;
-        return this.props.children(this.saveProject, props);
+        return children(
+            this.saveProject,
+            this.updateProject,
+            this.createProject
+        );
     }
 }
 
 ProjectSaver.propTypes = {
     children: PropTypes.func,
-    vm: PropTypes.shape({
-        saveProjectSb3: PropTypes.func
-    })
+    projectId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
+    saveProjectSb3: PropTypes.func
 };
 
 const mapStateToProps = state => ({
-    vm: state.scratchGui.vm
+    saveProjectSb3: state.scratchGui.vm.saveProjectSb3.bind(state.scratchGui.vm),
+    projectId: state.scratchGui.projectId
 });
 
 export default connect(
diff --git a/src/lib/project-loader-hoc.jsx b/src/lib/project-loader-hoc.jsx
index 22a1aa5d1ce4c9666b6b87acde4084285053b62c..68642c33600c2bbc6b0948c5d4602f785f044832 100644
--- a/src/lib/project-loader-hoc.jsx
+++ b/src/lib/project-loader-hoc.jsx
@@ -1,5 +1,8 @@
 import React from 'react';
 import PropTypes from 'prop-types';
+import {connect} from 'react-redux';
+
+import {setProjectId} from '../reducers/project-id';
 
 import analytics from './analytics';
 import log from './log';
@@ -21,12 +24,19 @@ const ProjectLoaderHOC = function (WrappedComponent) {
             };
             storage.setProjectHost(props.projectHost);
             storage.setAssetHost(props.assetHost);
-
-        }
-        componentDidMount () {
-            if (this.props.projectId || this.props.projectId === 0) {
-                this.updateProject(this.props.projectId);
+            if (props.projectId !== props.reduxProjectId) {
+                props.setProjectId(props.projectId);
+            }
+            if (
+                props.projectId !== '' &&
+                props.projectId !== null &&
+                typeof props.projectId !== 'undefined'
+            ) {
+                this.updateProject(props.projectId);
+            } else {
+                this.updateProject(props.reduxProjectId);
             }
+
         }
         componentWillUpdate (nextProps) {
             if (this.props.projectHost !== nextProps.projectHost) {
@@ -36,6 +46,7 @@ const ProjectLoaderHOC = function (WrappedComponent) {
                 storage.setAssetHost(nextProps.assetHost);
             }
             if (this.props.projectId !== nextProps.projectId) {
+                this.props.setProjectId(nextProps.projectId);
                 this.setState({fetchingProject: true}, () => {
                     this.updateProject(nextProps.projectId);
                 });
@@ -62,7 +73,13 @@ const ProjectLoaderHOC = function (WrappedComponent) {
         }
         render () {
             const {
-                projectId, // eslint-disable-line no-unused-vars
+                /* eslint-disable no-unused-vars */
+                assetHost,
+                projectHost,
+                projectId,
+                reduxProjectId,
+                setProjectId,
+                /* eslint-enable no-unused-vars */
                 ...componentProps
             } = this.props;
             if (!this.state.projectData) return null;
@@ -78,15 +95,23 @@ const ProjectLoaderHOC = function (WrappedComponent) {
     ProjectLoaderComponent.propTypes = {
         assetHost: PropTypes.string,
         projectHost: PropTypes.string,
-        projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
+        projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+        setProjectId: PropTypes.func
     };
     ProjectLoaderComponent.defaultProps = {
         assetHost: 'https://assets.scratch.mit.edu',
-        projectHost: 'https://projects.scratch.mit.edu',
-        projectId: 0
+        projectHost: 'https://projects.scratch.mit.edu'
     };
 
-    return ProjectLoaderComponent;
+    const mapStateToProps = state => ({
+        reduxProjectId: state.scratchGui.projectId
+    });
+
+    const mapDispatchToProps = dispatch => ({
+        setProjectId: id => dispatch(setProjectId(id))
+    });
+
+    return connect(mapStateToProps, mapDispatchToProps)(ProjectLoaderComponent);
 };
 
 export {
diff --git a/src/lib/storage.js b/src/lib/storage.js
index 9c49d81703f96aa67e6509013d91df0f0231e911..71905ed9d3c74d1f50dbe5054c0827ec28aebe0f 100644
--- a/src/lib/storage.js
+++ b/src/lib/storage.js
@@ -15,15 +15,17 @@ class Storage extends ScratchStorage {
             asset.data,
             asset.id
         ));
-        this.addWebSource(
+        this.addWebStore(
             [this.AssetType.Project],
-            this.getProjectURL.bind(this)
+            this.getProjectGetConfig.bind(this),
+            this.getProjectCreateConfig.bind(this),
+            this.getProjectUpdateConfig.bind(this)
         );
-        this.addWebSource(
+        this.addWebStore(
             [this.AssetType.ImageVector, this.AssetType.ImageBitmap, this.AssetType.Sound],
-            this.getAssetURL.bind(this)
+            this.getAssetGetConfig.bind(this)
         );
-        this.addWebSource(
+        this.addWebStore(
             [this.AssetType.Sound],
             asset => `static/extension-assets/scratch3_music/${asset.assetId}.${asset.dataFormat}`
         );
@@ -31,13 +33,25 @@ class Storage extends ScratchStorage {
     setProjectHost (projectHost) {
         this.projectHost = projectHost;
     }
-    getProjectURL (projectAsset) {
-        return `${this.projectHost}/internalapi/project/${projectAsset.assetId}/get/`;
+    getProjectGetConfig (projectAsset) {
+        return `${this.projectHost}/${projectAsset.assetId}`;
+    }
+    getProjectCreateConfig () {
+        return {
+            url: `${this.projectHost}/`,
+            withCredentials: true
+        };
+    }
+    getProjectUpdateConfig (projectAsset) {
+        return {
+            url: `${this.projectHost}/${projectAsset.assetId}`,
+            withCredentials: true
+        };
     }
     setAssetHost (assetHost) {
         this.assetHost = assetHost;
     }
-    getAssetURL (asset) {
+    getAssetGetConfig (asset) {
         return `${this.assetHost}/internalapi/asset/${asset.assetId}.${asset.dataFormat}/get/`;
     }
 }
diff --git a/src/reducers/gui.js b/src/reducers/gui.js
index 04b2644686165b0038c4824c0092701d36a0f697..9340af56e1177485aa02c361c404070b6b4c6bf3 100644
--- a/src/reducers/gui.js
+++ b/src/reducers/gui.js
@@ -11,6 +11,7 @@ import modalReducer, {modalsInitialState} from './modals';
 import modeReducer, {modeInitialState} from './mode';
 import monitorReducer, {monitorsInitialState} from './monitors';
 import monitorLayoutReducer, {monitorLayoutInitialState} from './monitor-layout';
+import projectIdReducer, {projectIdInitialState} from './project-id';
 import restoreDeletionReducer, {restoreDeletionInitialState} from './restore-deletion';
 import stageSizeReducer, {stageSizeInitialState} from './stage-size';
 import targetReducer, {targetsInitialState} from './targets';
@@ -35,6 +36,7 @@ const guiInitialState = {
     modals: modalsInitialState,
     monitors: monitorsInitialState,
     monitorLayout: monitorLayoutInitialState,
+    projectId: projectIdInitialState,
     restoreDeletion: restoreDeletionInitialState,
     targets: targetsInitialState,
     toolbox: toolboxInitialState,
@@ -77,6 +79,7 @@ const guiReducer = combineReducers({
     modals: modalReducer,
     monitors: monitorReducer,
     monitorLayout: monitorLayoutReducer,
+    projectId: projectIdReducer,
     restoreDeletion: restoreDeletionReducer,
     targets: targetReducer,
     toolbox: toolboxReducer,
diff --git a/src/reducers/project-id.js b/src/reducers/project-id.js
new file mode 100644
index 0000000000000000000000000000000000000000..da98a921e7701a9a2e7a114781e5f1c6e570bfa4
--- /dev/null
+++ b/src/reducers/project-id.js
@@ -0,0 +1,27 @@
+const SET_PROJECT_ID = 'scratch-gui/project-id/SET_PROJECT_ID';
+
+const initialState = 0;
+
+const reducer = function (state, action) {
+    if (typeof state === 'undefined') state = initialState;
+
+    switch (action.type) {
+    case SET_PROJECT_ID:
+        return action.id;
+    default:
+        return state;
+    }
+};
+
+const setProjectId = function (id) {
+    return {
+        type: SET_PROJECT_ID,
+        id: id
+    };
+};
+
+export {
+    reducer as default,
+    initialState as projectIdInitialState,
+    setProjectId
+};