diff --git a/interface/resources/qml/hifi/tablet/TabletButton.qml b/interface/resources/qml/hifi/tablet/TabletButton.qml
index bcd693a0a3..3c12130d2e 100644
--- a/interface/resources/qml/hifi/tablet/TabletButton.qml
+++ b/interface/resources/qml/hifi/tablet/TabletButton.qml
@@ -12,6 +12,10 @@ Item {
 
     signal clicked()
 
+    function changeProperty(key, value) {
+        tabletButton[key] = value;
+    }
+
     Rectangle {
         id: buttonBg
         color: tabletButton.color
diff --git a/libraries/script-engine/src/TabletScriptingInterface.cpp b/libraries/script-engine/src/TabletScriptingInterface.cpp
index 032d8ce671..d77c60e9e7 100644
--- a/libraries/script-engine/src/TabletScriptingInterface.cpp
+++ b/libraries/script-engine/src/TabletScriptingInterface.cpp
@@ -121,6 +121,21 @@ void TabletButtonProxy::setQmlButton(QQuickItem* qmlButton) {
     _qmlButton = qmlButton;
 }
 
-// TABLET_UI_HACK TODO: add property accessors, and forward property changes to the _qmlButton if present.
+QVariantMap TabletButtonProxy::getProperties() const {
+    std::lock_guard<std::mutex> guard(_mutex);
+    return _properties;
+}
+
+void TabletButtonProxy::editProperties(QVariantMap properties) {
+    std::lock_guard<std::mutex> guard(_mutex);
+    QVariantMap::const_iterator iter = properties.constBegin();
+    while (iter != properties.constEnd()) {
+        _properties[iter.key()] = iter.value();
+        if (_qmlButton) {
+            QMetaObject::invokeMethod(_qmlButton, "changeProperty", Qt::AutoConnection, Q_ARG(QVariant, QVariant(iter.key())), Q_ARG(QVariant, iter.value()));
+        }
+        ++iter;
+    }
+}
 
 #include "TabletScriptingInterface.moc"
diff --git a/libraries/script-engine/src/TabletScriptingInterface.h b/libraries/script-engine/src/TabletScriptingInterface.h
index 262a496f1a..da796be174 100644
--- a/libraries/script-engine/src/TabletScriptingInterface.h
+++ b/libraries/script-engine/src/TabletScriptingInterface.h
@@ -90,7 +90,19 @@ public:
 
     void setQmlButton(QQuickItem* qmlButton);
 
-    const QVariantMap& getProperties() const { return _properties; }
+    /**jsdoc
+     * Returns the current value of this button's properties
+     * @function TabletButtonProxy#getProperties
+     * @returns {object}
+     */
+    Q_INVOKABLE QVariantMap getProperties() const;
+
+    /**jsdoc
+     * Replace the values of some of this button's properties
+     * @function TabletButtonProxy#editProperties
+     * @param properties {object} set of properties to change
+     */
+    Q_INVOKABLE void editProperties(QVariantMap properties);
 
 public slots:
     void clickedSlot() { emit clicked(); }
diff --git a/scripts/developer/tests/tabletTest.js b/scripts/developer/tests/tabletTest.js
index 6f101beb8b..8840c249bb 100644
--- a/scripts/developer/tests/tabletTest.js
+++ b/scripts/developer/tests/tabletTest.js
@@ -17,6 +17,18 @@ var button = tablet.addButton({
     text: "BAM!!!"
 });
 
+// change the color and name every second...
+var colors = ["#ff6f6f", "#6fff6f", "#6f6fff"];
+var names = ["BAM!", "BAM!!", "BAM!!!"];
+var colorIndex = 0;
+Script.setInterval(function () {
+    colorIndex = (colorIndex + 1) % colors.length;
+    button.editProperties({
+        color: colors[colorIndex],
+        text: names[colorIndex]
+    });
+}, 1000);
+
 button.clicked.connect(function () {
     print("AJT: BAMM!!! CLICK from JS!");
 });