diff --git a/Gruntfile.js b/Gruntfile.js
index b6474182a..b39256d88 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -165,6 +165,7 @@ module.exports = function(grunt) {
                     "packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js",
                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette.js",
                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js",
+                    "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js",
                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js",
                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
index f67a3de9a..7567ada3a 100755
--- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
@@ -583,7 +583,8 @@
             "nodeHelp": "Node Help",
             "none":"None",
             "arrayItems": "__count__ items",
-            "showTips":"You can open the tips from the settings panel"
+            "showTips":"You can open the tips from the settings panel",
+            "outline": "Outline"
         },
         "config": {
             "name": "Configuration nodes",
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
new file mode 100644
index 000000000..82d3ce1c0
--- /dev/null
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js
@@ -0,0 +1,426 @@
+RED.sidebar.info.outliner = (function() {
+
+    var treeList;
+
+    var flowList;
+    var subflowList;
+    var globalConfigNodes;
+
+    var objects = {};
+
+    var objectBacklog = {};
+
+    function getFlowData(project) {
+        var flowData = [
+            {
+                label: "Flows",
+                expanded: true,
+                children: [
+                    {
+                        id: "__global__",
+                        label: "Global",
+                        children: []
+                    }
+                ]
+            },
+            {
+                label: "Subflows",
+                children: []
+            }
+        ]
+        flowList = flowData[0];
+        subflowList = flowData[1];
+        globalConfigNodes = flowList.children[0];
+
+        if (project) {
+            flowData = [
+                {
+                    element: getProjectLabel(project),
+                    icon: "fa fa-archive",
+                    children: flowData,
+                    expanded: true
+                }
+            ]
+        }
+        return flowData;
+    }
+
+    function getProjectLabel(p) {
+        var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
+        var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
+        contentDiv.text(p.name);
+        var controls = $('<div>',{class:"red-ui-info-outline-item-controls"}).appendTo(div);
+        var editProjectButton = $('<button class="red-ui-button red-ui-button-small" style="position:absolute;right:2px;"><i class="fa fa-ellipsis-h"></i></button>')
+            .appendTo(controls)
+            .on("click", function(evt) {
+                evt.preventDefault();
+                RED.projects.editProject();
+            });
+        RED.popover.tooltip(editProjectButton,RED._('sidebar.project.showProjectSettings'));
+        return div;
+    }
+
+    var empties = {};
+    function getEmptyItem(id) {
+        var item = {
+            empty: true,
+            element: $('<div class="red-ui-info-outline-item red-ui-info-outline-item-empty">').text("empty")
+        }
+        empties[id] = item;
+        return item;
+    }
+
+    function getNodeLabelText(n) {
+        var label = n.name || n.id;
+        if (n._def.label) {
+            try {
+                label = (typeof n._def.label === "function" ? n._def.label.call(n) : n._def.label)||"";
+            } catch(err) {
+                console.log("Definition error: "+type+".label",err);
+            }
+        }
+        return label;
+    }
+
+    function getNodeLabel(n) {
+        var div = $('<div>',{class:"red-ui-info-outline-item"});
+        var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
+        if (n.type === "group") {
+            div.addClass('red-ui-info-outline-item-group')
+        } else {
+            var colour = RED.utils.getNodeColor(n.type,n._def);
+            nodeDiv.css('backgroundColor',colour);
+        }
+        var icon_url = RED.utils.getNodeIcon(n._def,n);
+        var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
+        RED.utils.createIconElement(icon_url, iconContainer, false);
+        var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
+        var labelText = getNodeLabelText(n);
+        var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
+        if (labelText) {
+            label.text(labelText)
+        } else {
+            label.html("&nbsp;")
+        }
+
+        addControls(n, div);
+
+        return div;
+    }
+
+    function getFlowLabel(n) {
+        var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
+        var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
+        contentDiv.text(typeof n === "string"? n : n.label);
+        addControls(n, div);
+        return div;
+    }
+
+    function getSubflowLabel(n) {
+
+        var div = $('<div>',{class:"red-ui-info-outline-item"});
+        var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div);
+        if (n.type === "group") {
+            div.addClass('red-ui-info-outline-item-group')
+        } else {
+            var colour = RED.utils.getNodeColor(n.type,n._def);
+            nodeDiv.css('backgroundColor',colour);
+        }
+        var icon_url = RED.utils.getNodeIcon(n._def,n);
+        var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
+        RED.utils.createIconElement(icon_url, iconContainer, false);
+        var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div);
+        var labelText = getNodeLabelText(n);
+        var label = $('<div>',{class:"red-ui-search-result-node-label red-ui-info-outline-item-label"}).appendTo(contentDiv);
+        if (labelText) {
+            label.text(labelText)
+        } else {
+            label.html("&nbsp;")
+        }
+
+        addControls(n, div);
+
+        return div;
+
+
+        // var div = $('<div>',{class:"red-ui-info-outline-item red-ui-info-outline-item-flow"});
+        // var contentDiv = $('<div>',{class:"red-ui-search-result-description red-ui-info-outline-item-label"}).appendTo(div);
+        // contentDiv.text(n.name || n.id);
+        // addControls(n, div);
+        // return div;
+    }
+
+    function addControls(n,div) {
+        if (n.type === 'group') {
+            return;
+        }
+        var controls = $('<div>',{class:"red-ui-info-outline-item-controls red-ui-info-outline-item-hover-controls"}).appendTo(div);
+        if (n._def.button) {
+            $('<button type="button" class="red-ui-info-outline-item-control-action red-ui-button red-ui-button-small"><i class="fa fa-toggle-right"></i></button>').appendTo(controls).on("click",function(evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+                RED.view.clickNodeButton(n);
+            })
+        }
+
+
+        if (n.type !== 'group') {
+            $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-eye"></i></button>').appendTo(controls).on("click",function(evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+                RED.view.reveal(n.id);
+            })
+        }
+        if (n.type !== 'group' && n.type !== 'subflow') {
+            $('<button type="button" class="red-ui-info-outline-item-control-disable red-ui-button red-ui-button-small"><i class="fa fa-circle-thin"></i><i class="fa fa-ban"></i></button>').appendTo(controls).on("click",function(evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+                if (n.type === 'tab') {
+                    if (n.disabled) {
+                        RED.workspaces.enable(n.id)
+                    } else {
+                        RED.workspaces.disable(n.id)
+                    }
+                } else {
+                    // TODO: this ought to be a utility function in RED.nodes
+                    var historyEvent = {
+                        t: "edit",
+                        node: n,
+                        changed: n.changed,
+                        changes: {
+                            d: n.d
+                        },
+                        dirty:RED.nodes.dirty()
+                    }
+                    if (n.d) {
+                        delete n.d;
+                    } else {
+                        n.d = true;
+                    }
+                    n.dirty = true;
+                    n.changed = true;
+                    RED.events.emit("nodes:change",n);
+                    RED.nodes.dirty(true)
+                    RED.view.redraw();
+                }
+            });
+        } else {
+            $('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
+        }
+        controls.find("button").on("dblclick", function(evt) {
+            evt.preventDefault();
+            evt.stopPropagation();
+        })
+    }
+
+    function onProjectLoad(activeProject) {
+        var newFlowData = getFlowData(activeProject);
+        treeList.treeList('data',newFlowData);
+    }
+
+    function build() {
+            var container = $("<div>", {class:"red-ui-info-outline"}).css({'height': '400px'});
+            var toolbar = $("<div>", {class:"red-ui-info-outline-toolbar"}).appendTo(container);
+
+            var searchInput = $('<input type="text">').appendTo(toolbar).searchBox({
+                delay: 100,
+                change: function() {
+                    var val = $(this).val().trim().toLowerCase();
+                    if (val) {
+                        var c = treeList.treeList('filter',function(item) {
+                            if (item.depth === 0) {
+                                return true;
+                            }
+                            if (item.id &&  objects[item.id]) {
+                                var l = ((objects[item.id].type||"")+" "+(objects[item.id].name||"")+" "+(objects[item.id].id||"")+" "+(objects[item.id].label||"")).toLowerCase();
+                                var isMatch = l.indexOf(val) > -1;
+                                if (isMatch) {
+                                    return true;
+                                }
+                            }
+                            return false;
+                        })
+                    } else {
+                        treeList.treeList('filter',null);
+
+                    }
+                }
+            });
+
+            treeList = $("<div>").css({width: "100%"}).appendTo(container).treeList({
+                data:getFlowData()
+            })
+            // treeList.on('treelistselect', function(e,item) {
+            //     console.log(item)
+            //     RED.view.reveal(item.id);
+            // })
+            // treeList.treeList('data',[ ... ] )
+            treeList.on('treelistconfirm', function(e,item) {
+                var node = RED.nodes.node(item.id);
+                if (node) {
+                    if (node._def.category === "config") {
+                        RED.editor.editConfig("", node.type, node.id);
+                    } else {
+                        RED.editor.edit(node);
+                    }
+                }
+            })
+
+            RED.events.on("projects:load", onProjectLoad)
+
+            RED.events.on("flows:add", onFlowAdd)
+            RED.events.on("flows:remove", onObjectRemove)
+            RED.events.on("flows:change", onFlowChange)
+            RED.events.on("flows:reorder", onFlowsReorder)
+
+            RED.events.on("subflows:add", onSubflowAdd)
+            RED.events.on("subflows:remove", onObjectRemove)
+            RED.events.on("subflows:change", onSubflowChange)
+
+            RED.events.on("nodes:add",onNodeAdd);
+            RED.events.on("nodes:remove",onObjectRemove);
+            RED.events.on("nodes:change",onNodeChange);
+
+            RED.events.on("groups:add",onNodeAdd);
+            RED.events.on("groups:remove",onObjectRemove);
+            RED.events.on("groups:change",onNodeChange);
+
+            RED.events.on("view:selection-changed", onSelectionChanged);
+
+
+            // ["links","nodes","flows","subflows","groups"].forEach(function(t) {
+            //     ["add","remove","change"].forEach(function(v) {
+            //         RED.events.on(t+":"+v, function(n) { console.log(t+":"+v,n)})
+            //     })
+            // })
+            // RED.events.on("workspace:clear", function() { console.log("workspace:clear")})
+
+            return container;
+    }
+    function onFlowAdd(ws) {
+        objects[ws.id] = {
+            id: ws.id,
+            element: getFlowLabel(ws),
+            children:[getEmptyItem(ws.id)],
+            deferBuild: true,
+            icon: "red-ui-icons red-ui-icons-flow"
+        }
+        flowList.treeList.addChild(objects[ws.id])
+        objects[ws.id].element.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
+        objects[ws.id].treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!ws.disabled)
+
+
+    }
+    function onFlowChange(n) {
+        var existingObject = objects[n.id];
+        existingObject.element.find(".red-ui-info-outline-item-label").text(n.label || n.id);
+        existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
+        existingObject.treeList.container.toggleClass("red-ui-info-outline-item-disabled", !!n.disabled)
+    }
+    function onFlowsReorder(order) {
+        var indexMap = {};
+        order.forEach(function(id,index) {
+            indexMap[id] = index;
+        })
+
+        flowList.treeList.sortChildren(function(A,B) {
+            if (A.id === "__global__") { return -1 }
+            if (B.id === "__global__") { return 1 }
+            return indexMap[A.id] - indexMap[B.id]
+        })
+    }
+    function onSubflowAdd(sf) {
+        objects[sf.id] = {
+            id: sf.id,
+            element: getSubflowLabel(sf),
+            children:[getEmptyItem(sf.id)],
+            deferBuild: true
+        }
+        subflowList.treeList.addChild(objects[sf.id])
+    }
+    function onSubflowChange(n) {
+        var existingObject = objects[n.id];
+
+        existingObject.treeList.replaceElement(getSubflowLabel(n));
+        // existingObject.element.find(".red-ui-info-outline-item-label").text(n.name || n.id);
+
+    }
+
+    function onNodeChange(n) {
+        var existingObject = objects[n.id];
+        var parent = n.g||n.z;
+
+        var nodeLabelText = getNodeLabelText(n);
+        if (nodeLabelText) {
+            existingObject.element.find(".red-ui-info-outline-item-label").text(nodeLabelText);
+        } else {
+            existingObject.element.find(".red-ui-info-outline-item-label").html("&nbsp;");
+        }
+
+        if (parent !== existingObject.parent.id) {
+            existingObject.treeList.remove();
+            if (!parent) {
+                globalConfigNodes.treeList.addChild(existingObject);
+            } else {
+                objects[parent].treeList.addChild(existingObject)
+            }
+        }
+        existingObject.element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
+    }
+    function onObjectRemove(n) {
+        var existingObject = objects[n.id];
+        existingObject.treeList.remove();
+        delete objects[n.d]
+        var parent = existingObject.parent;
+        if (parent.children.length === 0) {
+            parent.treeList.addChild(getEmptyItem(parent.id));
+        }
+    }
+
+    function onNodeAdd(n) {
+        objects[n.id] = {
+            id: n.id,
+            element: getNodeLabel(n)
+        }
+        if (n.type === "group") {
+            objects[n.id].children = [];
+            objects[n.id].deferBuild = true;
+        }
+        var parent = n.g||n.z;
+        if (parent) {
+            if (objects[parent]) {
+                if (empties[parent]) {
+                    empties[parent].treeList.remove();
+                    delete empties[parent];
+                }
+                objects[parent].treeList.addChild(objects[n.id])
+            } else {
+                // The parent hasn't been added yet
+                console.log("missing",parent)
+            }
+        } else {
+            // No parent - add to Global flow list
+            globalConfigNodes.treeList.addChild(objects[n.id])
+        }
+        objects[n.id].element.toggleClass("red-ui-info-outline-item-disabled", !!n.d)
+    }
+
+    function onSelectionChanged(selection) {
+        // treeList.treeList('clearSelection');
+        // console.log(selection);
+        if (selection.nodes) {
+            selection.nodes.forEach(function(n) {
+                // console.log("..",n.id);
+                treeList.treeList('show',n.id);
+                if (objects[n.id].treeList) {
+                    objects[n.id].treeList.select(true);
+                }
+
+            });
+        }
+    }
+
+    return {
+        build: build
+    }
+})();
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
index 39683e41e..c6e9aec52 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
@@ -18,6 +18,7 @@ RED.sidebar.info = (function() {
     var content;
     var sections;
     var propertiesSection;
+    var outlinerSection;
     var infoSection;
     var helpSection;
     var tipBox;
@@ -39,6 +40,13 @@ RED.sidebar.info = (function() {
             container: stackContainer
         }).hide();
 
+        outlinerSection = sections.add({
+            title: RED._("sidebar.info.outline"),
+            collapsible: true
+        })
+        outlinerSection.expand();
+        RED.sidebar.info.outliner.build().appendTo(outlinerSection.content);
+
         propertiesSection = sections.add({
             title: RED._("sidebar.info.info"),
             collapsible: true
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
index a9c1c9500..7e3d72b89 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
@@ -859,7 +859,9 @@ RED.utils = (function() {
     }
 
     function getNodeIcon(def,node) {
-        if (def.category === 'config') {
+        if (node && node.type === 'group') {
+            return "font-awesome/fa-object-group"
+        } else if (def.category === 'config') {
             return RED.settings.apiRootUrl+"icons/node-red/cog.svg"
         } else if (node && node.type === 'tab') {
             return RED.settings.apiRootUrl+"icons/node-red/subflow.svg"
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/search.scss b/packages/node_modules/@node-red/editor-client/src/sass/search.scss
index 0ec8b6525..273793896 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/search.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/search.scss
@@ -87,6 +87,8 @@
     }
     .red-ui-palette-icon {
         width: 15px;
+        position:relative;
+        left: -1px;
     }
     .red-ui-search-result-description {
         margin-left:28px;
@@ -153,7 +155,7 @@
     width: 30px;
     float:left;
     height: 25px;
-    border-radius: 5px;
+    border-radius: 3px;
     border: 1px solid $node-border;
     background-position: 5% 50%;
     background-repeat: no-repeat;
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
index bc72f7532..1605c9c76 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/tab-info.scss
@@ -279,3 +279,173 @@ div.red-ui-info-table {
     border-radius: 4px;
     padding: 2px 4px 2px;
 }
+
+.red-ui-help-search {
+    border-bottom: 1px solid $secondary-border-color;
+}
+
+
+.red-ui-info-outline {
+    display: flex;
+    flex-direction: column;
+
+    .red-ui-treeList {
+        flex-grow: 1;
+    }
+
+    .red-ui-treeList-container,.red-ui-editableList-border {
+        border: none;
+        border-radius: 0;
+    }
+    .red-ui-treeList-label {
+        font-size: 13px;
+        padding: 2px 0;
+        overflow: hidden;
+    }
+    .red-ui-info-outline-item {
+        display: inline-block;
+        padding: 0;
+        font-size: 13px;
+        border: none;
+        .red-ui-palette-icon-fa {
+            position: relative;
+            top: 1px;
+            left: 0px;
+        }
+        &:hover {
+            background: inherit
+        }
+
+        &.red-ui-info-outline-item-flow {
+            .red-ui-search-result-description {
+                margin-left: 4px;
+            }
+        }
+        &.red-ui-info-outline-item-group .red-ui-search-result-node {
+            background: none;
+            border-color: transparent;
+            .red-ui-palette-icon-container {
+                background: none;
+            }
+            .red-ui-palette-icon-fa {
+                color: $secondary-text-color;
+                font-size: 18px;
+            }
+        }
+        &.red-ui-info-outline-item-empty {
+            font-style: italic;
+            color: $form-placeholder-color;
+        }
+    }
+
+    .red-ui-search-result-node {
+        width: 24px;
+        height: 20px;
+        margin-top: 1px;
+    }
+
+    .red-ui-palette-icon-container {
+        width: 24px;
+    }
+    .red-ui-palette-icon {
+        width: 20px;
+    }
+    .red-ui-search-result-description {
+        margin-left: 32px;
+        line-height: 22px;
+        white-space: nowrap;
+    }
+    .red-ui-search-result-node-label {
+        color: $secondary-text-color;
+    }
+}
+.red-ui-info-outline-item-control-spacer {
+    display: inline-block;
+    width: 23px;
+}
+
+.red-ui-info-outline-item-controls {
+    position: absolute;
+    top:0;
+    bottom: 0;
+    right: 0px;
+    padding: 2px 0 0 1px;
+    text-align: right;
+    background: $list-item-background;
+
+    .red-ui-treeList-label:hover & {
+        background: $list-item-background-hover;
+    }
+    .red-ui-treeList-label.selected & {
+        background: $list-item-background-selected;
+    }
+
+
+    &.red-ui-info-outline-item-hover-controls button {
+        min-width: 23px;
+    }
+
+    .red-ui-treeList-label:not(:hover) &.red-ui-info-outline-item-hover-controls {
+        button {
+            border: none;
+            background: none;
+        }
+    }
+    .red-ui-info-outline-item-control-reveal,
+    .red-ui-info-outline-item-control-action {
+        display: none;
+    }
+    .red-ui-treeList-label:hover & {
+        .red-ui-info-outline-item-control-reveal,
+        .red-ui-info-outline-item-control-action {
+            display: inline-block;
+        }
+    }
+
+    .fa-ban {
+        display: none;
+    }
+    .red-ui-info-outline-item.red-ui-info-outline-item-disabled & {
+        .fa-ban {
+            display: inline-block;
+        }
+        .fa-circle-thin {
+            display: none;
+        }
+    }
+    button {
+        margin-right: 3px
+    }
+}
+.red-ui-info-outline-item-disabled {
+    .red-ui-search-result-node {
+        opacity: 0.4;
+    }
+    .red-ui-info-outline-item-label {
+        font-style: italic;
+        color: $secondary-text-color-disabled;
+    }
+    .red-ui-icons-flow {
+        opacity: 0.4;
+    }
+}
+.red-ui-icons {
+    display: inline-block;
+    width: 18px;
+    &:before {
+        white-space: pre;
+        content: ' '
+    }
+
+}
+
+.red-ui-icons-flow {
+    background-image: url('images/subflow_tab.svg');
+    background-repeat: no-repeat;
+    background-size: contain;
+    filter: brightness(2.5);
+}
+
+.red-ui-info-outline-toolbar {
+    border-bottom: 1px solid $secondary-border-color;
+}