diff --git a/user-script/README.md b/user-script/README.md
new file mode 100644
index 0000000..61ad8f4
--- /dev/null
+++ b/user-script/README.md
@@ -0,0 +1,24 @@
+# User script
+
+This extension demonstrates the `browser.contentScripts.register()` API, which enables an extension to register URL-matching content scripts at runtime.
+
+This extension adds a browser action that shows a popup. The popup lets you specify:
+
+* some code that comprises your content script
+* one or more [match patterns](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns), comma-separated. The content script will only be loaded into pages whose URLs match these patterns.
+
+Once these are set up you can register the content script by clicking "Register script". The extension will then register a content script with the given properties by calling `browser.contentScripts.register()`.
+
+To keep things simple, you can only have one script registered at any time: if you click "Register script" again, the old script is unregistered. To do this, the extension keeps a reference to the `RegisteredContentScript` object returned from `browser.contentScripts.register()`: this object provides the `unregister()` method.
+
+Note that the extension uses a background script to register the content scripts and to keep a reference to the `RegisteredContentScript` object. If it did not do this, then as soon as the popup window closed, the `RegisteredContentScript` would go out of scope and be destroyed, and the browser would then unregister the content script as part of cleanup.
+
+## Default settings
+
+The popup is initialized with some default values for the pattern and the code:
+
+* the pattern `*://*.org/*`, which will load the script into any HTTP or HTTPS pages on a `.org` domain.
+* the code `document.body.innerHTML = '
This page has been eaten
'`
+
+To try the extension out quickly, just click "Register script" with these defaults, and load http://example.org/ or
+https://www.mozilla.org/. Then try changing the pattern or the code, and reloading these or related pages.
diff --git a/user-script/background.js b/user-script/background.js
new file mode 100644
index 0000000..3df64c2
--- /dev/null
+++ b/user-script/background.js
@@ -0,0 +1,22 @@
+'use strict';
+
+var registered = null;
+
+async function registerScript(message) {
+
+ let hosts = message.hosts;
+ let code = message.code;
+
+ if (registered) {
+ registered.unregister();
+ }
+
+ registered = await browser.contentScripts.register({
+ matches: hosts,
+ js: [{code}],
+ runAt: "document_idle"
+ });
+
+}
+
+browser.runtime.onMessage.addListener(registerScript);
diff --git a/user-script/icons/LICENSE b/user-script/icons/LICENSE
new file mode 100644
index 0000000..8b397ff
--- /dev/null
+++ b/user-script/icons/LICENSE
@@ -0,0 +1 @@
+The icon "if_source_code_103710.svg" is from picol.org (http://www.picol.org/) and is used under the terms of the Creative Commons Attribution license: http://creativecommons.org/licenses/by/3.0/.
diff --git a/user-script/icons/if_source_code_103710.svg b/user-script/icons/if_source_code_103710.svg
new file mode 100644
index 0000000..503d953
--- /dev/null
+++ b/user-script/icons/if_source_code_103710.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/user-script/manifest.json b/user-script/manifest.json
new file mode 100644
index 0000000..0612f45
--- /dev/null
+++ b/user-script/manifest.json
@@ -0,0 +1,36 @@
+{
+
+ "manifest_version": 2,
+ "name": "User script",
+ "version": "1.1",
+
+ "applications": {
+ "gecko": {
+ "id": "user-script-example@mozilla.org",
+ "strict_min_version": "59.0a1"
+ }
+ },
+
+ "description": "Demonstration of contentScripts.register.",
+ "icons": {
+ "48": "icons/if_source_code_103710.svg"
+ },
+
+ "permissions": [
+ ""
+ ],
+
+ "browser_action": {
+ "default_icon": {
+ "32" : "icons/if_source_code_103710.svg"
+ },
+ "default_title": "User script",
+ "default_popup": "popup/user-script.html",
+ "browser_style": true
+ },
+
+ "background": {
+ "scripts": ["background.js"]
+ }
+
+}
diff --git a/user-script/popup/user-script.css b/user-script/popup/user-script.css
new file mode 100644
index 0000000..5c12d0d
--- /dev/null
+++ b/user-script/popup/user-script.css
@@ -0,0 +1,16 @@
+
+#outer-wrapper {
+ padding: 0.5em;
+}
+
+input {
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+textarea {
+ width: 100%;
+ resize: none;
+ border: 1px solid #e4e4e4;
+ margin-bottom: 1em;
+}
diff --git a/user-script/popup/user-script.html b/user-script/popup/user-script.html
new file mode 100644
index 0000000..3073962
--- /dev/null
+++ b/user-script/popup/user-script.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+