diff --git a/package.json b/package.json
index 1fcd00ef3..fdcb4bc84 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,9 @@
   },
   "devDependencies": {
     "eslint": "2.7.0",
+    "highlightjs": "8.7.0",
     "json-loader": "0.5.4",
+    "scratch-blocks": "git+https://git@github.com/LLK/scratch-blocks.git",
     "tap": "5.7.1",
     "webpack": "1.13.0"
   }
diff --git a/playground/index.html b/playground/index.html
new file mode 100644
index 000000000..cbb7c2ac5
--- /dev/null
+++ b/playground/index.html
@@ -0,0 +1,91 @@
+<!doctype html>
+
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>Scratch VM Playground</title>
+    <link rel="stylesheet" href="playground.css">
+    <link rel="stylesheet" href="../node_modules/highlightjs/styles/zenburn.css">
+</head>
+<body>
+    <div id="vm-devtools">
+        <div id="tab-blockexplorer">
+            <h2>VM Block Representation</h2>
+            <pre id="blockexplorer"></pre>
+        </div>
+    </div>
+    <div id="blocks"></div>
+
+    <xml id="toolbox" style="display: none">
+      <category name="Events">
+        <block type="event_whenflagclicked"></block>
+        <block type="event_whenbroadcastreceived"></block>
+        <block type="event_broadcast"></block>
+      </category>
+      <category name="Control">
+        <block type="control_forever"></block>
+        <block type="control_repeat">
+          <value name="TIMES">
+            <shadow type="math_number">
+              <field name="NUM">4</field>
+            </shadow>
+          </value>
+        </block>
+        <block type="control_if"></block>
+        <block type="control_if_else"></block>
+        <block type="control_stop"></block>
+        <block type="control_wait">
+          <value name="DURATION">
+            <shadow type="math_number">
+              <field name="NUM">1</field>
+            </shadow>
+          </value>
+        </block>
+      </category>
+      <category name="Wedo">
+          <block type="wedo_setcolor"></block>
+          <block type="wedo_motorspeed"></block>
+          <block type="wedo_whentilt"></block>
+          <block type="wedo_whendistanceclose"></block>
+      </category>
+      <category name="Operators">
+          <block type="math_add">
+            <value name="NUM1">
+              <shadow type="math_number">
+                <field name="NUM">0</field>
+              </shadow>
+            </value>
+            <value name="NUM2">
+              <shadow type="math_number">
+                <field name="NUM">0</field>
+              </shadow>
+            </value>
+          </block>
+          <block type="logic_equals">
+            <value name="VALUE1">
+              <shadow type="text">
+                <field name="TEXT">0</field>
+              </shadow>
+            </value>
+            <value name="VALUE2">
+              <shadow type="text">
+                <field name="TEXT">0</field>
+              </shadow>
+            </value>
+          </block>
+      </category>
+    </xml>
+
+    <!-- Syntax highlighter -->
+    <script src="../node_modules/highlightjs/highlight.pack.min.js"></script>
+    <!-- Scratch Blocks -->
+    <!-- For easier development between the two, use `npm link` -->
+    <script src="../node_modules/scratch-blocks/blockly_compressed_vertical.js"></script>
+    <script src="../node_modules/scratch-blocks/blocks_compressed.js"></script>
+    <script src="../node_modules/scratch-blocks/blocks_compressed_vertical.js"></script>
+    <!-- Compiled VM -->
+    <script src="../vm.js"></script>
+    <!-- Playground -->
+    <script src="./playground.js"></script>
+</body>
+</html>
diff --git a/playground/playground.css b/playground/playground.css
new file mode 100644
index 000000000..f1a54242e
--- /dev/null
+++ b/playground/playground.css
@@ -0,0 +1,30 @@
+body {
+    background: rgb(36,36,36);
+}
+#blocks {
+    position: absolute;
+    left: 40%;
+    right: 0;
+    top: 0;
+    bottom: 0;
+}
+#vm-devtools {
+    color: rgb(217,217,217);
+    position: absolute;
+    left: 1%;
+    right: 60%;
+    top: 0;
+    bottom: 0;
+    width: 35%;
+}
+#blockexplorer {
+    position: absolute;
+    width: 100%;
+    height: 80%;
+    overflow: scroll;
+    border: 1px solid #fff;
+    background: rgb(36,36,36);
+    color: rgb(217,217,217);
+    font-family: monospace;
+    font-size: 10pt;
+}
diff --git a/playground/playground.js b/playground/playground.js
new file mode 100644
index 000000000..1b8b99523
--- /dev/null
+++ b/playground/playground.js
@@ -0,0 +1,26 @@
+window.onload = function() {
+    // Lots of global variables to make debugging easier
+    var vm = new window.VirtualMachine();
+    window.vm = vm;
+
+    var toolbox = document.getElementById('toolbox');
+    var workspace = window.Blockly.inject('blocks', {
+        toolbox: toolbox,
+        media: '../node_modules/scratch-blocks/media/'
+    });
+    window.workspace = workspace;
+
+    // @todo: Also bind to flyout events, block running feedback.
+    // Block events.
+    workspace.addChangeListener(vm.blockListener);
+
+    var explorer = 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);
+    });
+
+    // Run threads
+    vm.runtime.start();
+};