diff --git a/runtime/ui/controller/controller_collection.go b/runtime/ui/controller/collection.go
similarity index 79%
rename from runtime/ui/controller/controller_collection.go
rename to runtime/ui/controller/collection.go
index f0b7c7b..a7c6124 100644
--- a/runtime/ui/controller/controller_collection.go
+++ b/runtime/ui/controller/collection.go
@@ -9,22 +9,22 @@ import (
 )
 
 // var ccOnce sync.Once
-var controllers *ControllerCollection
+var controllers *Collection
 
-type ControllerCollection struct {
+type Collection struct {
 	gui     *gocui.Gui
-	Tree    *FileTreeController
-	Layer   *LayerController
-	Status  *StatusController
-	Filter  *FilterController
-	Details *DetailsController
+	Tree    *FileTree
+	Layer   *Layer
+	Status  *Status
+	Filter  *Filter
+	Details *Details
 	lookup  map[string]Controller
 }
 
-func NewControllerCollection(g *gocui.Gui, analysis *image.AnalysisResult, cache filetree.TreeCache) (*ControllerCollection, error) {
+func NewCollection(g *gocui.Gui, analysis *image.AnalysisResult, cache filetree.TreeCache) (*Collection, error) {
 	var err error
 
-	controllers = &ControllerCollection{
+	controllers = &Collection{
 		gui: g,
 	}
 	controllers.lookup = make(map[string]Controller)
@@ -56,7 +56,7 @@ func NewControllerCollection(g *gocui.Gui, analysis *image.AnalysisResult, cache
 	return controllers, nil
 }
 
-func (c *ControllerCollection) UpdateAndRender() error {
+func (c *Collection) UpdateAndRender() error {
 	err := c.Update()
 	if err != nil {
 		logrus.Debug("failed update: ", err)
@@ -73,7 +73,7 @@ func (c *ControllerCollection) UpdateAndRender() error {
 }
 
 // Update refreshes the state objects for future rendering.
-func (c *ControllerCollection) Update() error {
+func (c *Collection) Update() error {
 	for _, controller := range c.lookup {
 		err := controller.Update()
 		if err != nil {
@@ -85,7 +85,7 @@ func (c *ControllerCollection) Update() error {
 }
 
 // Render flushes the state objects to the screen.
-func (c *ControllerCollection) Render() error {
+func (c *Collection) Render() error {
 	for _, controller := range c.lookup {
 		if controller.IsVisible() {
 			err := controller.Render()
@@ -98,7 +98,7 @@ func (c *ControllerCollection) Render() error {
 }
 
 // ToggleView switches between the file view and the layer view and re-renders the screen.
-func (c *ControllerCollection) ToggleView() (err error) {
+func (c *Collection) ToggleView() (err error) {
 	v := c.gui.CurrentView()
 	if v == nil || v.Name() == c.Layer.Name() {
 		_, err = c.gui.SetCurrentView(c.Tree.Name())
@@ -114,7 +114,7 @@ func (c *ControllerCollection) ToggleView() (err error) {
 	return c.UpdateAndRender()
 }
 
-func (c *ControllerCollection) ToggleFilterView() error {
+func (c *Collection) ToggleFilterView() error {
 	// delete all user input from the tree view
 	err := c.Filter.ToggleVisible()
 	if err != nil {
@@ -135,17 +135,17 @@ func (c *ControllerCollection) ToggleFilterView() error {
 }
 
 // CursorDown moves the cursor down in the currently selected gocui pane, scrolling the screen as needed.
-func (c *ControllerCollection) CursorDown(g *gocui.Gui, v *gocui.View) error {
+func (c *Collection) CursorDown(g *gocui.Gui, v *gocui.View) error {
 	return c.CursorStep(g, v, 1)
 }
 
 // CursorUp moves the cursor up in the currently selected gocui pane, scrolling the screen as needed.
-func (c *ControllerCollection) CursorUp(g *gocui.Gui, v *gocui.View) error {
+func (c *Collection) CursorUp(g *gocui.Gui, v *gocui.View) error {
 	return c.CursorStep(g, v, -1)
 }
 
 // Moves the cursor the given step distance, setting the origin to the new cursor line
-func (c *ControllerCollection) CursorStep(g *gocui.Gui, v *gocui.View, step int) error {
+func (c *Collection) CursorStep(g *gocui.Gui, v *gocui.View, step int) error {
 	cx, cy := v.Cursor()
 
 	// if there isn't a next line
diff --git a/runtime/ui/controller/details_controller.go b/runtime/ui/controller/details.go
similarity index 67%
rename from runtime/ui/controller/details_controller.go
rename to runtime/ui/controller/details.go
index d3eccbc..60336e1 100644
--- a/runtime/ui/controller/details_controller.go
+++ b/runtime/ui/controller/details.go
@@ -14,9 +14,9 @@ import (
 	"github.com/lunixbochs/vtclean"
 )
 
-// DetailsController holds the UI objects and data models for populating the lower-left pane. Specifically the pane that
+// Details holds the UI objects and data models for populating the lower-left pane. Specifically the pane that
 // shows the layer details and image statistics.
-type DetailsController struct {
+type Details struct {
 	name           string
 	gui            *gocui.Gui
 	view           *gocui.View
@@ -26,8 +26,8 @@ type DetailsController struct {
 }
 
 // NewDetailsController creates a new view object attached the the global [gocui] screen object.
-func NewDetailsController(name string, gui *gocui.Gui, efficiency float64, inefficiencies filetree.EfficiencySlice) (controller *DetailsController) {
-	controller = new(DetailsController)
+func NewDetailsController(name string, gui *gocui.Gui, efficiency float64, inefficiencies filetree.EfficiencySlice) (controller *Details) {
+	controller = new(Details)
 
 	// populate main fields
 	controller.name = name
@@ -38,63 +38,63 @@ func NewDetailsController(name string, gui *gocui.Gui, efficiency float64, ineff
 	return controller
 }
 
-func (controller *DetailsController) Name() string {
-	return controller.name
+func (c *Details) Name() string {
+	return c.name
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (controller *DetailsController) Setup(v *gocui.View, header *gocui.View) error {
+func (c *Details) Setup(v *gocui.View, header *gocui.View) error {
 
 	// set controller options
-	controller.view = v
-	controller.view.Editable = false
-	controller.view.Wrap = true
-	controller.view.Highlight = false
-	controller.view.Frame = false
+	c.view = v
+	c.view.Editable = false
+	c.view.Wrap = true
+	c.view.Highlight = false
+	c.view.Frame = false
 
-	controller.header = header
-	controller.header.Editable = false
-	controller.header.Wrap = false
-	controller.header.Frame = false
+	c.header = header
+	c.header.Editable = false
+	c.header.Wrap = false
+	c.header.Frame = false
 
 	var infos = []key.BindingInfo{
 		{
 			Key:      gocui.KeyArrowDown,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorDown,
+			OnAction: c.CursorDown,
 		},
 		{
 			Key:      gocui.KeyArrowUp,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorUp,
+			OnAction: c.CursorUp,
 		},
 	}
 
-	_, err := key.GenerateBindings(controller.gui, controller.name, infos)
+	_, err := key.GenerateBindings(c.gui, c.name, infos)
 	if err != nil {
 		return err
 	}
 
-	return controller.Render()
+	return c.Render()
 }
 
 // IsVisible indicates if the details view pane is currently initialized.
-func (controller *DetailsController) IsVisible() bool {
-	return controller != nil
+func (c *Details) IsVisible() bool {
+	return c != nil
 }
 
 // CursorDown moves the cursor down in the details pane (currently indicates nothing).
-func (controller *DetailsController) CursorDown() error {
-	return controllers.CursorDown(controller.gui, controller.view)
+func (c *Details) CursorDown() error {
+	return controllers.CursorDown(c.gui, c.view)
 }
 
 // CursorUp moves the cursor up in the details pane (currently indicates nothing).
-func (controller *DetailsController) CursorUp() error {
-	return controllers.CursorUp(controller.gui, controller.view)
+func (c *Details) CursorUp() error {
+	return controllers.CursorUp(c.gui, c.view)
 }
 
 // Update refreshes the state objects for future rendering.
-func (controller *DetailsController) Update() error {
+func (c *Details) Update() error {
 	return nil
 }
 
@@ -103,7 +103,7 @@ func (controller *DetailsController) Update() error {
 // 2. the image efficiency score
 // 3. the estimated wasted image space
 // 4. a list of inefficient file allocations
-func (controller *DetailsController) Render() error {
+func (c *Details) Render() error {
 	currentLayer := controllers.Layer.currentLayer()
 
 	var wastedSpace int64
@@ -112,12 +112,12 @@ func (controller *DetailsController) Render() error {
 	inefficiencyReport := fmt.Sprintf(format.Header(template), "Count", "Total Space", "Path")
 
 	height := 100
-	if controller.view != nil {
-		_, height = controller.view.Size()
+	if c.view != nil {
+		_, height = c.view.Size()
 	}
 
-	for idx := 0; idx < len(controller.inefficiencies); idx++ {
-		data := controller.inefficiencies[len(controller.inefficiencies)-1-idx]
+	for idx := 0; idx < len(c.inefficiencies); idx++ {
+		data := c.inefficiencies[len(c.inefficiencies)-1-idx]
 		wastedSpace += data.CumulativeSize
 
 		// todo: make this report scrollable
@@ -127,24 +127,24 @@ func (controller *DetailsController) Render() error {
 	}
 
 	imageSizeStr := fmt.Sprintf("%s %s", format.Header("Total Image size:"), humanize.Bytes(controllers.Layer.ImageSize))
-	effStr := fmt.Sprintf("%s %d %%", format.Header("Image efficiency score:"), int(100.0*controller.efficiency))
+	effStr := fmt.Sprintf("%s %d %%", format.Header("Image efficiency score:"), int(100.0*c.efficiency))
 	wastedSpaceStr := fmt.Sprintf("%s %s", format.Header("Potential wasted space:"), humanize.Bytes(uint64(wastedSpace)))
 
-	controller.gui.Update(func(g *gocui.Gui) error {
+	c.gui.Update(func(g *gocui.Gui) error {
 		// update header
-		controller.header.Clear()
-		width, _ := controller.view.Size()
+		c.header.Clear()
+		width, _ := c.view.Size()
 
 		layerHeaderStr := fmt.Sprintf("[Layer Details]%s", strings.Repeat("─", width-15))
 		imageHeaderStr := fmt.Sprintf("[Image Details]%s", strings.Repeat("─", width-15))
 
-		_, err := fmt.Fprintln(controller.header, format.Header(vtclean.Clean(layerHeaderStr, false)))
+		_, err := fmt.Fprintln(c.header, format.Header(vtclean.Clean(layerHeaderStr, false)))
 		if err != nil {
 			return err
 		}
 
 		// update contents
-		controller.view.Clear()
+		c.view.Clear()
 
 		var lines = make([]string, 0)
 		if currentLayer.Names != nil && len(currentLayer.Names) > 0 {
@@ -162,7 +162,7 @@ func (controller *DetailsController) Render() error {
 		lines = append(lines, effStr+"\n")
 		lines = append(lines, inefficiencyReport)
 
-		_, err = fmt.Fprintln(controller.view, strings.Join(lines, "\n"))
+		_, err = fmt.Fprintln(c.view, strings.Join(lines, "\n"))
 		if err != nil {
 			logrus.Debug("unable to write to buffer: ", err)
 		}
@@ -172,6 +172,6 @@ func (controller *DetailsController) Render() error {
 }
 
 // KeyHelp indicates all the possible actions a user can take while the current pane is selected (currently does nothing).
-func (controller *DetailsController) KeyHelp() string {
+func (c *Details) KeyHelp() string {
 	return "TBD"
 }
diff --git a/runtime/ui/controller/filetree_controller.go b/runtime/ui/controller/filetree.go
similarity index 55%
rename from runtime/ui/controller/filetree_controller.go
rename to runtime/ui/controller/filetree.go
index 5dc27db..df10a6b 100644
--- a/runtime/ui/controller/filetree_controller.go
+++ b/runtime/ui/controller/filetree.go
@@ -20,21 +20,21 @@ const (
 
 type CompareType int
 
-// FileTreeController holds the UI objects and data models for populating the right pane. Specifically the pane that
+// FileTree holds the UI objects and data models for populating the right pane. Specifically the pane that
 // shows selected layer or aggregate file ASCII tree.
-type FileTreeController struct {
+type FileTree struct {
 	name   string
 	gui    *gocui.Gui
 	view   *gocui.View
 	header *gocui.View
-	vm     *viewmodel.FileTreeViewModel
+	vm     *viewmodel.FileTree
 
 	helpKeys []*key.Binding
 }
 
 // NewFileTreeController creates a new view object attached the the global [gocui] screen object.
-func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (controller *FileTreeController, err error) {
-	controller = new(FileTreeController)
+func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (controller *FileTree, err error) {
+	controller = new(FileTree)
 
 	// populate main fields
 	controller.name = name
@@ -47,143 +47,143 @@ func NewFileTreeController(name string, gui *gocui.Gui, tree *filetree.FileTree,
 	return controller, err
 }
 
-func (controller *FileTreeController) Name() string {
-	return controller.name
+func (c *FileTree) Name() string {
+	return c.name
 }
 
-func (controller *FileTreeController) AreAttributesVisible() bool {
-	return controller.vm.ShowAttributes
+func (c *FileTree) AreAttributesVisible() bool {
+	return c.vm.ShowAttributes
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (controller *FileTreeController) Setup(v *gocui.View, header *gocui.View) error {
+func (c *FileTree) Setup(v *gocui.View, header *gocui.View) error {
 
 	// set controller options
-	controller.view = v
-	controller.view.Editable = false
-	controller.view.Wrap = false
-	controller.view.Frame = false
+	c.view = v
+	c.view.Editable = false
+	c.view.Wrap = false
+	c.view.Frame = false
 
-	controller.header = header
-	controller.header.Editable = false
-	controller.header.Wrap = false
-	controller.header.Frame = false
+	c.header = header
+	c.header.Editable = false
+	c.header.Wrap = false
+	c.header.Frame = false
 
 	var infos = []key.BindingInfo{
 		{
 			ConfigKeys: []string{"keybinding.toggle-collapse-dir"},
-			OnAction:   controller.toggleCollapse,
+			OnAction:   c.toggleCollapse,
 			Display:    "Collapse dir",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-collapse-all-dir"},
-			OnAction:   controller.toggleCollapseAll,
+			OnAction:   c.toggleCollapseAll,
 			Display:    "Collapse all dir",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-added-files"},
-			OnAction:   func() error { return controller.toggleShowDiffType(filetree.Added) },
-			IsSelected: func() bool { return !controller.vm.HiddenDiffTypes[filetree.Added] },
+			OnAction:   func() error { return c.toggleShowDiffType(filetree.Added) },
+			IsSelected: func() bool { return !c.vm.HiddenDiffTypes[filetree.Added] },
 			Display:    "Added",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-removed-files"},
-			OnAction:   func() error { return controller.toggleShowDiffType(filetree.Removed) },
-			IsSelected: func() bool { return !controller.vm.HiddenDiffTypes[filetree.Removed] },
+			OnAction:   func() error { return c.toggleShowDiffType(filetree.Removed) },
+			IsSelected: func() bool { return !c.vm.HiddenDiffTypes[filetree.Removed] },
 			Display:    "Removed",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-modified-files"},
-			OnAction:   func() error { return controller.toggleShowDiffType(filetree.Modified) },
-			IsSelected: func() bool { return !controller.vm.HiddenDiffTypes[filetree.Modified] },
+			OnAction:   func() error { return c.toggleShowDiffType(filetree.Modified) },
+			IsSelected: func() bool { return !c.vm.HiddenDiffTypes[filetree.Modified] },
 			Display:    "Modified",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-unchanged-files", "keybinding.toggle-unmodified-files"},
-			OnAction:   func() error { return controller.toggleShowDiffType(filetree.Unmodified) },
-			IsSelected: func() bool { return !controller.vm.HiddenDiffTypes[filetree.Unmodified] },
+			OnAction:   func() error { return c.toggleShowDiffType(filetree.Unmodified) },
+			IsSelected: func() bool { return !c.vm.HiddenDiffTypes[filetree.Unmodified] },
 			Display:    "Unmodified",
 		},
 		{
 			ConfigKeys: []string{"keybinding.toggle-filetree-attributes"},
-			OnAction:   controller.toggleAttributes,
-			IsSelected: func() bool { return controller.vm.ShowAttributes },
+			OnAction:   c.toggleAttributes,
+			IsSelected: func() bool { return c.vm.ShowAttributes },
 			Display:    "Attributes",
 		},
 		{
 			ConfigKeys: []string{"keybinding.page-up"},
-			OnAction:   controller.PageUp,
+			OnAction:   c.PageUp,
 		},
 		{
 			ConfigKeys: []string{"keybinding.page-down"},
-			OnAction:   controller.PageDown,
+			OnAction:   c.PageDown,
 		},
 		{
 			Key:      gocui.KeyArrowDown,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorDown,
+			OnAction: c.CursorDown,
 		},
 		{
 			Key:      gocui.KeyArrowUp,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorUp,
+			OnAction: c.CursorUp,
 		},
 		{
 			Key:      gocui.KeyArrowLeft,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorLeft,
+			OnAction: c.CursorLeft,
 		},
 		{
 			Key:      gocui.KeyArrowRight,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorRight,
+			OnAction: c.CursorRight,
 		},
 	}
 
-	helpKeys, err := key.GenerateBindings(controller.gui, controller.name, infos)
+	helpKeys, err := key.GenerateBindings(c.gui, c.name, infos)
 	if err != nil {
 		return err
 	}
-	controller.helpKeys = helpKeys
+	c.helpKeys = helpKeys
 
-	_, height := controller.view.Size()
-	controller.vm.Setup(0, height)
-	_ = controller.Update()
-	_ = controller.Render()
+	_, height := c.view.Size()
+	c.vm.Setup(0, height)
+	_ = c.Update()
+	_ = c.Render()
 
 	return nil
 }
 
 // IsVisible indicates if the file tree view pane is currently initialized
-func (controller *FileTreeController) IsVisible() bool {
-	return controller != nil
+func (c *FileTree) IsVisible() bool {
+	return c != nil
 }
 
 // ResetCursor moves the cursor back to the top of the buffer and translates to the top of the buffer.
-func (controller *FileTreeController) resetCursor() {
-	_ = controller.view.SetCursor(0, 0)
-	controller.vm.ResetCursor()
+func (c *FileTree) resetCursor() {
+	_ = c.view.SetCursor(0, 0)
+	c.vm.ResetCursor()
 }
 
 // SetTreeByLayer populates the view model by stacking the indicated image layer file trees.
-func (controller *FileTreeController) setTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error {
-	err := controller.vm.SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
+func (c *FileTree) setTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error {
+	err := c.vm.SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop)
 	if err != nil {
 		return err
 	}
 	// controller.ResetCursor()
 
-	_ = controller.Update()
-	return controller.Render()
+	_ = c.Update()
+	return c.Render()
 }
 
 // CursorDown moves the cursor down and renders the view.
 // Note: we cannot use the gocui buffer since any state change requires writing the entire tree to the buffer.
 // Instead we are keeping an upper and lower bounds of the tree string to render and only flushing
 // this range into the view buffer. This is much faster when tree sizes are large.
-func (controller *FileTreeController) CursorDown() error {
-	if controller.vm.CursorDown() {
-		return controller.Render()
+func (c *FileTree) CursorDown() error {
+	if c.vm.CursorDown() {
+		return c.Render()
 	}
 	return nil
 }
@@ -192,82 +192,82 @@ func (controller *FileTreeController) CursorDown() error {
 // Note: we cannot use the gocui buffer since any state change requires writing the entire tree to the buffer.
 // Instead we are keeping an upper and lower bounds of the tree string to render and only flushing
 // this range into the view buffer. This is much faster when tree sizes are large.
-func (controller *FileTreeController) CursorUp() error {
-	if controller.vm.CursorUp() {
-		return controller.Render()
+func (c *FileTree) CursorUp() error {
+	if c.vm.CursorUp() {
+		return c.Render()
 	}
 	return nil
 }
 
 // CursorLeft moves the cursor up until we reach the Parent Node or top of the tree
-func (controller *FileTreeController) CursorLeft() error {
-	err := controller.vm.CursorLeft(filterRegex())
+func (c *FileTree) CursorLeft() error {
+	err := c.vm.CursorLeft(filterRegex())
 	if err != nil {
 		return err
 	}
-	_ = controller.Update()
-	return controller.Render()
+	_ = c.Update()
+	return c.Render()
 }
 
 // CursorRight descends into directory expanding it if needed
-func (controller *FileTreeController) CursorRight() error {
-	err := controller.vm.CursorRight(filterRegex())
+func (c *FileTree) CursorRight() error {
+	err := c.vm.CursorRight(filterRegex())
 	if err != nil {
 		return err
 	}
-	_ = controller.Update()
-	return controller.Render()
+	_ = c.Update()
+	return c.Render()
 }
 
 // PageDown moves to next page putting the cursor on top
-func (controller *FileTreeController) PageDown() error {
-	err := controller.vm.PageDown()
+func (c *FileTree) PageDown() error {
+	err := c.vm.PageDown()
 	if err != nil {
 		return err
 	}
-	return controller.Render()
+	return c.Render()
 }
 
 // PageUp moves to previous page putting the cursor on top
-func (controller *FileTreeController) PageUp() error {
-	err := controller.vm.PageUp()
+func (c *FileTree) PageUp() error {
+	err := c.vm.PageUp()
 	if err != nil {
 		return err
 	}
-	return controller.Render()
+	return c.Render()
 }
 
 // getAbsPositionNode determines the selected screen cursor's location in the file tree, returning the selected FileNode.
-// func (controller *FileTreeController) getAbsPositionNode() (node *filetree.FileNode) {
+// func (controller *FileTree) getAbsPositionNode() (node *filetree.FileNode) {
 // 	return controller.vm.getAbsPositionNode(filterRegex())
 // }
 
 // ToggleCollapse will collapse/expand the selected FileNode.
-func (controller *FileTreeController) toggleCollapse() error {
-	err := controller.vm.ToggleCollapse(filterRegex())
+func (c *FileTree) toggleCollapse() error {
+	err := c.vm.ToggleCollapse(filterRegex())
 	if err != nil {
 		return err
 	}
-	_ = controller.Update()
-	return controller.Render()
+	_ = c.Update()
+	return c.Render()
 }
 
 // ToggleCollapseAll will collapse/expand the all directories.
-func (controller *FileTreeController) toggleCollapseAll() error {
-	err := controller.vm.ToggleCollapseAll()
+func (c *FileTree) toggleCollapseAll() error {
+	err := c.vm.ToggleCollapseAll()
 	if err != nil {
 		return err
 	}
-	if controller.vm.CollapseAll {
-		controller.resetCursor()
+	if c.vm.CollapseAll {
+		c.resetCursor()
 	}
-	_ = controller.Update()
-	return controller.Render()
+	_ = c.Update()
+	return c.Render()
 }
 
 // ToggleAttributes will show/hide file attributes
-func (controller *FileTreeController) toggleAttributes() error {
-	err := controller.vm.ToggleAttributes()
+func (c *FileTree) toggleAttributes() error {
+	err := c.vm.ToggleAttributes()
 	if err != nil {
 		return err
 	}
@@ -276,8 +276,8 @@ func (controller *FileTreeController) toggleAttributes() error {
 }
 
 // ToggleShowDiffType will show/hide the selected DiffType in the filetree pane.
-func (controller *FileTreeController) toggleShowDiffType(diffType filetree.DiffType) error {
-	controller.vm.ToggleShowDiffType(diffType)
+func (c *FileTree) toggleShowDiffType(diffType filetree.DiffType) error {
+	c.vm.ToggleShowDiffType(diffType)
 	// we need to render the changes to the status pane as well (not just this contoller/view)
 	return controllers.UpdateAndRender()
 }
@@ -301,58 +301,58 @@ func filterRegex() *regexp.Regexp {
 }
 
 // OnLayoutChange is called by the UI framework to inform the view-model of the new screen dimensions
-func (controller *FileTreeController) OnLayoutChange(resized bool) error {
-	_ = controller.Update()
+func (c *FileTree) OnLayoutChange(resized bool) error {
+	_ = c.Update()
 	if resized {
-		return controller.Render()
+		return c.Render()
 	}
 	return nil
 }
 
 // Update refreshes the state objects for future rendering.
-func (controller *FileTreeController) Update() error {
+func (c *FileTree) Update() error {
 	var width, height int
 
-	if controller.view != nil {
-		width, height = controller.view.Size()
+	if c.view != nil {
+		width, height = c.view.Size()
 	} else {
 		// before the TUI is setup there may not be a controller to reference. Use the entire screen as reference.
-		width, height = controller.gui.Size()
+		width, height = c.gui.Size()
 	}
 	// height should account for the header
-	return controller.vm.Update(filterRegex(), width, height-1)
+	return c.vm.Update(filterRegex(), width, height-1)
 }
 
 // Render flushes the state objects (file tree) to the pane.
-func (controller *FileTreeController) Render() error {
+func (c *FileTree) Render() error {
 	title := "Current Layer Contents"
 	if controllers.Layer.CompareMode == CompareAll {
 		title = "Aggregated Layer Contents"
 	}
 
 	// indicate when selected
-	if controller.gui.CurrentView() == controller.view {
+	if c.gui.CurrentView() == c.view {
 		title = "● " + title
 	}
 
-	controller.gui.Update(func(g *gocui.Gui) error {
+	c.gui.Update(func(g *gocui.Gui) error {
 		// update the header
-		controller.header.Clear()
+		c.header.Clear()
 		width, _ := g.Size()
 		headerStr := fmt.Sprintf("[%s]%s\n", title, strings.Repeat("─", width*2))
-		if controller.vm.ShowAttributes {
+		if c.vm.ShowAttributes {
 			headerStr += fmt.Sprintf(filetree.AttributeFormat+" %s", "P", "ermission", "UID:GID", "Size", "Filetree")
 		}
 
-		_, _ = fmt.Fprintln(controller.header, format.Header(vtclean.Clean(headerStr, false)))
+		_, _ = fmt.Fprintln(c.header, format.Header(vtclean.Clean(headerStr, false)))
 
 		// update the contents
-		controller.view.Clear()
-		err := controller.vm.Render()
+		c.view.Clear()
+		err := c.vm.Render()
 		if err != nil {
 			return err
 		}
-		_, err = fmt.Fprint(controller.view, controller.vm.Buffer.String())
+		_, err = fmt.Fprint(c.view, c.vm.Buffer.String())
 
 		return err
 	})
@@ -360,9 +360,9 @@ func (controller *FileTreeController) Render() error {
 }
 
 // KeyHelp indicates all the possible actions a user can take while the current pane is selected.
-func (controller *FileTreeController) KeyHelp() string {
+func (c *FileTree) KeyHelp() string {
 	var help string
-	for _, binding := range controller.helpKeys {
+	for _, binding := range c.helpKeys {
 		help += binding.RenderKeyHelp()
 	}
 	return help
diff --git a/runtime/ui/controller/filter_controller.go b/runtime/ui/controller/filter.go
similarity index 58%
rename from runtime/ui/controller/filter_controller.go
rename to runtime/ui/controller/filter.go
index 2ff718d..51c0e3b 100644
--- a/runtime/ui/controller/filter_controller.go
+++ b/runtime/ui/controller/filter.go
@@ -7,9 +7,9 @@ import (
 	"github.com/wagoodman/dive/runtime/ui/format"
 )
 
-// FilterController holds the UI objects and data models for populating the bottom row. Specifically the pane that
+// Filter holds the UI objects and data models for populating the bottom row. Specifically the pane that
 // allows the user to filter the file tree by path.
-type FilterController struct {
+type Filter struct {
 	name      string
 	gui       *gocui.Gui
 	view      *gocui.View
@@ -20,8 +20,8 @@ type FilterController struct {
 }
 
 // NewFilterController creates a new view object attached the the global [gocui] screen object.
-func NewFilterController(name string, gui *gocui.Gui) (controller *FilterController) {
-	controller = new(FilterController)
+func NewFilterController(name string, gui *gocui.Gui) (controller *Filter) {
+	controller = new(Filter)
 
 	// populate main fields
 	controller.name = name
@@ -32,40 +32,40 @@ func NewFilterController(name string, gui *gocui.Gui) (controller *FilterControl
 	return controller
 }
 
-func (controller *FilterController) Name() string {
-	return controller.name
+func (c *Filter) Name() string {
+	return c.name
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (controller *FilterController) Setup(v *gocui.View, header *gocui.View) error {
+func (c *Filter) Setup(v *gocui.View, header *gocui.View) error {
 
 	// set controller options
-	controller.view = v
-	controller.maxLength = 200
-	controller.view.Frame = false
-	controller.view.BgColor = gocui.AttrReverse
-	controller.view.Editable = true
-	controller.view.Editor = controller
+	c.view = v
+	c.maxLength = 200
+	c.view.Frame = false
+	c.view.BgColor = gocui.AttrReverse
+	c.view.Editable = true
+	c.view.Editor = c
 
-	controller.header = header
-	controller.header.BgColor = gocui.AttrReverse
-	controller.header.Editable = false
-	controller.header.Wrap = false
-	controller.header.Frame = false
+	c.header = header
+	c.header.BgColor = gocui.AttrReverse
+	c.header.Editable = false
+	c.header.Wrap = false
+	c.header.Frame = false
 
-	return controller.Render()
+	return c.Render()
 }
 
 // ToggleFilterView shows/hides the file tree filter pane.
-func (controller *FilterController) ToggleVisible() error {
+func (c *Filter) ToggleVisible() error {
 	// delete all user input from the tree view
-	controller.view.Clear()
+	c.view.Clear()
 
 	// toggle hiding
-	controller.hidden = !controller.hidden
+	c.hidden = !c.hidden
 
-	if !controller.hidden {
-		_, err := controller.gui.SetCurrentView(controller.name)
+	if !c.hidden {
+		_, err := c.gui.SetCurrentView(c.name)
 		if err != nil {
 			logrus.Error("unable to toggle filter view: ", err)
 			return err
@@ -76,41 +76,41 @@ func (controller *FilterController) ToggleVisible() error {
 	// reset the cursor for the next time it is visible
 	// Note: there is a subtle gocui behavior here where this cannot be called when the view
 	// is newly visible. Is this a problem with dive or gocui?
-	return controller.view.SetCursor(0, 0)
+	return c.view.SetCursor(0, 0)
 }
 
 // todo: remove the need for this
-func (controller *FilterController) HeaderStr() string {
-	return controller.headerStr
+func (c *Filter) HeaderStr() string {
+	return c.headerStr
 }
 
 // IsVisible indicates if the filter view pane is currently initialized
-func (controller *FilterController) IsVisible() bool {
-	if controller == nil {
+func (c *Filter) IsVisible() bool {
+	if c == nil {
 		return false
 	}
-	return !controller.hidden
+	return !c.hidden
 }
 
 // CursorDown moves the cursor down in the filter pane (currently indicates nothing).
-func (controller *FilterController) CursorDown() error {
+func (c *Filter) CursorDown() error {
 	return nil
 }
 
 // CursorUp moves the cursor up in the filter pane (currently indicates nothing).
-func (controller *FilterController) CursorUp() error {
+func (c *Filter) CursorUp() error {
 	return nil
 }
 
 // Edit intercepts the key press events in the filer view to update the file view in real time.
-func (controller *FilterController) Edit(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
-	if !controller.IsVisible() {
+func (c *Filter) Edit(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
+	if !c.IsVisible() {
 		return
 	}
 
 	cx, _ := v.Cursor()
 	ox, _ := v.Origin()
-	limit := ox+cx+1 > controller.maxLength
+	limit := ox+cx+1 > c.maxLength
 	switch {
 	case ch != 0 && mod == 0 && !limit:
 		v.EditWrite(ch)
@@ -126,14 +126,14 @@ func (controller *FilterController) Edit(v *gocui.View, key gocui.Key, ch rune,
 }
 
 // Update refreshes the state objects for future rendering (currently does nothing).
-func (controller *FilterController) Update() error {
+func (c *Filter) Update() error {
 	return nil
 }
 
 // Render flushes the state objects to the screen. Currently this is the users path filter input.
-func (controller *FilterController) Render() error {
-	controller.gui.Update(func(g *gocui.Gui) error {
-		_, err := fmt.Fprintln(controller.header, format.Header(controller.headerStr))
+func (c *Filter) Render() error {
+	c.gui.Update(func(g *gocui.Gui) error {
+		_, err := fmt.Fprintln(c.header, format.Header(c.headerStr))
 		if err != nil {
 			logrus.Error("unable to write to buffer: ", err)
 		}
@@ -143,6 +143,6 @@ func (controller *FilterController) Render() error {
 }
 
 // KeyHelp indicates all the possible actions a user can take while the current pane is selected.
-func (controller *FilterController) KeyHelp() string {
+func (c *Filter) KeyHelp() string {
 	return format.StatusControlNormal("▏Type to filter the file tree ")
 }
diff --git a/runtime/ui/controller/layer_controller.go b/runtime/ui/controller/layer.go
similarity index 50%
rename from runtime/ui/controller/layer_controller.go
rename to runtime/ui/controller/layer.go
index a0bf0c0..948a0b1 100644
--- a/runtime/ui/controller/layer_controller.go
+++ b/runtime/ui/controller/layer.go
@@ -13,9 +13,9 @@ import (
 	"github.com/spf13/viper"
 )
 
-// LayerController holds the UI objects and data models for populating the lower-left pane. Specifically the pane that
+// Layer holds the UI objects and data models for populating the lower-left pane. Specifically the pane that
 // shows the image layers and layer selector.
-type LayerController struct {
+type Layer struct {
 	name              string
 	gui               *gocui.Gui
 	view              *gocui.View
@@ -30,8 +30,8 @@ type LayerController struct {
 }
 
 // NewLayerController creates a new view object attached the the global [gocui] screen object.
-func NewLayerController(name string, gui *gocui.Gui, layers []*image.Layer) (controller *LayerController, err error) {
-	controller = new(LayerController)
+func NewLayerController(name string, gui *gocui.Gui, layers []*image.Layer) (controller *Layer, err error) {
+	controller = new(Layer)
 
 	// populate main fields
 	controller.name = name
@@ -50,196 +50,196 @@ func NewLayerController(name string, gui *gocui.Gui, layers []*image.Layer) (con
 	return controller, err
 }
 
-func (controller *LayerController) Name() string {
-	return controller.name
+func (c *Layer) Name() string {
+	return c.name
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (controller *LayerController) Setup(v *gocui.View, header *gocui.View) error {
+func (c *Layer) Setup(v *gocui.View, header *gocui.View) error {
 
 	// set controller options
-	controller.view = v
-	controller.view.Editable = false
-	controller.view.Wrap = false
-	controller.view.Frame = false
+	c.view = v
+	c.view.Editable = false
+	c.view.Wrap = false
+	c.view.Frame = false
 
-	controller.header = header
-	controller.header.Editable = false
-	controller.header.Wrap = false
-	controller.header.Frame = false
+	c.header = header
+	c.header.Editable = false
+	c.header.Wrap = false
+	c.header.Frame = false
 
 	var infos = []key.BindingInfo{
 		{
 			ConfigKeys: []string{"keybinding.compare-layer"},
-			OnAction:   func() error { return controller.setCompareMode(CompareLayer) },
-			IsSelected: func() bool { return controller.CompareMode == CompareLayer },
+			OnAction:   func() error { return c.setCompareMode(CompareLayer) },
+			IsSelected: func() bool { return c.CompareMode == CompareLayer },
 			Display:    "Show layer changes",
 		},
 		{
 			ConfigKeys: []string{"keybinding.compare-all"},
-			OnAction:   func() error { return controller.setCompareMode(CompareAll) },
-			IsSelected: func() bool { return controller.CompareMode == CompareAll },
+			OnAction:   func() error { return c.setCompareMode(CompareAll) },
+			IsSelected: func() bool { return c.CompareMode == CompareAll },
 			Display:    "Show aggregated changes",
 		},
 		{
 			Key:      gocui.KeyArrowDown,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorDown,
+			OnAction: c.CursorDown,
 		},
 		{
 			Key:      gocui.KeyArrowUp,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorUp,
+			OnAction: c.CursorUp,
 		},
 		{
 			Key:      gocui.KeyArrowLeft,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorUp,
+			OnAction: c.CursorUp,
 		},
 		{
 			Key:      gocui.KeyArrowRight,
 			Modifier: gocui.ModNone,
-			OnAction: controller.CursorDown,
+			OnAction: c.CursorDown,
 		},
 		{
 			ConfigKeys: []string{"keybinding.page-up"},
-			OnAction:   controller.PageUp,
+			OnAction:   c.PageUp,
 		},
 		{
 			ConfigKeys: []string{"keybinding.page-down"},
-			OnAction:   controller.PageDown,
+			OnAction:   c.PageDown,
 		},
 	}
 
-	helpKeys, err := key.GenerateBindings(controller.gui, controller.name, infos)
+	helpKeys, err := key.GenerateBindings(c.gui, c.name, infos)
 	if err != nil {
 		return err
 	}
-	controller.helpKeys = helpKeys
+	c.helpKeys = helpKeys
 
-	return controller.Render()
+	return c.Render()
 }
 
 // height obtains the height of the current pane (taking into account the lost space due to the header).
-func (controller *LayerController) height() uint {
-	_, height := controller.view.Size()
+func (c *Layer) height() uint {
+	_, height := c.view.Size()
 	return uint(height - 1)
 }
 
 // IsVisible indicates if the layer view pane is currently initialized.
-func (controller *LayerController) IsVisible() bool {
-	return controller != nil
+func (c *Layer) IsVisible() bool {
+	return c != nil
 }
 
 // PageDown moves to next page putting the cursor on top
-func (controller *LayerController) PageDown() error {
-	step := int(controller.height()) + 1
-	targetLayerIndex := controller.LayerIndex + step
+func (c *Layer) PageDown() error {
+	step := int(c.height()) + 1
+	targetLayerIndex := c.LayerIndex + step
 
-	if targetLayerIndex > len(controller.Layers) {
-		step -= targetLayerIndex - (len(controller.Layers) - 1)
+	if targetLayerIndex > len(c.Layers) {
+		step -= targetLayerIndex - (len(c.Layers) - 1)
 	}
 
 	if step > 0 {
-		err := controllers.CursorStep(controller.gui, controller.view, step)
+		err := controllers.CursorStep(c.gui, c.view, step)
 		if err == nil {
-			return controller.SetCursor(controller.LayerIndex + step)
+			return c.SetCursor(c.LayerIndex + step)
 		}
 	}
 	return nil
 }
 
 // PageUp moves to previous page putting the cursor on top
-func (controller *LayerController) PageUp() error {
-	step := int(controller.height()) + 1
-	targetLayerIndex := controller.LayerIndex - step
+func (c *Layer) PageUp() error {
+	step := int(c.height()) + 1
+	targetLayerIndex := c.LayerIndex - step
 
 	if targetLayerIndex < 0 {
 		step += targetLayerIndex
 	}
 
 	if step > 0 {
-		err := controllers.CursorStep(controller.gui, controller.view, -step)
+		err := controllers.CursorStep(c.gui, c.view, -step)
 		if err == nil {
-			return controller.SetCursor(controller.LayerIndex - step)
+			return c.SetCursor(c.LayerIndex - step)
 		}
 	}
 	return nil
 }
 
 // CursorDown moves the cursor down in the layer pane (selecting a higher layer).
-func (controller *LayerController) CursorDown() error {
-	if controller.LayerIndex < len(controller.Layers) {
-		err := controllers.CursorDown(controller.gui, controller.view)
+func (c *Layer) CursorDown() error {
+	if c.LayerIndex < len(c.Layers) {
+		err := controllers.CursorDown(c.gui, c.view)
 		if err == nil {
-			return controller.SetCursor(controller.LayerIndex + 1)
+			return c.SetCursor(c.LayerIndex + 1)
 		}
 	}
 	return nil
 }
 
 // CursorUp moves the cursor up in the layer pane (selecting a lower layer).
-func (controller *LayerController) CursorUp() error {
-	if controller.LayerIndex > 0 {
-		err := controllers.CursorUp(controller.gui, controller.view)
+func (c *Layer) CursorUp() error {
+	if c.LayerIndex > 0 {
+		err := controllers.CursorUp(c.gui, c.view)
 		if err == nil {
-			return controller.SetCursor(controller.LayerIndex - 1)
+			return c.SetCursor(c.LayerIndex - 1)
 		}
 	}
 	return nil
 }
 
 // SetCursor resets the cursor and orients the file tree view based on the given layer index.
-func (controller *LayerController) SetCursor(layer int) error {
-	controller.LayerIndex = layer
-	err := controllers.Tree.setTreeByLayer(controller.getCompareIndexes())
+func (c *Layer) SetCursor(layer int) error {
+	c.LayerIndex = layer
+	err := controllers.Tree.setTreeByLayer(c.getCompareIndexes())
 	if err != nil {
 		return err
 	}
 
 	_ = controllers.Details.Render()
 
-	return controller.Render()
+	return c.Render()
 }
 
 // currentLayer returns the Layer object currently selected.
-func (controller *LayerController) currentLayer() *image.Layer {
-	return controller.Layers[controller.LayerIndex]
+func (c *Layer) currentLayer() *image.Layer {
+	return c.Layers[c.LayerIndex]
 }
 
 // setCompareMode switches the layer comparison between a single-layer comparison to an aggregated comparison.
-func (controller *LayerController) setCompareMode(compareMode CompareType) error {
-	controller.CompareMode = compareMode
+func (c *Layer) setCompareMode(compareMode CompareType) error {
+	c.CompareMode = compareMode
 	err := controllers.UpdateAndRender()
 	if err != nil {
 		logrus.Errorf("unable to set compare mode: %+v", err)
 		return err
 	}
-	return controllers.Tree.setTreeByLayer(controller.getCompareIndexes())
+	return controllers.Tree.setTreeByLayer(c.getCompareIndexes())
 }
 
 // getCompareIndexes determines the layer boundaries to use for comparison (based on the current compare mode)
-func (controller *LayerController) getCompareIndexes() (bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) {
-	bottomTreeStart = controller.CompareStartIndex
-	topTreeStop = controller.LayerIndex
+func (c *Layer) getCompareIndexes() (bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) {
+	bottomTreeStart = c.CompareStartIndex
+	topTreeStop = c.LayerIndex
 
-	if controller.LayerIndex == controller.CompareStartIndex {
-		bottomTreeStop = controller.LayerIndex
-		topTreeStart = controller.LayerIndex
-	} else if controller.CompareMode == CompareLayer {
-		bottomTreeStop = controller.LayerIndex - 1
-		topTreeStart = controller.LayerIndex
+	if c.LayerIndex == c.CompareStartIndex {
+		bottomTreeStop = c.LayerIndex
+		topTreeStart = c.LayerIndex
+	} else if c.CompareMode == CompareLayer {
+		bottomTreeStop = c.LayerIndex - 1
+		topTreeStart = c.LayerIndex
 	} else {
-		bottomTreeStop = controller.CompareStartIndex
-		topTreeStart = controller.CompareStartIndex + 1
+		bottomTreeStop = c.CompareStartIndex
+		topTreeStart = c.CompareStartIndex + 1
 	}
 
 	return bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop
 }
 
 // renderCompareBar returns the formatted string for the given layer.
-func (controller *LayerController) renderCompareBar(layerIdx int) string {
-	bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop := controller.getCompareIndexes()
+func (c *Layer) renderCompareBar(layerIdx int) string {
+	bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop := c.getCompareIndexes()
 	result := "  "
 
 	if layerIdx >= bottomTreeStart && layerIdx <= bottomTreeStop {
@@ -253,10 +253,10 @@ func (controller *LayerController) renderCompareBar(layerIdx int) string {
 }
 
 // Update refreshes the state objects for future rendering (currently does nothing).
-func (controller *LayerController) Update() error {
-	controller.ImageSize = 0
-	for idx := 0; idx < len(controller.Layers); idx++ {
-		controller.ImageSize += controller.Layers[idx].Size
+func (c *Layer) Update() error {
+	c.ImageSize = 0
+	for idx := 0; idx < len(c.Layers); idx++ {
+		c.ImageSize += c.Layers[idx].Size
 	}
 	return nil
 }
@@ -264,36 +264,36 @@ func (controller *LayerController) Update() error {
 // Render flushes the state objects to the screen. The layers pane reports:
 // 1. the layers of the image + metadata
 // 2. the current selected image
-func (controller *LayerController) Render() error {
+func (c *Layer) Render() error {
 
 	// indicate when selected
 	title := "Layers"
-	if controller.gui.CurrentView() == controller.view {
+	if c.gui.CurrentView() == c.view {
 		title = "● " + title
 	}
 
-	controller.gui.Update(func(g *gocui.Gui) error {
+	c.gui.Update(func(g *gocui.Gui) error {
 		// update header
-		controller.header.Clear()
+		c.header.Clear()
 		width, _ := g.Size()
 		headerStr := fmt.Sprintf("[%s]%s\n", title, strings.Repeat("─", width*2))
 		headerStr += fmt.Sprintf("Cmp"+image.LayerFormat, "Size", "Command")
-		_, err := fmt.Fprintln(controller.header, format.Header(vtclean.Clean(headerStr, false)))
+		_, err := fmt.Fprintln(c.header, format.Header(vtclean.Clean(headerStr, false)))
 		if err != nil {
 			return err
 		}
 
 		// update contents
-		controller.view.Clear()
-		for idx, layer := range controller.Layers {
+		c.view.Clear()
+		for idx, layer := range c.Layers {
 
 			layerStr := layer.String()
-			compareBar := controller.renderCompareBar(idx)
+			compareBar := c.renderCompareBar(idx)
 
-			if idx == controller.LayerIndex {
-				_, err = fmt.Fprintln(controller.view, compareBar+" "+format.Selected(layerStr))
+			if idx == c.LayerIndex {
+				_, err = fmt.Fprintln(c.view, compareBar+" "+format.Selected(layerStr))
 			} else {
-				_, err = fmt.Fprintln(controller.view, compareBar+" "+layerStr)
+				_, err = fmt.Fprintln(c.view, compareBar+" "+layerStr)
 			}
 
 			if err != nil {
@@ -308,9 +308,9 @@ func (controller *LayerController) Render() error {
 }
 
 // KeyHelp indicates all the possible actions a user can take while the current pane is selected.
-func (controller *LayerController) KeyHelp() string {
+func (c *Layer) KeyHelp() string {
 	var help string
-	for _, binding := range controller.helpKeys {
+	for _, binding := range c.helpKeys {
 		help += binding.RenderKeyHelp()
 	}
 	return help
diff --git a/runtime/ui/controller/status_controller.go b/runtime/ui/controller/status.go
similarity index 56%
rename from runtime/ui/controller/status_controller.go
rename to runtime/ui/controller/status.go
index 7de9a30..9a3e612 100644
--- a/runtime/ui/controller/status_controller.go
+++ b/runtime/ui/controller/status.go
@@ -10,9 +10,9 @@ import (
 	"github.com/jroimartin/gocui"
 )
 
-// StatusController holds the UI objects and data models for populating the bottom-most pane. Specifically the panel
+// Status holds the UI objects and data models for populating the bottom-most pane. Specifically the panel
 // shows the user a set of possible actions to take in the window and currently selected pane.
-type StatusController struct {
+type Status struct {
 	name string
 	gui  *gocui.Gui
 	view *gocui.View
@@ -21,8 +21,8 @@ type StatusController struct {
 }
 
 // NewStatusController creates a new view object attached the the global [gocui] screen object.
-func NewStatusController(name string, gui *gocui.Gui) (controller *StatusController) {
-	controller = new(StatusController)
+func NewStatusController(name string, gui *gocui.Gui) (controller *Status) {
+	controller = new(Status)
 
 	// populate main fields
 	controller.name = name
@@ -32,49 +32,49 @@ func NewStatusController(name string, gui *gocui.Gui) (controller *StatusControl
 	return controller
 }
 
-func (controller *StatusController) Name() string {
-	return controller.name
+func (c *Status) Name() string {
+	return c.name
 }
 
-func (controller *StatusController) AddHelpKeys(keys ...*key.Binding) {
-	controller.helpKeys = append(controller.helpKeys, keys...)
+func (c *Status) AddHelpKeys(keys ...*key.Binding) {
+	c.helpKeys = append(c.helpKeys, keys...)
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (controller *StatusController) Setup(v *gocui.View, header *gocui.View) error {
+func (c *Status) Setup(v *gocui.View, header *gocui.View) error {
 
 	// set controller options
-	controller.view = v
-	controller.view.Frame = false
+	c.view = v
+	c.view.Frame = false
 
-	return controller.Render()
+	return c.Render()
 }
 
 // IsVisible indicates if the status view pane is currently initialized.
-func (controller *StatusController) IsVisible() bool {
-	return controller != nil
+func (c *Status) IsVisible() bool {
+	return c != nil
 }
 
 // CursorDown moves the cursor down in the details pane (currently indicates nothing).
-func (controller *StatusController) CursorDown() error {
+func (c *Status) CursorDown() error {
 	return nil
 }
 
 // CursorUp moves the cursor up in the details pane (currently indicates nothing).
-func (controller *StatusController) CursorUp() error {
+func (c *Status) CursorUp() error {
 	return nil
 }
 
 // Update refreshes the state objects for future rendering (currently does nothing).
-func (controller *StatusController) Update() error {
+func (c *Status) Update() error {
 	return nil
 }
 
 // Render flushes the state objects to the screen.
-func (controller *StatusController) Render() error {
-	controller.gui.Update(func(g *gocui.Gui) error {
-		controller.view.Clear()
-		_, err := fmt.Fprintln(controller.view, controller.KeyHelp()+format.StatusNormal("▏"+strings.Repeat(" ", 1000)))
+func (c *Status) Render() error {
+	c.gui.Update(func(g *gocui.Gui) error {
+		c.view.Clear()
+		_, err := fmt.Fprintln(c.view, c.KeyHelp()+format.StatusNormal("▏"+strings.Repeat(" ", 1000)))
 		if err != nil {
 			logrus.Debug("unable to write to buffer: ", err)
 		}
@@ -85,9 +85,9 @@ func (controller *StatusController) Render() error {
 }
 
 // KeyHelp indicates all the possible global actions a user can take when any pane is selected.
-func (controller *StatusController) KeyHelp() string {
+func (c *Status) KeyHelp() string {
 	var help string
-	for _, binding := range controller.helpKeys {
+	for _, binding := range c.helpKeys {
 		help += binding.RenderKeyHelp()
 	}
 	return help
diff --git a/runtime/ui/layout_manager.go b/runtime/ui/layout_manager.go
index 561f683..fb59d54 100644
--- a/runtime/ui/layout_manager.go
+++ b/runtime/ui/layout_manager.go
@@ -9,10 +9,10 @@ import (
 
 type layoutManager struct {
 	fileTreeSplitRatio float64
-	controllers        *controller.ControllerCollection
+	controllers        *controller.Collection
 }
 
-func newLayoutManager(c *controller.ControllerCollection) *layoutManager {
+func newLayoutManager(c *controller.Collection) *layoutManager {
 
 	fileTreeSplitRatio := viper.GetFloat64("filetree.pane-width")
 	if fileTreeSplitRatio >= 1 || fileTreeSplitRatio <= 0 {
diff --git a/runtime/ui/ui.go b/runtime/ui/ui.go
index b4fa834..e0cced8 100644
--- a/runtime/ui/ui.go
+++ b/runtime/ui/ui.go
@@ -16,7 +16,7 @@ const debug = false
 // type global
 type app struct {
 	gui         *gocui.Gui
-	controllers *controller.ControllerCollection
+	controllers *controller.Collection
 	layout      *layoutManager
 }
 
@@ -28,10 +28,10 @@ var (
 func newApp(gui *gocui.Gui, analysis *image.AnalysisResult, cache filetree.TreeCache) (*app, error) {
 	var err error
 	once.Do(func() {
-		var theControls *controller.ControllerCollection
+		var theControls *controller.Collection
 		var globalHelpKeys []*key.Binding
 
-		theControls, err = controller.NewControllerCollection(gui, analysis, cache)
+		theControls, err = controller.NewCollection(gui, analysis, cache)
 		if err != nil {
 			return
 		}
diff --git a/runtime/ui/viewmodel/filetree_viewmodel.go b/runtime/ui/viewmodel/filetree.go
similarity index 89%
rename from runtime/ui/viewmodel/filetree_viewmodel.go
rename to runtime/ui/viewmodel/filetree.go
index cf467e6..75cb469 100644
--- a/runtime/ui/viewmodel/filetree_viewmodel.go
+++ b/runtime/ui/viewmodel/filetree.go
@@ -15,7 +15,7 @@ import (
 
 // FileTreeViewModel holds the UI objects and data models for populating the right pane. Specifically the pane that
 // shows selected layer or aggregate file ASCII tree.
-type FileTreeViewModel struct {
+type FileTree struct {
 	ModelTree *filetree.FileTree
 	ViewTree  *filetree.FileTree
 	RefTrees  []*filetree.FileTree
@@ -35,8 +35,8 @@ type FileTreeViewModel struct {
 }
 
 // NewFileTreeViewModel creates a new view object attached the the global [gocui] screen object.
-func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (treeViewModel *FileTreeViewModel, err error) {
-	treeViewModel = new(FileTreeViewModel)
+func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree, cache filetree.TreeCache) (treeViewModel *FileTree, err error) {
+	treeViewModel = new(FileTree)
 
 	// populate main fields
 	treeViewModel.ShowAttributes = viper.GetBool("filetree.show-attributes")
@@ -66,13 +66,13 @@ func NewFileTreeViewModel(tree *filetree.FileTree, refTrees []*filetree.FileTree
 }
 
 // Setup initializes the UI concerns within the context of a global [gocui] view object.
-func (vm *FileTreeViewModel) Setup(lowerBound, height int) {
+func (vm *FileTree) Setup(lowerBound, height int) {
 	vm.bufferIndexLowerBound = lowerBound
 	vm.refHeight = height
 }
 
 // height returns the current height and considers the header
-func (vm *FileTreeViewModel) height() int {
+func (vm *FileTree) height() int {
 	if vm.ShowAttributes {
 		return vm.refHeight - 1
 	}
@@ -80,24 +80,24 @@ func (vm *FileTreeViewModel) height() int {
 }
 
 // bufferIndexUpperBound returns the current upper bounds for the view
-func (vm *FileTreeViewModel) bufferIndexUpperBound() int {
+func (vm *FileTree) bufferIndexUpperBound() int {
 	return vm.bufferIndexLowerBound + vm.height()
 }
 
 // IsVisible indicates if the file tree view pane is currently initialized
-func (vm *FileTreeViewModel) IsVisible() bool {
+func (vm *FileTree) IsVisible() bool {
 	return vm != nil
 }
 
 // ResetCursor moves the cursor back to the top of the buffer and translates to the top of the buffer.
-func (vm *FileTreeViewModel) ResetCursor() {
+func (vm *FileTree) ResetCursor() {
 	vm.TreeIndex = 0
 	vm.bufferIndex = 0
 	vm.bufferIndexLowerBound = 0
 }
 
 // SetTreeByLayer populates the view model by stacking the indicated image layer file trees.
-func (vm *FileTreeViewModel) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error {
+func (vm *FileTree) SetTreeByLayer(bottomTreeStart, bottomTreeStop, topTreeStart, topTreeStop int) error {
 	if topTreeStop > len(vm.RefTrees)-1 {
 		return fmt.Errorf("invalid layer index given: %d of %d", topTreeStop, len(vm.RefTrees)-1)
 	}
@@ -126,7 +126,7 @@ func (vm *FileTreeViewModel) SetTreeByLayer(bottomTreeStart, bottomTreeStop, top
 }
 
 // doCursorUp performs the internal view's buffer adjustments on cursor up. Note: this is independent of the gocui buffer.
-func (vm *FileTreeViewModel) CursorUp() bool {
+func (vm *FileTree) CursorUp() bool {
 	if vm.TreeIndex <= 0 {
 		return false
 	}
@@ -141,7 +141,7 @@ func (vm *FileTreeViewModel) CursorUp() bool {
 }
 
 // doCursorDown performs the internal view's buffer adjustments on cursor down. Note: this is independent of the gocui buffer.
-func (vm *FileTreeViewModel) CursorDown() bool {
+func (vm *FileTree) CursorDown() bool {
 	if vm.TreeIndex >= vm.ModelTree.VisibleSize() {
 		return false
 	}
@@ -157,7 +157,7 @@ func (vm *FileTreeViewModel) CursorDown() bool {
 }
 
 // CursorLeft moves the cursor up until we reach the Parent Node or top of the tree
-func (vm *FileTreeViewModel) CursorLeft(filterRegex *regexp.Regexp) error {
+func (vm *FileTree) CursorLeft(filterRegex *regexp.Regexp) error {
 	var visitor func(*filetree.FileNode) error
 	var evaluator func(*filetree.FileNode) bool
 	var dfsCounter, newIndex int
@@ -208,7 +208,7 @@ func (vm *FileTreeViewModel) CursorLeft(filterRegex *regexp.Regexp) error {
 }
 
 // CursorRight descends into directory expanding it if needed
-func (vm *FileTreeViewModel) CursorRight(filterRegex *regexp.Regexp) error {
+func (vm *FileTree) CursorRight(filterRegex *regexp.Regexp) error {
 	node := vm.getAbsPositionNode(filterRegex)
 	if node == nil {
 		return nil
@@ -240,7 +240,7 @@ func (vm *FileTreeViewModel) CursorRight(filterRegex *regexp.Regexp) error {
 }
 
 // PageDown moves to next page putting the cursor on top
-func (vm *FileTreeViewModel) PageDown() error {
+func (vm *FileTree) PageDown() error {
 	nextBufferIndexLowerBound := vm.bufferIndexLowerBound + vm.height()
 	nextBufferIndexUpperBound := nextBufferIndexLowerBound + vm.height()
 
@@ -266,7 +266,7 @@ func (vm *FileTreeViewModel) PageDown() error {
 }
 
 // PageUp moves to previous page putting the cursor on top
-func (vm *FileTreeViewModel) PageUp() error {
+func (vm *FileTree) PageUp() error {
 	nextBufferIndexLowerBound := vm.bufferIndexLowerBound - vm.height()
 	nextBufferIndexUpperBound := nextBufferIndexLowerBound + vm.height()
 
@@ -291,7 +291,7 @@ func (vm *FileTreeViewModel) PageUp() error {
 }
 
 // getAbsPositionNode determines the selected screen cursor's location in the file tree, returning the selected FileNode.
-func (vm *FileTreeViewModel) getAbsPositionNode(filterRegex *regexp.Regexp) (node *filetree.FileNode) {
+func (vm *FileTree) getAbsPositionNode(filterRegex *regexp.Regexp) (node *filetree.FileNode) {
 	var visitor func(*filetree.FileNode) error
 	var evaluator func(*filetree.FileNode) bool
 	var dfsCounter int
@@ -322,7 +322,7 @@ func (vm *FileTreeViewModel) getAbsPositionNode(filterRegex *regexp.Regexp) (nod
 }
 
 // ToggleCollapse will collapse/expand the selected FileNode.
-func (vm *FileTreeViewModel) ToggleCollapse(filterRegex *regexp.Regexp) error {
+func (vm *FileTree) ToggleCollapse(filterRegex *regexp.Regexp) error {
 	node := vm.getAbsPositionNode(filterRegex)
 	if node != nil && node.Data.FileInfo.IsDir {
 		node.Data.ViewInfo.Collapsed = !node.Data.ViewInfo.Collapsed
@@ -331,7 +331,7 @@ func (vm *FileTreeViewModel) ToggleCollapse(filterRegex *regexp.Regexp) error {
 }
 
 // ToggleCollapseAll will collapse/expand the all directories.
-func (vm *FileTreeViewModel) ToggleCollapseAll() error {
+func (vm *FileTree) ToggleCollapseAll() error {
 	vm.CollapseAll = !vm.CollapseAll
 
 	visitor := func(curNode *filetree.FileNode) error {
@@ -352,18 +352,18 @@ func (vm *FileTreeViewModel) ToggleCollapseAll() error {
 }
 
 // ToggleCollapse will collapse/expand the selected FileNode.
-func (vm *FileTreeViewModel) ToggleAttributes() error {
+func (vm *FileTree) ToggleAttributes() error {
 	vm.ShowAttributes = !vm.ShowAttributes
 	return nil
 }
 
 // ToggleShowDiffType will show/hide the selected DiffType in the filetree pane.
-func (vm *FileTreeViewModel) ToggleShowDiffType(diffType filetree.DiffType) {
+func (vm *FileTree) ToggleShowDiffType(diffType filetree.DiffType) {
 	vm.HiddenDiffTypes[diffType] = !vm.HiddenDiffTypes[diffType]
 }
 
 // Update refreshes the state objects for future rendering.
-func (vm *FileTreeViewModel) Update(filterRegex *regexp.Regexp, width, height int) error {
+func (vm *FileTree) Update(filterRegex *regexp.Regexp, width, height int) error {
 	vm.refWidth = width
 	vm.refHeight = height
 
@@ -411,7 +411,7 @@ func (vm *FileTreeViewModel) Update(filterRegex *regexp.Regexp, width, height in
 }
 
 // Render flushes the state objects (file tree) to the pane.
-func (vm *FileTreeViewModel) Render() error {
+func (vm *FileTree) Render() error {
 	treeString := vm.ViewTree.StringBetween(vm.bufferIndexLowerBound, vm.bufferIndexUpperBound(), vm.ShowAttributes)
 	lines := strings.Split(treeString, "\n")
 
diff --git a/runtime/ui/viewmodel/filetree_viewmodel_test.go b/runtime/ui/viewmodel/filetree_test.go
similarity index 98%
rename from runtime/ui/viewmodel/filetree_viewmodel_test.go
rename to runtime/ui/viewmodel/filetree_test.go
index 3d92a67..c90f0d7 100644
--- a/runtime/ui/viewmodel/filetree_viewmodel_test.go
+++ b/runtime/ui/viewmodel/filetree_test.go
@@ -73,7 +73,7 @@ func assertTestData(t *testing.T, actualBytes []byte) {
 	helperCheckDiff(t, expectedBytes, actualBytes)
 }
 
-func initializeTestViewModel(t *testing.T) *FileTreeViewModel {
+func initializeTestViewModel(t *testing.T) *FileTree {
 	result := docker.TestAnalysisFromArchive(t, "../../../.data/test-docker-image.tar")
 
 	cache := filetree.NewFileTreeCache(result.RefTrees)
@@ -95,7 +95,7 @@ func initializeTestViewModel(t *testing.T) *FileTreeViewModel {
 	return vm
 }
 
-func runTestCase(t *testing.T, vm *FileTreeViewModel, width, height int, filterRegex *regexp.Regexp) {
+func runTestCase(t *testing.T, vm *FileTree, width, height int, filterRegex *regexp.Regexp) {
 	err := vm.Update(filterRegex, width, height)
 	if err != nil {
 		t.Errorf("failed to update viewmodel: %v", err)