diff --git a/package-lock.json b/package-lock.json
index c209645b9..e5219cc2f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3865,7 +3865,8 @@
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
     },
     "escape-string-regexp": {
       "version": "1.0.5",
diff --git a/package.json b/package.json
index 7e67f95b0..9e0fe0997 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,6 @@
     "canvas-toBlob": "1.0.0",
     "decode-html": "2.0.0",
     "diff-match-patch": "1.0.4",
-    "escape-html": "1.0.3",
     "format-message": "6.2.1",
     "htmlparser2": "3.10.0",
     "immutable": "3.8.1",
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index 204cd4633..b5739579c 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -1,6 +1,5 @@
 const EventEmitter = require('events');
 const {OrderedMap} = require('immutable');
-const escapeHtml = require('escape-html');
 
 const ArgumentType = require('../extension-support/argument-type');
 const Blocks = require('./blocks');
@@ -15,6 +14,7 @@ const log = require('../util/log');
 const maybeFormatMessage = require('../util/maybe-format-message');
 const StageLayering = require('./stage-layering');
 const Variable = require('./variable');
+const xmlEscape = require('../util/xml-escape');
 
 // Virtual I/O devices.
 const Clock = require('../io/clock');
@@ -747,7 +747,7 @@ class Runtime extends EventEmitter {
      * @private
      */
     _makeExtensionMenuId (menuName, extensionId) {
-        return `${extensionId}_menu_${escapeHtml(menuName)}`;
+        return `${extensionId}_menu_${xmlEscape(menuName)}`;
     }
 
     /**
@@ -1207,7 +1207,7 @@ class Runtime extends EventEmitter {
 
         const defaultValue =
             typeof argInfo.defaultValue === 'undefined' ? '' :
-                escapeHtml(maybeFormatMessage(argInfo.defaultValue, this.makeMessageContextForTarget()).toString());
+                xmlEscape(maybeFormatMessage(argInfo.defaultValue, this.makeMessageContextForTarget()).toString());
 
         if (argTypeInfo.check) {
             argJSON.check = argTypeInfo.check;
diff --git a/webpack.config.js b/webpack.config.js
index 86f9645bc..9b38815bd 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -72,7 +72,6 @@ module.exports = [
         },
         externals: {
             'decode-html': true,
-            'escape-html': true,
             'format-message': true,
             'htmlparser2': true,
             'immutable': true,