diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..20106aa
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,26 @@
+{
+  "parserOptions": {
+    "ecmaVersion": 6,
+    "sourceType": "module"
+  },
+  "env": {
+    "browser": true,
+    "amd": true,
+    "es6": true,
+    "node": true,
+    "mocha": true
+  },
+  "rules": {
+    "comma-dangle": 1,
+    "quotes": [ 1, "single" ],
+    "no-undef": 1,
+    "global-strict": 0,
+    "no-extra-semi": 1,
+    "no-underscore-dangle": 0,
+    "no-console": 1,
+    "no-unused-vars": 1,
+    "no-trailing-spaces": [1, { "skipBlankLines": true }],
+    "no-unreachable": 1,
+    "no-alert": 0
+  }
+}
diff --git a/.eslintrc.yml b/.eslintrc.yml
deleted file mode 100644
index d38ced5..0000000
--- a/.eslintrc.yml
+++ /dev/null
@@ -1,80 +0,0 @@
-# see http://eslint.org/docs/rules/ for recommended rules
-extends: 'eslint:recommended'
-
-rules:
-  indent:
-    - 2
-    - 4
-    - SwitchCase: 1
-  linebreak-style: [2, unix]
-  no-console: [0]
-  no-unused-vars: [1]
-  # commas go last
-  comma-style: [1, last]
-  # variable comes before literal in conditional
-  yoda: [1, never]
-  # dots on same line as property
-  dot-location: [1, property]
-  # don't allow void operator
-  no-void: [1]
-  # no space before function paren
-  space-before-function-paren: [1, never]
-  # prefer a single declaration for vars
-  one-var:
-    - 0
-  space-before-blocks: [1, always]
-  # prefer no space between array brackets
-  array-bracket-spacing: [1, never]
-  # prefer no space between object curly brackets
-  object-curly-spacing: [1, never]
-  # prefer no space between object prop brackets
-  computed-property-spacing: [1, never]
-  # prefer camelcase
-  # camelcase:
-  #   - 1
-  #   - properties: always
-  # prefer brackets for blocks
-  curly: [1]
-  no-multi-spaces: [1]
-  space-in-parens: [1, never]
-  eol-last: [1]
-  no-trailing-spaces: [1]
-  no-mixed-spaces-and-tabs: [1]
-  # Allow but do not force dangling commas.
-  comma-dangle: [0]
-  # use single quotes
-  quotes: [2, single]
-  # use semicolons to end statements
-  semi: [2, always]
-
-  # warn if function params are reassigned
-  no-param-reassign:
-    - 1
-    - props: false
-  # enforce type equality
-  eqeqeq: [2]
-
-  no-return-assign: [2, always]
-  no-undef-init: [1]
-  no-lonely-if: [2]
-  no-use-before-define: [2, nofunc]
-  # enforce constructor functions are uppercased
-  new-cap:
-    - 2
-    - newIsCap: true
-      capIsNew: false
-
-
-
-env:
-  # allow node env globals
-  node: true
-  # allow commonjs module definition globals (e.g. require, module.exports)
-  commonjs: true
-  mocha: true
-  es6: true
-
-
-
-
-globals:
diff --git a/.ofrc b/.ofrc
index b9c3566..b9af98f 100644
--- a/.ofrc
+++ b/.ofrc
@@ -1,7 +1,6 @@
 {
   "network": {
-    "api_protocol": "http",
-    "api_domain": "openframe.io",
-    "api_port": "80"
+    "api_base": "https://api.openframe.io",
+    "app_base": "https://openframe.io"
   }
 }
diff --git a/package.json b/package.json
index 0d770d0..7ee37f4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "openframe",
-  "version": "0.3.10",
+  "version": "0.3.11",
   "description": "Openframe controller process which runs on the machine controlling the frame.",
   "main": "index.js",
   "scripts": {
diff --git a/src/controller.js b/src/controller.js
index e279d6e..604e666 100755
--- a/src/controller.js
+++ b/src/controller.js
@@ -19,14 +19,15 @@ var util = require('util'),
     user = require('./user'),
     rest = require('./rest'),
     Spinner = require('cli-spinner').Spinner,
-    spinner = new Spinner('[%s]'),
+    spinner = new Spinner('[%s]');
 
     // --> EXPORT
-    fc = module.exports = {};
+let fc = {};
 
 // inherit from EventEmitter
-util.inherits(fc, EventEmitter);
+// util.inherits(fc, EventEmitter);
 
+module.exports = fc;
 /**
  * Initialize the frame controller
  * - login user
@@ -56,7 +57,7 @@ fc.init = function() {
  * - login user
  * - pull latest frame state
  * - install extension package
- * - add extension to frame.plugins
+ * - add extension to frame.extensions
  * - exit with user-facing success/error message
  *
  * @param  {String} extension An npm-style dependency string (package[@version]);
@@ -76,7 +77,7 @@ fc.installExtension = function(extension) {
                         .then(function() {
                             debug('Installed ' + extension + ' successfully, saving frame...');
                             // successfully installed extension locally, add to frame
-                            frame.state.plugins[packageName] = version;
+                            frame.state.extensions[packageName] = version;
                             frame.save()
                                 .then(function() {
                                     console.log('[o]   Extension installed successfully!\n');
@@ -98,7 +99,7 @@ fc.installExtension = function(extension) {
  * - login user
  * - pull latest frame state
  * - uninstall extension package
- * - remove extension to frame.plugins
+ * - remove extension to frame.extensions
  * - exit with user-facing success/error message
  *
  * @param  {String} extension name (npm package);
@@ -114,8 +115,8 @@ fc.uninstallExtension = function(packageName) {
                         .then(function() {
                             debug('Uninstalled ' + packageName + ' successfully, saving frame...');
                             // successfully installed extension locally, add to frame
-                            if (packageName in frame.state.plugins) {
-                                delete frame.state.plugins[packageName];
+                            if (packageName in frame.state.extensions) {
+                                delete frame.state.extensions[packageName];
                             }
                             frame.save()
                                 .then(function(resp) {
@@ -143,13 +144,10 @@ fc.ready = function() {
     debug('ready');
     spinner.stop(true);
 
-    if (frame.state && frame.state._current_artwork) {
+    if (frame.state && frame.state.current_artwork) {
         fc.changeArtwork();
     } else {
-        // remove port if it's 80
-        var url_port = config.ofrc.network.api_url.split(':');
-        var url = url_port[2] === '80' ? url_port[0] + url_port[1] : config.ofrc.network.api_url;
-
+        var url = config.ofrc.network.app_base;
 
         // No current artwork... give the user a message:
         console.log('[o]   Connected! You can now push artwork to this frame.');
@@ -224,7 +222,7 @@ fc.connect = function(userId) {
             .then(function() {
                 debug('ready to init...');
                 // initExtensions now always resolves, is never rejected
-                return pm.initExtensions(frame.state.plugins, fc.extensionApi);
+                return pm.initExtensions(frame.state.extensions, fc.extensionApi);
             })
             .then(readyToConnect)
             .catch(function(err) {
@@ -261,10 +259,10 @@ fc.registerNewFrame = function(userId) {
             debug(data.obj);
             frame.state = data.obj;
             frame.persistStateToFile();
-            pm.installExtensions(frame.state.plugins)
+            pm.installExtensions(frame.state.extensions)
                 .then(function() {
                     debug('-----> extensions installed');
-                    pm.initExtensions(frame.state.plugins, fc.extensionApi)
+                    pm.initExtensions(frame.state.extensions, fc.extensionApi)
                         .then(function() {
                             resolve(frame.state);
                         });
@@ -281,13 +279,13 @@ fc.registerNewFrame = function(userId) {
 
 /**
  * Change the artwork being displayed to that which is stored in the
- * Frame's _current_artwork.
+ * Frame's current_artwork.
  */
 fc.changeArtwork = function() {
-    debug('changeArtwork', frame.state._current_artwork);
+    debug('changeArtwork', frame.state.current_artwork);
 
     var old_artwork = fc.current_artwork || undefined,
-        new_artwork = frame.state._current_artwork,
+        new_artwork = frame.state.current_artwork,
         old_format = old_artwork && frame.formats[old_artwork.format],
         new_format = frame.formats[new_artwork.format],
         new_artwork_conf = new_artwork.config || {},
@@ -357,14 +355,14 @@ fc.updateFrame = function() {
     // fetch the latest frame state, and update as needed
     frame.fetch()
         .then(function(new_state) {
-            if (frame.state._current_artwork) {
+            if (frame.state.current_artwork) {
                 fc.changeArtwork()
                     .then(function() {
                         // success changing artwork, do nothing more...
                     })
                     .catch(function() {
-                        // error changing artwork, reset frame.state._current_artwork to true current
-                        frame.state._current_artwork = fc.current_artwork;
+                        // error changing artwork, reset frame.state.current_artwork to true current
+                        frame.state.current_artwork = fc.current_artwork;
                     });
             }
         });
@@ -402,7 +400,7 @@ function _startArt(new_format, new_artwork) {
     var _command = new_format.start_command,
         tokens = new_artwork.tokens || {};
     if (typeof _command === 'function') {
-        
+
         // we're passing artwork-specific args and tokens here, letting the format
         // construct the command dynamically...
         var config = new_artwork.config || {};
diff --git a/src/downloader.js b/src/downloader.js
index 5ab5a91..e0d157d 100644
--- a/src/downloader.js
+++ b/src/downloader.js
@@ -1,14 +1,14 @@
-'use strict';
+// 'use strict';
 
 /**
  * A small utility for downloading files.
  */
 
 // Dependencies
-var exec = require('child_process').exec,
-    debug = require('debug')('openframe:downloader'),
-    artworkDir = '/tmp',
-    http = require('http-request');
+const { exec, spawn } = require('child_process');
+
+var debug = require('debug')('openframe:downloader'),
+    artworkDir = '/tmp';
 
 // unused at present
 function _mkdirp(dir) {
@@ -26,23 +26,29 @@ function _mkdirp(dir) {
  * @param  {String}   file_url
  * @param  {String}   file_output_name
  */
-function downloadFile(file_url, file_output_name, cb) {
+function downloadFile(file_url, file_output_name) {
+    debug('downloading %s', file_url);
     return new Promise(function(resolve, reject) {
         var file_name = file_output_name,
             file_path = artworkDir + '/' + file_name;
 
-        // simplified download using http-request module
-        http.get({
-            url: file_url,
-            progress: function (current, total) {
-                debug('downloaded %d bytes from %d', current, total);
-            }
-        }, file_path, function (err, res) {
-            if (err) {
-                reject(err);
-                return;
+        const curl = spawn('curl', ['-L', '-o', file_path, file_url]);
+
+        curl.stdout.on('data', (data) => {
+            debug(`stdout: ${data}`);
+        });
+
+        curl.stderr.on('data', (data) => {
+            debug(`stderr: ${data}`);
+        });
+
+        curl.on('close', (code) => {
+            debug(`child process exited with code ${code}`);
+            if (code !== 0) {
+                reject('Download failed');
+            } else {
+                resolve(file_path);
             }
-            resolve(res.file);
         });
     });
 
diff --git a/src/extension-manager.js b/src/extension-manager.js
index a5f0035..f5f2ca0 100644
--- a/src/extension-manager.js
+++ b/src/extension-manager.js
@@ -4,30 +4,30 @@ var debug = require('debug')('openframe:extensions_manager'),
 
     config = require('./config'),
 
-    pm = module.exports = {};
+    em = module.exports = {};
 
 /**
- * Initialize extensionss module
+ * Initialize extensions module
  *
  * TODO: UNUSED - delete me?
  *
  * @param  {Object} ofrc config object
  */
-pm.init = function() {
+em.init = function() {
     debug('init');
 };
 
 /**
- * Install extensionss.
+ * Install extensions.
  *
- * TODO: since we're just running npm cli via exec(), and reason not to install
- * all extensionss at once instead of one at a time?
+ * TODO: since we're just running npm cli via exec(), any reason not to install
+ * all extensions at once instead of one at a time?
  *
- * @param {object} extensionss A hash of extensionss to install
+ * @param {object} extensions A hash of extensions to install
  * @param {Boolean} force Install the extensions even if it's already installed (skip the check)
  * @return {Promise} A promise resolved with all of the npmi results for each extensions
  */
-pm.installExtensions = function(extensionss, force) {
+em.installExtensions = function(extensions, force) {
     debug('installExtensions');
 
     var promises = [],
@@ -35,9 +35,9 @@ pm.installExtensions = function(extensionss, force) {
         _force = force === true ? true : false;
 
     // install each extensions
-    for (key in extensionss) {
-        if (extensionss.hasOwnProperty(key)) {
-            promises.push(_installExtension(key, extensionss[key], _force));
+    for (key in extensions) {
+        if (extensions.hasOwnProperty(key)) {
+            promises.push(_installExtension(key, extensions[key], _force));
         }
     }
 
@@ -47,20 +47,20 @@ pm.installExtensions = function(extensionss, force) {
 /**
  * Add a new extensions to this frame.
  *
- * Installs the extensions, and if that's successful then adds it to the extensionss list.
+ * Installs the extensions, and if that's successful then adds it to the extensions list.
  *
- * TODO: deal with conflicting versions of extensionss
+ * TODO: deal with conflicting versions of extensions
  *
  * @param  {String} package_name NPM package name
- * @param  {String} version      NPM package version (or repo URL for extensionss not in NPM)
+ * @param  {String} version      NPM package version (or repo URL for extensions not in NPM)
  * @return {Promise} A promise resolving with the result from npmi
  */
-pm.addExtension = function(package_name, version) {
+em.addExtension = function(package_name, version) {
     debug('addExtension', package_name, version);
     return new Promise((resolve, reject) => {
-        pm.installExtension(package_name, version)
+        em.installExtension(package_name, version)
             .then(function() {
-                pm.extensionss[package_name] = version;
+                em.extensions[package_name] = version;
                 config.save();
                 resolve(package_name);
             })
@@ -72,20 +72,20 @@ pm.addExtension = function(package_name, version) {
 };
 
 /**
- * Initialize extensionss.
+ * Initialize extensions.
  *
  * @param  {String} extensions
  * @param  {Object} ofExtensionApi An interface to the frame provided to each extensions
  */
-pm.initExtensions = function(extensionss, ofExtensionApi) {
-    debug('initExtensions', extensionss);
+em.initExtensions = function(extensions, ofExtensionApi) {
+    debug('initExtensions', extensions);
     var promises = [],
         key;
 
     return new Promise((resolve, reject) => {
         // add each extensions to package.json
-        for (key in extensionss) {
-            if (extensionss.hasOwnProperty(key)) {
+        for (key in extensions) {
+            if (extensions.hasOwnProperty(key)) {
                 promises.push(_initExtension(key, ofExtensionApi));
             }
         }
@@ -104,7 +104,7 @@ pm.initExtensions = function(extensionss, ofExtensionApi) {
  * @private
  *
  * @param  {String} package_name NPM package name
- * @param  {String} version      NPM package version (or repo URL for extensionss not in NPM)
+ * @param  {String} version      NPM package version (or repo URL for extensions not in NPM)
  * @param {Boolean} force Install the extensions even if it's already installed (skip the check)
  * @return {Promise} A promise resolving with the package_name
  */
@@ -140,7 +140,7 @@ function _installExtension(package_name, version, force) {
 }
 
 // public exposure
-pm.installExtension = _installExtension;
+em.installExtension = _installExtension;
 
 /**
  * Removes a single extensions by removing it from the npm package.
@@ -160,13 +160,13 @@ function _removeExtension(package_name) {
 }
 
 // public exposure
-pm.uninstallExtension = _removeExtension;
+em.uninstallExtension = _removeExtension;
 
 /**
  * Check whether a extension is already installed.
  *
  * @param  {String} package_name NPM package name
- * @param  {String} version      NPM package version (or repo URL for extensionss not in NPM)
+ * @param  {String} version      NPM package version (or repo URL for extensions not in NPM)
  * @return {Promise} A promise resolving with either true (extensions installed) or false (extensions not installed)
  */
 function _checkExtension(package_name, version) {
@@ -193,7 +193,7 @@ function _checkExtension(package_name, version) {
  * If the extensions has an install.sh file, execute it. Then call the extensions's init method
  * passing in a reference to the frame controller.
  *
- * TODO: initialize extensionss with sandboxed API?
+ * TODO: initialize extensions with sandboxed API?
  * - addFormat
  * - installDeps (?)
  *
diff --git a/src/frame.js b/src/frame.js
index 1c97eaf..9aa2743 100644
--- a/src/frame.js
+++ b/src/frame.js
@@ -42,7 +42,7 @@ frame.save = function(persist) {
     }
 
     // careful about circular saving... save on the server triggers save locally, triggers save to server, etc...
-    return rest.client.Frame.Frame_upsert({
+    return rest.client.Frame.Frame_upsert_patch_frames({
         data: frame.state,
         id: frame.state.id
     }).catch(debug);
diff --git a/src/pubsub.js b/src/pubsub.js
index 94aa95e..a6fe49e 100644
--- a/src/pubsub.js
+++ b/src/pubsub.js
@@ -1,5 +1,3 @@
-'use strict';
-
 var faye = require('faye'),
     config = require('./config'),
     frame = require('./frame'),
diff --git a/src/rest.js b/src/rest.js
index 7a02f43..db2088c 100644
--- a/src/rest.js
+++ b/src/rest.js
@@ -9,7 +9,7 @@ var Swagger = require('swagger-client'),
 rest.client;
 
 rest.init = function() {
-    var api_url = config.ofrc.network.api_url;
+    var api_url = config.ofrc.network.api_base;
 
     return new Promise(function(resolve, reject) {
         new Swagger({