diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx
index 4c63a8cceb7bec2c86632886b6e195ff1c4535ae..d4563a02c6fbdf50075f0787253cf5495e9d7d47 100644
--- a/src/containers/costume-tab.jsx
+++ b/src/containers/costume-tab.jsx
@@ -11,6 +11,8 @@ import {connect} from 'react-redux';
 import {handleFileUpload, costumeUpload} from '../lib/file-uploader.js';
 import errorBoundaryHOC from '../lib/error-boundary-hoc.jsx';
 import DragConstants from '../lib/drag-constants';
+import {emptyCostume} from '../lib/empty-assets';
+import sharedMessages from '../lib/shared-messages';
 
 import {
     closeCameraCapture,
@@ -37,7 +39,7 @@ import searchIcon from '../components/action-menu/icon--search.svg';
 import costumeLibraryContent from '../lib/libraries/costumes.json';
 import backdropLibraryContent from '../lib/libraries/backdrops.json';
 
-const messages = defineMessages({
+let messages = defineMessages({
     addLibraryBackdropMsg: {
         defaultMessage: 'Choose a Backdrop',
         description: 'Button to add a backdrop in the editor tab',
@@ -75,6 +77,8 @@ const messages = defineMessages({
     }
 });
 
+messages = {...messages, ...sharedMessages};
+
 class CostumeTab extends React.Component {
     constructor (props) {
         super(props);
@@ -150,20 +154,10 @@ class CostumeTab extends React.Component {
         this.props.vm.addCostume(costume.md5, costume);
     }
     handleNewBlankCostume () {
-        const emptyItem = costumeLibraryContent.find(item => (
-            item.name === 'Empty'
-        ));
-        const name = this.props.vm.editingTarget.isStage ? `backdrop1` : `costume1`;
-        const vmCostume = {
-            name: name,
-            md5: emptyItem.md5,
-            rotationCenterX: emptyItem.info[0],
-            rotationCenterY: emptyItem.info[1],
-            bitmapResolution: emptyItem.info.length > 2 ? emptyItem.info[2] : 1,
-            skinId: null
-        };
-
-        this.handleNewCostume(vmCostume);
+        const name = this.props.vm.editingTarget.isStage ?
+            this.props.intl.formatMessage(messages.backdrop) :
+            this.props.intl.formatMessage(messages.costume);
+        this.handleNewCostume(emptyCostume(name));
     }
     handleSurpriseCostume () {
         const item = costumeLibraryContent[Math.floor(Math.random() * costumeLibraryContent.length)];
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index e5a86fcc067417198d55724646f85f1ebecebfa9..7520ae6d4889b8103754c8f3951b09f40ca10318 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -2,6 +2,7 @@ import bindAll from 'lodash.bindall';
 import omit from 'lodash.omit';
 import PropTypes from 'prop-types';
 import React from 'react';
+import {intlShape, injectIntl} from 'react-intl';
 
 import {connect} from 'react-redux';
 import {openBackdropLibrary} from '../reducers/modals';
@@ -9,11 +10,12 @@ import {activateTab, COSTUMES_TAB_INDEX} from '../reducers/editor-tab';
 import {setHoveredSprite} from '../reducers/hovered-target';
 import DragConstants from '../lib/drag-constants';
 import DropAreaHOC from '../lib/drop-area-hoc.jsx';
+import {emptyCostume} from '../lib/empty-assets';
+import sharedMessages from '../lib/shared-messages';
 
 import StageSelectorComponent from '../components/stage-selector/stage-selector.jsx';
 
 import backdropLibraryContent from '../lib/libraries/backdrops.json';
-import costumeLibraryContent from '../lib/libraries/costumes.json';
 import {handleFileUpload, costumeUpload} from '../lib/file-uploader.js';
 
 const dragTypes = [
@@ -66,11 +68,7 @@ class StageSelector extends React.Component {
         this.addBackdropFromLibraryItem(item);
     }
     handleEmptyBackdrop () {
-        // @todo this is brittle, will need to be refactored for localized libraries
-        const emptyItem = costumeLibraryContent.find(item => item.name === 'Empty');
-        if (emptyItem) {
-            this.addBackdropFromLibraryItem(emptyItem);
-        }
+        this.handleNewBackdrop(emptyCostume(this.props.intl.formatMessage(sharedMessages.backdrop)));
     }
     handleBackdropUpload (e) {
         const storage = this.props.vm.runtime.storage;
@@ -108,7 +106,7 @@ class StageSelector extends React.Component {
     }
     render () {
         const componentProps = omit(this.props, [
-            'assetId', 'dispatchSetHoveredSprite', 'id', 'onActivateTab', 'onSelect']);
+            'assetId', 'dispatchSetHoveredSprite', 'id', 'intl', 'onActivateTab', 'onSelect']);
         return (
             <DroppableStage
                 fileInputRef={this.setFileInput}
@@ -128,6 +126,7 @@ class StageSelector extends React.Component {
 StageSelector.propTypes = {
     ...StageSelectorComponent.propTypes,
     id: PropTypes.string,
+    intl: intlShape.isRequired,
     onSelect: PropTypes.func
 };
 
@@ -152,7 +151,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-export default connect(
+export default injectIntl(connect(
     mapStateToProps,
     mapDispatchToProps
-)(StageSelector);
+)(StageSelector));
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index 4444c31432c50174ff1eba9a799fd7a8d710c9c7..5bccb7c333d68fb1d6c6ba33585e7efd0d5d9f8d 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -2,6 +2,7 @@ import bindAll from 'lodash.bindall';
 import React from 'react';
 
 import {connect} from 'react-redux';
+import {intlShape, injectIntl} from 'react-intl';
 
 import {
     openSpriteLibrary,
@@ -15,6 +16,8 @@ import DragConstants from '../lib/drag-constants';
 import TargetPaneComponent from '../components/target-pane/target-pane.jsx';
 import spriteLibraryContent from '../lib/libraries/sprites.json';
 import {handleFileUpload, spriteUpload} from '../lib/file-uploader.js';
+import sharedMessages from '../lib/shared-messages';
+import {emptySprite} from '../lib/empty-assets';
 
 class TargetPane extends React.Component {
     constructor (props) {
@@ -109,15 +112,17 @@ class TargetPane extends React.Component {
         this.props.vm.addSprite(JSON.stringify(item.json));
     }
     handlePaintSpriteClick () {
-        // @todo this is brittle, will need to be refactored for localized libraries
-        const emptyItem = spriteLibraryContent.find(item => item.name === 'Empty');
-        if (emptyItem) {
-            this.props.vm.addSprite(JSON.stringify(emptyItem.json)).then(() => {
-                setTimeout(() => { // Wait for targets update to propagate before tab switching
-                    this.props.onActivateTab(COSTUMES_TAB_INDEX);
-                });
+        const formatMessage = this.props.intl.formatMessage;
+        const emptyItem = emptySprite(
+            formatMessage(sharedMessages.sprite),
+            formatMessage(sharedMessages.sound),
+            formatMessage(sharedMessages.costume)
+        );
+        this.props.vm.addSprite(JSON.stringify(emptyItem)).then(() => {
+            setTimeout(() => { // Wait for targets update to propagate before tab switching
+                this.props.onActivateTab(COSTUMES_TAB_INDEX);
             });
-        }
+        });
     }
     handleNewSprite (spriteJSONString) {
         this.props.vm.addSprite(spriteJSONString);
@@ -215,6 +220,7 @@ const {
 } = TargetPaneComponent.propTypes;
 
 TargetPane.propTypes = {
+    intl: intlShape.isRequired,
     ...targetPaneProps
 };
 
@@ -253,7 +259,7 @@ const mapDispatchToProps = dispatch => ({
     }
 });
 
-export default connect(
+export default injectIntl(connect(
     mapStateToProps,
     mapDispatchToProps
-)(TargetPane);
+)(TargetPane));
diff --git a/src/lib/empty-assets.js b/src/lib/empty-assets.js
new file mode 100644
index 0000000000000000000000000000000000000000..65f1f678c5ad695eb51fdcdef323b90f8d0be7df
--- /dev/null
+++ b/src/lib/empty-assets.js
@@ -0,0 +1,64 @@
+/**
+ * @fileoverview
+ * Utility functions to return json corresponding to default empty assets.
+ */
+
+/**
+ * Generate a blank costume object for vm.addCostume with the provided name.
+ * @param {string} name the name to use for the costume, caller should localize
+ * @return {object} vm costume object
+ */
+const emptyCostume = name => ({
+    name: name,
+    md5: 'cd21514d0531fdffb22204e0ec5ed84a.svg',
+    rotationCenterX: 0,
+    rotationCenterY: 0,
+    bitmapResolution: 1,
+    skinId: null
+});
+
+/**
+ * Generate a new empty sprite. The caller should provide localized versions of the
+ * default names.
+ * @param {string} name the name to use for the sprite
+ * @param {string} soundName the name to use for the default sound
+ * @param {string} costumeName the name to use for the default costume
+ * @return {object} object expected by vm.addSprite
+ */
+const emptySprite = (name, soundName, costumeName) => ({
+    objName: name,
+    sounds: [
+        {
+            soundName: soundName,
+            soundID: -1,
+            md5: '83a9787d4cb6f3b7632b4ddfebf74367.wav',
+            sampleCount: 258,
+            rate: 11025,
+            format: ''
+        }
+    ],
+    costumes: [
+        {
+            costumeName: costumeName,
+            baseLayerID: -1,
+            baseLayerMD5: 'cd21514d0531fdffb22204e0ec5ed84a.svg',
+            bitmapResolution: 1,
+            rotationCenterX: 0,
+            rotationCenterY: 0
+        }
+    ],
+    currentCostumeIndex: 0,
+    scratchX: 36,
+    scratchY: 28,
+    scale: 1,
+    direction: 90,
+    rotationStyle: 'normal',
+    isDraggable: false,
+    visible: true,
+    spriteInfo: {}
+});
+
+export {
+    emptyCostume,
+    emptySprite
+};
diff --git a/src/lib/shared-messages.js b/src/lib/shared-messages.js
new file mode 100644
index 0000000000000000000000000000000000000000..85ebe1c4041bb940c676f5b0a194af6d6c43ff6b
--- /dev/null
+++ b/src/lib/shared-messages.js
@@ -0,0 +1,24 @@
+import {defineMessages} from 'react-intl';
+
+export default defineMessages({
+    backdrop: {
+        defaultMessage: 'backdrop1',
+        description: 'Default name for a new backdrop, scratch will automatically adjust the number if necessary',
+        id: 'gui.sharedMessages.backdrop'
+    },
+    costume: {
+        defaultMessage: 'costume1',
+        description: 'Default name for a new costume, scratch will automatically adjust the number if necessary',
+        id: 'gui.sharedMessages.costume'
+    },
+    sprite: {
+        defaultMessage: 'sprite1',
+        description: 'Default name for a new sprite, scratch will automatically adjust the number if necessary',
+        id: 'gui.sharedMessages.sprite'
+    },
+    sound: {
+        defaultMessage: 'pop',
+        description: 'Name of the pop sound, the default sound added to a sprite',
+        id: 'gui.sharedMessages.pop'
+    }
+});