diff --git a/src/engine/target.js b/src/engine/target.js
index 166e44369..114dd1276 100644
--- a/src/engine/target.js
+++ b/src/engine/target.js
@@ -20,9 +20,10 @@ class Target extends EventEmitter {
     /**
      * @param {Runtime} runtime Reference to the runtime.
      * @param {?Blocks} blocks Blocks instance for the blocks owned by this target.
+     * @param {?Object.<string, *>} comments Array of comments owned by this target.
      * @constructor
      */
-    constructor (runtime, blocks) {
+    constructor (runtime, blocks, comments) {
         super();
 
         if (!blocks) {
@@ -55,7 +56,7 @@ class Target extends EventEmitter {
          * Key is the comment id.
          * @type {Object.<string,*>}
          */
-        this.comments = {};
+        this.comments = comments || {};
         /**
          * Dictionary of custom state for this target.
          * This can be used to store target-specific custom state for blocks which need it.
diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js
index e4a12e244..d3230cce1 100644
--- a/src/sprites/rendered-target.js
+++ b/src/sprites/rendered-target.js
@@ -15,7 +15,7 @@ class RenderedTarget extends Target {
      * @constructor
      */
     constructor (sprite, runtime) {
-        super(runtime, sprite.blocks);
+        super(runtime, sprite.blocks, sprite.comments);
 
         /**
          * Reference to the sprite that this is a render of.
diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js
index a38fa129c..243882e63 100644
--- a/src/sprites/sprite.js
+++ b/src/sprites/sprite.js
@@ -54,6 +54,12 @@ class Sprite {
         if (this.runtime && this.runtime.audioEngine) {
             this.soundBank = this.runtime.audioEngine.createBank();
         }
+        /**
+         * Dictionary of comments for this target.
+         * Key is the comment id.
+         * @type {Object.<string.*>}
+         */
+        this.comments = {};
     }
 
     /**
@@ -145,7 +151,12 @@ class Sprite {
             newSprite.blocks.createBlock(block);
         });
 
-
+        // Logic to handle new sprite retaining the comments from the current sprite
+        Object.keys(this.comments).forEach(commentId => {
+            const newComment = this.comments[commentId];
+            newSprite.comments[newComment.id] = newComment;
+        });
+         
         const allNames = this.runtime.targets.map(t => t.sprite.name);
         newSprite.name = StringUtil.unusedName(this.name, allNames);
 
diff --git a/test/unit/sprites_rendered-target.js b/test/unit/sprites_rendered-target.js
index a9823424a..c6400d362 100644
--- a/test/unit/sprites_rendered-target.js
+++ b/test/unit/sprites_rendered-target.js
@@ -45,6 +45,39 @@ test('blocks get new id on duplicate', t => {
     });
 });
 
+test('comments are duplicated when duplicating target', t => {
+    const r = new Runtime();
+    const s = new Sprite(null, r);
+    const rt = new RenderedTarget(s, r);
+    rt.createComment('testCommentId', null, 'testcomment', 0, 0, 100, 100, false);
+    return rt.duplicate().then(duplicate => {
+        // ensure duplicated comment exists
+        t.equal(Object.keys(duplicate.comments).length, 1);
+
+        // ensure comment was duplicated correctly
+        const dupComment = duplicate.comments.testCommentId;
+        t.equal(dupComment.id, 'testCommentId');
+        t.equal(dupComment.text, 'testcomment');
+        t.equal(dupComment.x, 0);
+        t.equal(dupComment.y, 0);
+        t.equal(dupComment.width, 100);
+        t.equal(dupComment.height, 100);
+        t.equal(dupComment.minimized, false);
+
+        t.end();
+    });
+});
+
+test('no comments are duplicated when duplicating target with no comments', t => {
+    const r = new Runtime();
+    const s = new Sprite(null, r);
+    const rt = new RenderedTarget(s, r);
+    return rt.duplicate().then(duplicate => {
+        t.equal(Object.keys(duplicate.comments).length, 0);
+        t.end();
+    });
+});
+
 test('direction', t => {
     const r = new Runtime();
     const s = new Sprite(null, r);