diff --git a/playground/index.html b/playground/index.html
index 87cef30b3..3d10a22d0 100644
--- a/playground/index.html
+++ b/playground/index.html
@@ -12,8 +12,16 @@
         <h2>Scratch VM Playground</h2>
         <button id="greenflag">Green flag</button>
         <button id="stopall">Stop</button>
+        <p>
+            <a id="threadexplorer-link" href="#">VM Threads</a><br />
+            <a id="blockexplorer-link" href="#">VM Block Representation</a>
+        </p>
+        <div id="tab-threadexplorer">
+            Thread explorer
+            <pre id="threadexplorer"></pre>
+        </div>
         <div id="tab-blockexplorer">
-            <h3>VM Block Representation</h3>
+            Block explorer
             <pre id="blockexplorer"></pre>
         </div>
     </div>
diff --git a/playground/playground.css b/playground/playground.css
index b20b2bd91..451a7cad5 100644
--- a/playground/playground.css
+++ b/playground/playground.css
@@ -1,6 +1,9 @@
 body {
     background: rgb(36,36,36);
 }
+a {
+    color: rgb(217,217,217);
+}
 #blocks {
     position: absolute;
     left: 40%;
@@ -17,7 +20,7 @@ body {
     bottom: 0;
     width: 35%;
 }
-#blockexplorer {
+#blockexplorer, #threadexplorer {
     position: absolute;
     width: 100%;
     height: 75%;
@@ -28,3 +31,7 @@ body {
     font-family: monospace;
     font-size: 10pt;
 }
+
+#tab-blockexplorer {
+    display: none;
+}
diff --git a/playground/playground.js b/playground/playground.js
index b2bf0d0db..d47f097a7 100644
--- a/playground/playground.js
+++ b/playground/playground.js
@@ -29,13 +29,26 @@ window.onload = function() {
     // Block events.
     workspace.addChangeListener(vm.blockListener);
 
-    var explorer = document.getElementById('blockexplorer');
+    var blockexplorer = document.getElementById('blockexplorer');
     workspace.addChangeListener(function() {
         // On a change, update the block explorer.
-        explorer.innerHTML = JSON.stringify(vm.runtime.blocks, null, 2);
-        window.hljs.highlightBlock(explorer);
+        blockexplorer.innerHTML = JSON.stringify(vm.runtime.blocks, null, 2);
+        window.hljs.highlightBlock(blockexplorer);
     });
 
+    var threadexplorer = document.getElementById('threadexplorer');
+    var cachedThreadJSON = '';
+    var updateThreadExplorer = function () {
+        var newJSON = JSON.stringify(vm.runtime.threads, null, 2);
+        if (newJSON != cachedThreadJSON) {
+            cachedThreadJSON = newJSON;
+            threadexplorer.innerHTML = cachedThreadJSON;
+            window.hljs.highlightBlock(threadexplorer);
+        }
+        window.requestAnimationFrame(updateThreadExplorer);
+    };
+    updateThreadExplorer();
+
     // Feedback for stacks running.
     vm.runtime.on('STACK_GLOW_ON', function(blockId) {
         workspace.glowStack(blockId, true);
@@ -54,4 +67,19 @@ window.onload = function() {
     document.getElementById('stopall').addEventListener('click', function() {
         vm.runtime.stopAll();
     });
+
+    var tabBlockExplorer = document.getElementById('tab-blockexplorer');
+    var tabThreadExplorer = document.getElementById('tab-threadexplorer');
+
+    // Handlers to show different explorers.
+    document.getElementById('threadexplorer-link').addEventListener('click',
+        function () {
+            tabBlockExplorer.style.display = 'none';
+            tabThreadExplorer.style.display = 'block';
+        });
+    document.getElementById('blockexplorer-link').addEventListener('click',
+        function () {
+            tabBlockExplorer.style.display = 'block';
+            tabThreadExplorer.style.display = 'none';
+        });
 };