diff --git a/client/ui/multiline.js b/client/ui/multiline.js
new file mode 100644
index 0000000000000000000000000000000000000000..8f16cbe031f16721c2c432d78634afa404369731
--- /dev/null
+++ b/client/ui/multiline.js
@@ -0,0 +1,65 @@
+(function() {
+    /* KRITICAL STEP */
+    // this is our object, that we will later append
+    // to the .lump position 
+    var multiline = {}
+
+    // our dom element
+    var li = document.createElement('li')
+    var label = document.createTextNode('temp label')
+    li.appendChild(label)
+    li.appendChild(document.createElement('br'))
+    var txtArea = document.createElement('textarea')
+    txtArea.rows = 25
+    txtArea.cols = 25
+    txtArea.value = '-'
+    txtArea.addEventListener('change', function() {
+        var data = {
+            id: multiline.parentId,
+            key: multiline.key,
+            msg: txtArea.value 
+        }
+        socketSend('put ui change', data)
+    })
+    li.appendChild(txtArea)
+
+    /* KRITICAL STEP */
+    // we have to give our 'lump' object a .domElem, this
+    // will be referenced upstream to append to the right module 
+    // append it to the dom so that it can be appended on init 
+    multiline.domElem = li
+
+    /* KRITICAL STEP */
+    // whatever is posted to .lump will receive messages through
+    // .onMessage, so if we don't write one, we'll cause errors
+    // upstream, and besides, wouldn't be able to get anything from
+    // the server 
+    multiline.onMessage = function(msg) {
+        console.log('got message in client side ui object', msg)
+        if (msg.call == 'setContents') {
+            txtArea.value = msg.argument
+        } else if (msg.call == 'setLabel'){
+        	label.innerHTML- msg.argument 
+        } else if (msg.call == 'setRows') {
+        	txtArea.rows = msg.argument 
+        }
+    }
+
+    /* KRITICAL STEP */
+    // expect this to only be used once
+    // it's basically our init function 
+    // and gets called once the module is loaded 
+    window.registerNewModule = function(id, key) {
+        multiline.parentId = id
+        multiline.key = key
+        // affectionately named lump of code, insert ourselves here 
+        program.modules[id].ui[key].lump = multiline
+        // and call-back to do onload things
+        var data = {
+            id: multiline.parentId,
+            key: multiline.key,
+            msg: 'onload'
+        }
+        socketSend('put ui change', data)
+    }
+})()
\ No newline at end of file
diff --git a/modules/flowcontrol/and.js b/modules/flowcontrol/and.js
index d299e60aab6b8cb57dd1d593c7b15dfea72ef8b4..15db836f252971f5c3d225d07426d8ad2f585441 100644
--- a/modules/flowcontrol/and.js
+++ b/modules/flowcontrol/and.js
@@ -3,48 +3,56 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button
 
-// the 'andflow' flowcontrol unit only lets events through once both have occurred ... 
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI
+
+// the 'andFlow' flowcontrol unit only lets events through once both have occurred ... 
 
 function AndFlow() {
 
-    var andflow = {
+    var andFlow = {
         // descriptions are used in UI
         description: {
-            name: 'andflow',
+            name: 'andFlow',
             alt: 'in ... out'
         }
     }
 
-    andflow.state = State()
+    andFlow.state = State()
     // alias !
-    var state = andflow.state
-
-    state.toggle = Button("Reset", onReset)
+    var state = andFlow.state
     // yikes 
     state.A = 0
     state.B = 0
 
-    andflow.inputs = {
+    andFlow.ui = UI()
+    var ui = andFlow.ui
+    ui.addElement('btnReset', './ui/uiButton.js', onReset)
+    ui.btnReset.onload = function() {
+        ui.btnReset.setText('reset')
+    }
+
+    andFlow.inputs = {
         reset: Input('any', onReset),
         A: Input('any', onA),
         B: Input('any', onB)
     }
 
-    andflow.outputs = {
+    andFlow.outputs = {
         out: Output('any')
     }
 
     function onReset(evt) {
-        state.A = 0,
-            state.B = 0
+        state.A = 0
+        state.B = 0
     }
 
     function onA(input) {
         state.A = 1
         if (state.A && state.B) {
-            andflow.outputs.out.emit(1)
+            andFlow.outputs.out.emit(1)
             onReset()
         }
     }
@@ -52,12 +60,12 @@ function AndFlow() {
     function onB(input) {
         state.B = 1
         if (state.A && state.B) {
-            andflow.outputs.out.emit(1)
+            andFlow.outputs.out.emit(1)
             onReset()
         }
     }
 
-    return andflow
+    return andFlow
 }
 
 // exports 
diff --git a/modules/motion/planner.js b/modules/motion/planner.js
index dff61e2852d3a10bd9d51eefe753982ad2f38e94..7b610ebbcf0fd8181becdb10b794030c6c84aba2 100644
--- a/modules/motion/planner.js
+++ b/modules/motion/planner.js
@@ -3,7 +3,10 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI 
 
 // descartes, to you 
 const DCRT = require('../../src/cartesian.js')
@@ -26,14 +29,10 @@ function Planner() {
     state.axisIDs = 'X,Y,Z'
     state.onUiChange('axisIDs', axisIDUpdate)
 
-    state.reset = Button('reset planner', onPlannerReset)
-
     state.accel = 200 // units/s/s
     state.jd = 0.1 // units to arc about
     state.minSpeed = 1 // units/s
 
-    state.startStop = Button('start / stop planner', onStartStop)
-
     state.position = [0, 0, 0]
 
     // should be grn / red button ... 
@@ -43,6 +42,18 @@ function Planner() {
     state.netWindow = 3
     state.netState = [0, 0, 0]
 
+    planner.ui = UI()
+    var ui = planner.ui 
+    ui.addElement('resetButton', './ui/uiButton.js', onPlannerReset)
+    ui.resetButton.onload = function(){
+        ui.resetButton.setText('reset planner')
+    }
+
+    ui.addElement('startStopButton', './ui/uiButton.js', onStartStop)
+    ui.startStopButton.onload = function(){
+        ui.startStopButton.setText('start / stop planner')
+    }
+
     planner.inputs = {
         instruction: Input('move instruction', onNewInstruction),
         acks: Input('move acknowledgement', onAck),
diff --git a/modules/motion/rawmove.js b/modules/motion/rawmove.js
deleted file mode 100644
index 3a25b1d3015651a8e500d7216499507945b7d808..0000000000000000000000000000000000000000
--- a/modules/motion/rawmove.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// boilerplate atkapi header
-const JSUnit = require('../../src/jsunit.js')
-let Input = JSUnit.Input
-let Output = JSUnit.Output
-let State = JSUnit.State
-let Button = JSUnit.Button
-
-function RawMove() {
-	var rawmove = {
-		description: {
-			name: 'Low Level Move Gen',
-			alt: 'instron friendly steps'
-		}
-	}
-
-	rawmove.state = State()
-	var state = rawmove.state 
-
-	state.button = Button('SEND IT', onMoveMake)
-	state.moveSize = 1
-	state.speed = 35
-	state.axisPloy = 'Y'
-
-	rawmove.inputs = {
-		trigger: Input('event', onMoveMake)
-	}
-
-	rawmove.outputs = {
-		move: Output('move instruction')
-	}
-
-	function onMoveMake(evt){
-		var speed = state.speed
-		var move = {
-			axes: ['Y'],
-			p1: [0],
-			p2: [state.moveSize],
-			cruise: speed,
-			entry: speed,
-			exit: speed, 
-			accel: 100,
-			vector: [state.moveSize]
-		}
-
-		rawmove.outputs.move.emit(move)
-	}
-
-	return rawmove
-}
-
-module.exports = RawMove
\ No newline at end of file
diff --git a/modules/ui/button.js b/modules/ui/button.js
index a86e9acd4156e88bfd25e44d579f28f90285c2b5..cc0151e537aa4eed41f43abb5d49edcee202ed8e 100644
--- a/modules/ui/button.js
+++ b/modules/ui/button.js
@@ -3,7 +3,10 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI 
 
 // a constructor, a fn, a javascript mess
 function uiButton() {
@@ -20,7 +23,12 @@ function uiButton() {
     // alias !
     var state = button.state 
 
-    state.button = Button('WHAM', onButtonPress)
+    button.ui = UI() 
+    var ui = button.ui 
+    ui.addElement('btn', './ui/uiButton.js', onButtonPress)
+    ui.btn.onload = function(){
+        ui.btn.setText('click!')
+    }
 
     button.inputs = {
         thru: Input('any', onButtonPress) // makes anything into '1' event
diff --git a/modules/ui/multiline.js b/modules/ui/multiline.js
index da519c5bee14ce19c20ba068227011cf251949af..3660f5cde00401231dcd11d33060a7e4599cdb4e 100644
--- a/modules/ui/multiline.js
+++ b/modules/ui/multiline.js
@@ -2,9 +2,12 @@
 const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
-
 let State = JSUnit.State
 
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI 
+
 const fs = require('fs')
 
 // a constructor, a fn, a javascript mess
@@ -20,12 +23,32 @@ function MultiLineIn() {
 
     multilinein.state = State()
     // alias !
-    state.load = State.newButton('--', onLoadFile)
-    state.thru = Button('THRU', lineThru)
-    state.previously = MultiLine('lines complete', 11)
-    state.now = MultiLine('line just out', 1)
-    state.incoming = MultiLine('future lines', 36)
-    state.incoming.value = "G0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\n"
+    var state = multilinein.state
+
+    multilinein.ui = UI()
+    var ui = multilinein.ui 
+    ui.addElement('thruButton', './ui/uiButton.js', lineThru)
+    ui.thruButton.onload = function(){
+        ui.thruButton.setText('click to advance line-by-line')
+    }
+
+    ui.addElement('previously', './ui/multiline.js', null)
+    ui.previously.onload = function(){
+        ui.previously.setContents('-')
+        ui.previously.setLabel('previously:')
+    }
+
+    ui.addElement('justNow', './ui/multiline.js', null)
+    ui.justNow.onload = function(){
+        ui.justNow.setContents('-')
+        ui.justNow.setLabel('just now:')
+    }
+
+    ui.addElement('incoming', './ui/multiline.js', null)
+    ui.incoming.onload = function(){
+        ui.incoming.setContents('G0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\nG0 F50 X10Y10Z10\nG0 X20Y20Z0\nG0 X0\nG0 Y10\n')
+        ui.incoming.setLabel('incoming:')
+    }
 
     multilinein.inputs = {
         req: Input('number', onLineRequest),
@@ -41,21 +64,18 @@ function MultiLineIn() {
 
     function lineThru() {
         // get all as arrays with linebreak as delimiter 
-        var outBox = state.previously.value.split('\n')
-        var box = state.now.value
-        var inBox = state.incoming.value.split('\n')
+        
+        var outBox = ui.previously.contents.split('\n')
+        var box = ui.justNow.contents
+        var inBox = ui.incoming.contents.split('\n')
 
         if (inBox.length < 1 && box == '') {
             console.log("END OF MULTILINE")
         } else {
             outBox.push(box)
-            state.now.value= checkContent(inBox.shift())
-            state.previously.value = checkContent(outBox.join('\n'))
-            state.incoming.value = checkContent(inBox.join('\n'))
-            // HERE is another hack for busted state-passing system 
-            state.now = state.now
-            state.previously = state.previously
-            state.incoming = state.incoming 
+            ui.justNow.setContents(checkContent(inBox.shift()))
+            ui.previously.setContents(checkContent(outBox.join('\n')))
+            ui.incoming.setContents(checkContent(inBox.join('\n')))
             if (inBox.length < 1 && box == '') {
                 console.log("END OF MULTILINE")
             } else {
@@ -84,8 +104,8 @@ function MultiLineIn() {
             if (err) throw err;
             console.log('Loading:')
             console.log(data);
-            state.incoming.value = data
-            state.incoming = state.incoming
+            //state.incoming.value = data
+            //state.incoming = state.incoming
         })
     }
 
diff --git a/modules/ui/number.js b/modules/ui/number.js
index 08302e196d779d04af46c21e32b574a96563c75a..00620aef30abd62ed255474599dce5c8a8e8dfe8 100644
--- a/modules/ui/number.js
+++ b/modules/ui/number.js
@@ -3,7 +3,10 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI 
 
 // a constructor, a fn, a javascript mess
 function uiNum() {
@@ -25,7 +28,13 @@ function uiNum() {
     var state = uinum.state 
 
     state.number = 10
-    state.onUiChange('number', onNumberDesire)
+
+    uinum.ui = UI() 
+    var ui = uinum.ui 
+    ui.addElement('onNumberButton', './ui/uiButton.js', onNumberDesire)
+    ui.onNumberButton.onload = function() {
+        ui.onNumberButton.setText('number out ->')
+    }
 
     state.button = Button('WHAM', onNumberDesire)
 
diff --git a/modules/util/andgate.js b/modules/util/andgate.js
index 0ad34185ab53418225c516f8fb6fca72378fc598..1c970f67221b0682bf48e740dbbb2f3dd64954d4 100644
--- a/modules/util/andgate.js
+++ b/modules/util/andgate.js
@@ -3,59 +3,67 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI 
 
 // a constructor, a fn, a javascript mess
 function AndFlowControl() {
 
-    var gate = {
+    var andGate = {
         // descriptions are used in UI
         description: {
-            name: 'gate',
+            name: 'andGate',
             alt: 'in ... out'
         }
     }
 
-    gate.state = State()
+    andGate.state = State()
     // alias !
-    var state = gate.state 
-
-    state.toggle = Button("Open / Close", onButtonPress)
+    var state = andGate.state 
 
     // yikes 
-    gate.isOpen = false
+    andGate.isOpen = false
     state.message = 'closed'
 
-    gate.inputs = {
-        thru: Input('any', gateKeeper) // makes anything into '1' event
+    andGate.ui = UI() 
+    var ui = andGate.ui 
+    ui.addElement('openButton', './ui/uiButton.js', onButtonPress)
+    ui.openButton.onload = function() {
+        ui.openButton.setText('open / close')
+    }
+
+    andGate.inputs = {
+        thru: Input('any', andGateKeeper) // makes anything into '1' event
     }
 
-    gate.outputs = {
+    andGate.outputs = {
         out: Output('any')
     }
 
     function onButtonPress(evt){
         state.toggle.isPressed = false
-        if(gate.isOpen){
-            gate.isOpen = false
+        if(andGate.isOpen){
+            andGate.isOpen = false
             state.message = 'closed' 
         } else {
-            gate.isOpen = true
+            andGate.isOpen = true
             state.message = 'open'
-            gate.outputs.out.emit('go')
+            andGate.outputs.out.emit('go')
         }
     }
 
-    function gateKeeper(input){
+    function andGateKeeper(input){
         // dereference for kicks
         var outVar = JSON.parse(JSON.stringify(input))
-        if(gate.isOpen){
-            gate.outputs.out.emit(outVar)
+        if(andGate.isOpen){
+            andGate.outputs.out.emit(outVar)
         }
     }
 
-    return gate
+    return andGate
 }
 
 // exports 
-module.exports = Gate
\ No newline at end of file
+module.exports = AndFlowControl
\ No newline at end of file
diff --git a/modules/util/gate.js b/modules/util/gate.js
index cada67a4316aea7b16c783645bcf31b8b05ef37c..a26b8433eea84df69011f232b32d6aa5965a58e2 100644
--- a/modules/util/gate.js
+++ b/modules/util/gate.js
@@ -3,7 +3,10 @@ const JSUnit = require('../../src/jsunit.js')
 let Input = JSUnit.Input
 let Output = JSUnit.Output
 let State = JSUnit.State
-let Button = JSUnit.Button 
+
+// interface elements
+const JSUI = require('../../src/jsui.js')
+let UI = JSUI.UI
 
 // a constructor, a fn, a javascript mess
 function Gate() {
@@ -18,11 +21,17 @@ function Gate() {
 
     gate.state = State()
     // alias ! 
-    var state = gate.state 
+    var state = gate.state
 
-    state.toggle = Button("Open / Close", onButtonPress)
     state.message = 'closed'
 
+    gate.ui = UI()
+    var ui = gate.ui
+    ui.addElement('openButton', './ui/uiButton.js', onButtonPress)
+    ui.openButton.onload = function() {
+        ui.openButton.setText('toggle gate')
+    }
+
     // yikes 
     gate.isOpen = false
 
@@ -34,12 +43,12 @@ function Gate() {
         out: Output('any')
     }
 
-    function onButtonPress(evt){
+    function onButtonPress(evt) {
         console.log("GATE BUTTON")
         state.toggle.isPressed = false
-        if(gate.isOpen){
+        if (gate.isOpen) {
             gate.isOpen = false
-            state.message = 'closed' 
+            state.message = 'closed'
         } else {
             gate.isOpen = true
             state.message = 'open'
@@ -47,10 +56,10 @@ function Gate() {
         }
     }
 
-    function gateKeeper(input){
+    function gateKeeper(input) {
         // dereference for kicks
         var outVar = JSON.parse(JSON.stringify(input))
-        if(gate.isOpen){
+        if (gate.isOpen) {
             gate.outputs.out.emit(outVar)
         }
     }
diff --git a/src/ui/multiline.js b/src/ui/multiline.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb17f878ef2bf5d66259b89e0c92e88fb6664144
--- /dev/null
+++ b/src/ui/multiline.js
@@ -0,0 +1,45 @@
+function Multiline() {
+    // server-side button object 
+    var multiline = {
+        type: 'button',
+        clientPath: 'ui/multiline.js',
+        callback: null, // this is loaded into our scope on load 
+        contents: null, // current value of multiline obj 
+        label: null
+    }
+
+    // hook to recv messages from the ui counterpart
+    multiline.onMessage = function(msg) {
+        console.log('message into server side object', msg)
+        if(msg == 'onload'){
+        	this.onload() 
+        } else {
+        	this.contents = msg 
+        }
+    }
+
+    multiline.setLabel = function(string){
+    	this.label = string 
+    	var msg = {
+    		call: 'setLabel',
+    		argument: string
+    	}
+    	this.sendToUi(msg)
+    }
+
+    // example of a function to use within the module 
+    multiline.setContents = function(string) {
+    	this.contents = string 
+        // ex. of how to send data up to client 
+        var msg = {
+            call: 'setContents',
+            argument: string
+        }
+        // this.sendToUi is given to us during load
+        this.sendToUi(msg)
+    }
+
+    return multiline
+}
+
+module.exports = Multiline
\ No newline at end of file