diff --git a/client/client.js b/client/client.js
index 91d9e4283885d082273fccee3b27d3093ecf8cf5..45a73a0d385a72c14d233947189aeaeac5433fb3 100644
--- a/client/client.js
+++ b/client/client.js
@@ -233,8 +233,8 @@ function heapSendsStateChange(data) {
 }
 
 function heapSendsUiChange(data){
-    if(true) console.log('HEAP SENDS CHANG UI IN MODULE', data) 
-    // 
+    if(true) console.log('HEAP SENDS MSG TO UI ELEMENT IN MDL', data) 
+    program.modules[data.id].ui[data.key].lump.onMessage(data.msg)
 }
 
 /*
@@ -254,7 +254,7 @@ function putState(rep, key) {
 }
 
 // save ui position to server for reload
-function putUi(rep) {
+function putPosition(rep) {
     var data = {
         description: {
             id: rep.description.id,
@@ -265,7 +265,7 @@ function putUi(rep) {
         }
     }
 
-    socketSend('put ui change', data)
+    socketSend('put position change', data)
 }
 
 // input / output click handling 
diff --git a/client/divtools.js b/client/divtools.js
index 228bb6d11af97c6e3e53afe008ba876438867b57..6e7fd21a71c365157b9cf09f8da1e6a1653da9ed 100644
--- a/client/divtools.js
+++ b/client/divtools.js
@@ -36,7 +36,7 @@ function addRepToView(rep) {
         function rmOnMouseUp(evt) {
             rep.description.position.left = parseInt(domElem.style.left, 10)
             rep.description.position.top = parseInt(domElem.style.top, 10)
-            putUi(rep)
+            putPosition(rep)
             document.removeEventListener('mousemove', domElemMouseMove)
             document.removeEventListener('mouseup', rmOnMouseUp)
         }
@@ -120,7 +120,7 @@ function addRepToView(rep) {
 
     wrapper.appendChild(rep.dom.domElem)
     if (uiSetFlag) {
-        putUi(rep)
+        putPosition(rep)
     }
 }
 
@@ -273,30 +273,17 @@ function writeUiElement(container, rep, key) {
     }
 
     ui.script.onload = function(msg){
-        console.log('script loaded')
-        // how many of these functions exist ?
+        console.log('UI script loaded')
+        // each ui script writes this function to 
+        // window. (global scope) on load,
+        // so we can use it now to get hooks
         registerNewModule(rep.description.id, key)
+        // that function will be used to append to
+        console.log('UI script hooked, having lump at', program.modules[rep.description.id].ui[key].lump)
+        container.appendChild(program.modules[rep.description.id].ui[key].lump.domElem)
     }
-
-    // now we'll hook it up to the socket ?
-
-    /*
-    // give it access to the socket, 
-    ui.thing.sendToHeap = function(msg) {
-        var data = {
-            id: rep.description.id,
-            key: key,
-            msg: msg
-        }
-        socketSend('put ui change', data)
-    }
-
-    container.appendChild(ui.thing.domElement)
-    rep.dom.ui[key] = ui.thing.domElement 
-    */
 }
 
-
 // bezier utilities
 
 var svgns = 'http://www.w3.org/2000/svg'
diff --git a/client/ui/uiButton.js b/client/ui/uiButton.js
index fc8e551805239904e02c334ac00a5a4610aaf90b..955a7da6423013a30f1f449e73c1616fb125234f 100644
--- a/client/ui/uiButton.js
+++ b/client/ui/uiButton.js
@@ -1,14 +1,37 @@
 (function(){
-	socketSend('console', 'loading new iife')
+	// client-side button object 
+	var btn = {}
 
-	this.init = function(){
-		socketSend('console', 'hello from' + this.parentId + this.key)
+	// make the dom object 
+	var li = document.createElement('li')
+	li.innerHTML = 'button test'
+	li.addEventListener('click', function(evt){
+		// example of how to send data back to server 
+		var data = {
+			id: btn.parentId,
+			key: btn.key,
+			msg: 'onclick'
+		}
+		socketSend('put ui change', data)
+	})
+
+	// append it to the dom so that it can be appended on init 
+	btn.domElem = li 
+
+	btn.onMessage = function(msg){
+		console.log('got message in client side ui object', msg)
+		if(msg.call == 'setText'){
+			btn.domElem.innerHTML = msg.argument
+		}
 	}
 
 	// expect this to only be used once
+	// it's basically our init function 
 	window.registerNewModule = function(id, key){
-		this.parentId = id 
-		this.key = key 
-		this.init() 
+		btn.parentId = id 
+		btn.key = key 
+		// affectionately named lump of code, insert ourselves here 
+		program.modules[id].ui[key].lump = btn 
+		socketSend('console', 'hello from' + btn.parentId + btn.key)
 	}
 })()
\ No newline at end of file
diff --git a/modules/ui/stest.js b/modules/ui/stest.js
index d44751aed2443012477f71a98ed020271dc74fed..657e25712558c7d9adcb4be016600df43b3e776d 100644
--- a/modules/ui/stest.js
+++ b/modules/ui/stest.js
@@ -51,8 +51,8 @@ function STest() {
 	ui.addElement('btnex', './ui/uiButton.js', onButtonData)
 
 	function onButtonData(evt){
-		console.log('button change evt', evt)
-		ui.btnex.isPressed = true 
+		console.log('on module callback', evt)
+		ui.btnex.setText('hello from ss')
 	}
 
 	return stest
diff --git a/src/jsui.js b/src/jsui.js
index 46f78466e8770ca0f9aada2cafe82e66e75c1395..9e3a99a1ce5d137b947760e0c0553296aac0f330 100644
--- a/src/jsui.js
+++ b/src/jsui.js
@@ -4,14 +4,22 @@ function UI() {
     ui.addElement = function(keyName, srcPath, callback){
     	var src = require(srcPath)
     	ui[keyName] = new src() 
+    	ui[keyName].keyName = keyName 
     	ui[keyName].callback = callback 
+    	ui[keyName].sendToUi = function(msg){
+    		var data = {
+    			id: ui.parentId,
+    			key: keyName, 
+    			msg: msg
+    		}
+    		ui.socket.send('put ui change', data)
+    	}
     }
 
     ui.init = function(parentModId, socket){
     	// get hookups from top level program 
         this.parentId = parentModId
         this.socket = socket
-        // and wrap state objects in getters / setters 
         for (key in this) {
             if (isUiKey(key)) {
             	// see if they have init functions?
@@ -37,4 +45,5 @@ module.exports = {
 
 /* bless u mdn 
 https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement
+https://developers.google.com/web/fundamentals/primers/modules
 */
\ No newline at end of file
diff --git a/src/ui/uiButton.js b/src/ui/uiButton.js
index 60c9e2e9a4ba5ca5fd745b47ff1e251e6dfc7df5..b47a50de78fc0efda6b997fc57dca35b32ac253f 100644
--- a/src/ui/uiButton.js
+++ b/src/ui/uiButton.js
@@ -1,11 +1,27 @@
 function UIButton() {
-	var uiButton = {
-		type: 'button',
-		clientPath: 'ui/uiButton.js',
-		isPressed: false
-	}
+    // server-side button object 
+    var uiButton = {
+        type: 'button',
+        clientPath: 'ui/uiButton.js',
+        callback: null, // this is loaded into our scope on load 
+        isPressed: false
+    }
 
-	return uiButton 
+    uiButton.onMessage = function(msg) {
+        console.log('message into server side object', msg)
+        this.callback(msg)
+    }
+
+    uiButton.setText = function(text) {
+        // ex. of how to send data up to client 
+        var msg = {
+            call: 'setText',
+            argument: text
+        }
+        this.sendToUi(msg)
+    }
+
+    return uiButton
 }
 
-module.exports = UIButton 
\ No newline at end of file
+module.exports = UIButton
\ No newline at end of file
diff --git a/views.js b/views.js
index d77ea9dcd0b7730ee75de6ad00ded0c840be619a..a413d7528bb1a4334a5962f4fb097e9ffa0d628f 100644
--- a/views.js
+++ b/views.js
@@ -116,6 +116,9 @@ function socketRecv(evt) {
             break
         case 'put ui change':
             uiRequestUiChange(data)
+            break 
+        case 'put position change':
+            uiRequestMdlPositionChange(data)
             break
         default:
             console.log('ERR server recv with non recognized type', recv)
@@ -287,7 +290,13 @@ function uiRequestLinkChange(data) {
     socketSend('put module change', nRep)
 }
 
-function uiRequestUiChange(data) {
+function uiRequestUiChange(data){
+    console.log('UI PUSH UI DATA DOWN', data)
+    var mdlUiElem = program.modules[data.id].ui[data.key]
+    mdlUiElem.onMessage(data.msg)
+}
+
+function uiRequestMdlPositionChange(data) {
     console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data)
     var mod = program.modules[data.description.id]
     mod.description.position = data.description.position