---
title: Comparison between Dashboard 2 and uibuilder
description: |
  UIBUILDER has a significantly different design philosophy to Node-RED's Dashboard 2.
  This page examines some of the key differences, their potential impacts and different workflows.
created: 2024-06-21 10:14:56
updated: 2024-08-29 13:44:42
---

Please do not use this comparison table to criticize one approach or the other, both approaches are deliberately different. Giving greater choice and flexibility for Node-RED users. Also note that I am much more familiar with UIBUIDER as its main author than I am of Dashboard 2.0, updates and corrections are always most welcome.

The following table is not in any specific order of importance.

| Capability                                                   | <img src="./images/node-blue.svg" style="width:25px;vertical-align: middle;" /> [UIBUILDER](https://flows.nodered.org/node/node-red-contrib-uibuilder) | <img src="https://dashboard.flowfuse.com/logo.png" alt="Node-RED Dashboard 2.0 Logo" style="zoom:5%;vertical-align: middle;" /> [Dashboard 2.0](https://flows.nodered.org/node/@flowfuse/node-red-dashboard) |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Low-code approaches                                          | Has a number of "no-code" nodes.<br />The no-code nodes output low-code standard data allowing further low-code manipulation where a no-code element does not quite match the requirements.<br />The low-code features take the form of a standardised data schema that describes the HTML UI. This allows an effectively unlimited ability to build anything that HTML/CSS supports. The outputs can be "hydrated" into HTML both in the browser and in Node-RED.<br />There is no visual page layout tool available. However, note that you can use 3rd-party generic page building tools with uibuilder since it all works with standard HTML/CSS.<br />The [default CSS](/client-docs/uib-brand-css.md) does provide for similar standardised layouts as D2. Customised [grid](https://grid.layoutit.com/) and [flexbox](https://loading.io/flexbox/) layouts can be designed using 3rd-party tools. | Low-code is provided by having a pre-defined node for each widget. *This approach is undoubtedly simpler for beginners or users without any HTML knowledge*. However, it tends to limit the flexibility for more complex layouts.<br />In addition, some [standardised page layouts](https://dashboard.flowfuse.com/layouts/) are available (grid, fixed and notebook) but unlike D1, there is no visual page layout. |
| **Data cache**.<br />New clients may connect to Node-RED at any point, new (or reloaded) connections commonly will need to get the latest data so this requires a cache in Node-RED. | Uses the optional `uib-cache` node. Wired up to the control msg output of the `uibuilder` node to detect (re)connections. Caching is extremely flexible and can be further filtered by user, page, topic, etc. Cache data can also be retained across Node-RED restarts if required due to use of Node-RED's standard context stores. The cache node can deal with no-/low-code UI data and other data.<br />In addition, dynamic changes to pages can easily be captured and written to the static page using the `uib-save` node. Dynamic UI's can even be created by sending no-/low-code data to the `uib-html` node and then saved. | Each widget (node) has to maintain its own cache. Usage is built-in and therefore there are no options. Nodes have [2 caches](https://discourse.nodered.org/t/how-to-sync-the-full-config-between-server-and-client-side-state/89252), datastore and statestore. |
| Network disconnection handling                               | Socket.IO automatically reconnects. Uses an extending window algorithm to prevent excessive browser CPU,<br />Data would be lost during disconnection but the use of the `uib-cache` node mitigates this. Stored data can be resent on reconnection. Caution is recommended re cache sizes which could overwhelm memory if unconstrained. | Socket.IO automatically reconnects.<br />Data is lost during disconnection. Reconnection does not currently result in missing data being sent. |
| **Client-side data**.                                        | Client library uses simple `set`, `get` functions to manage client-side data. The `onChange` function allows for monitoring and action. Get and set functions can also be run from Node-RED without the need for front-end code.<br />Data can be persisted in the browser to survive reloads if required. Persisted data can be automatically reloaded if desired. | Uses [VueX](https://vuex.vuejs.org) VueJS extension library for state management.<br />Data is persisted for the current browser session. |
| **Widgets**.<br />Pre-defined UI components.                 | Has a number of pre-defined widgets, referred to as "*elements*".  They are available via the `uib-element` node.<br />They are defined using uibuilder's low-code JSON configuration data enabling them to be further enhanced by any flow before sending to the clients.<br />Some elements are also provided as W3C standard web components and so can be automatically or manually added to pages.<br />**Form and input** handling is provided via the `uibuilder.eventSend(event)` function. This includes **automatic file uploads**.<br />New elements can be provided by 3rd-party nodes.<br />uibuilder can consume W3C standard web components as well.<br />uibuilder's Library Manager allows easy management of 3rd-party libraries and components as needed and allows for updates of them without having to rebuild uibuilder.<br />[Element List](/nodes/uib-element.md). | Widgets are relatively complex VueJS components however a collection of core and contributed widgets exist.<br />The approach does require the D2 package to include a large number of 3rd-party modules however.<br />Flexibility is mostly limited by whatever configuration has been built into the node's Editor config by the author.<br />New widgets require new nodes.<br />[Widget List](https://dashboard.flowfuse.com/nodes/widgets). |
| Custom web elements                                          | Allows for any level of custom web page. The base page is set using a template but can be fully edited as needed.<br />Additionally, widgets and/or HTML and/or Markdown can easily be sent to or loaded into any page. | Custom web code requires the `ui_template` node. This can load custom code to the head and body but the structure of the page cannot be altered. |
| **User management**.<br />Note that socketId is not stable and will change if the browser tab or client device enters sleep. | Has *socketId, ClientID, tab id, IP Address, and page name* data available to all responses. Can optionally include rich client data in Node-RED output messages.<br />ExpressJS & Socket.IO middleware available for additional user and session interactions. | By default, only has *socketId and socketIp*. Requires additional plugins for richer data. |
| User/client specific information                             | Data sent to a uibuilder node will be *automatically filtered* by *socketId, clientID and page name* if provided. Otherwise is broadcast to all clients connected to that uibuilder node.<br />Some limited provision for dedicated Socket.IO "rooms" also available - this also allows user-to-user comms. | Data is sent to individual ui widget nodes. It is automatically filtered by `msg._client` if provided.<br />No known provision for using rooms. None for client-to-client comms (without using a manual flow). |
| Handling externally authenticated clients                    | Integrated recognition of authenticated client HTTP headers from most proxy integrations including Authelia & others. Also for FlowFuse and CloudFlare access authentications. Automatically adds `msg._client` to messages from the authenticated client.<br />Also provides `socketIoHeaders`, `clientDetails`, `msgReceived`, and `msgSending` "hook" functions to allow fine-grained control & monitoring. | Plugin modules available for FlowFuse, Cloudflare Access, and Authelia. Adds `msg._client` to messages for authenticated client connections. |
| Sending data from Node-RED to clients                        | All messages go via the `uibuilder` node. Segmented of flows should use core link nodes or the uib-sender node.<br />Messages are filtered by *socketId, clientID and page name* if that data is provided.<br />There are 4 options, see [Easy UI updates](http://127.0.0.1:1880/red/uibuilder/docs/#/using/easy-ui-updates) for details:<ol><li>*The custom `uib-topic` attribute on any HTML tag* will auto-process incoming data.</li><li>*The custom `<uib-var>` component* also auto-processes data and has some additional rendering options such as json, table and list.</li><li>*Front-end JavaScript code* can listen for incoming data manually using the `uibuilder.onChange('msg', (msg)=>{...})` or `uibuilder.onTopic('topicname', (msg)=>{...})` functions.</li><li>No-code and low-code nodes can directly update identifiable on-page elements.</li></ol> | Messages are sent to individual ui widget nodes.<br />Messages can be manually processed using a `ui-template` node utilising the `this.$socket.on()` function.<br />Custom nodes may require use of a `watch` handler. [Ref](https://discourse.nodered.org/t/dashboard-2-radio-group/89495) |
| Sending data from clients to Node-RED                        | Front end code can use either the `uibuilder.send({...})` or `uibuilder.eventSend(event)` functions to return data to Node-RED. `eventSend` is specifically designed to be attached to any HTML event but notably input tags, it gathers detailed information about any user input and grabs surrounding HTML Form input data if the event happens within a form. `eventSend` can be used with no-/low-code nodes without the need for specific front-end coding.<br />Some built-in uibuilder functions also automatically send data to Node-RED.<br />No-code elements will automatically return data to Node-RED where that makes sense.<br />Received messages are output from the top port of the uibuilder node (except for a `uib-sender` node configured for automatic return). | Dashboard widgets that accept input will automatically return data to the widget node.<br />Custom `ui_template` code can use [`this.send(msg)`](https://dashboard.flowfuse.com/nodes/widgets/ui-template.html#sending-data). |
| **Client events**.<br />Background events triggered by a client such as changing pages. | Client events are received at port #2 of a uibuilder node as control messages. *Socket.IO connect/disconnect*, *cache replay/clear*, *page visibility change*, and *router page* change are the main built-in events. Custom events allowed by allowing control messages to be sent. Front end `uibuilder.eventSend(event)` function allows HTML events with standard content to be returned as standard messages. | `ui-events` node is required. `$pageView`/`$pageLeave`  are fired when a route page changes. |
| Web page layouts                                             | No pre-defined layouts. An optional, provided CSS file contains a base configuration for HTML5 style general layouts along with some helper classes for grid, flex and other more granular layouts.<br />Because uibuilder uses standard HTML, 3rd-party layout editors can be used to create custom layouts.<br />An [example page layout (blog-style grid layout)](https://discourse.nodered.org/t/uibuilder-example-web-page-layout-typical-blog-style/90176) is shared in the Node-RED forum, it demonstrates how simple it is to create a good layout with minimal HTML/CSS. | Has [3 layout types](https://dashboard.flowfuse.com/layouts/): grid, fixed and notebook. Layout configuration follows Dashboard 1 controls in the Node-RED Editor. |
| Markdown content                                             | Allows the use of the Markdown-IT library as an external (optional) resource allowing library updates separate to uibuilder. Also allows for any Markdown-IT *plugins*. Could easily be extended in the future to use alternative libraries.<br />Lots of ways to support static (file-based) and dynamic (msg or code-based) Markdown content.<br />Message and other dynamic content can be included in Markdown text by using the the `<uib-var>` web component.<br />The Markdown-IT library can be loaded via a message from Node-RED or included in low-code output.<br />The optional front-end router library (for creating single-page apps) also fully supports Markdown in the same way. Allowing UIBUILDER to be used as a content management system. | Embeds the Marked library. Updates require a new version to be released. Mermaid chart plugin included but no direct provision for others.<br />Markdown content limited to the `ui-markdown` node. Message content can be included in Markdown content using Mustache style `{{ ... }}` markup. |
| **Front-end frameworks**.<br />Typically, large collections of code that support the dynamic management of front-end UI's. | Allows any or no framework. No framework is required to work but any can be used if desired. Note that some frameworks require pre-definition of pages (or lots of dynamic processing as in the case of Dashboard) and so some uibuilder features may not be compatible. | Fixed at using VueJS v3 with VueX and Vuetify.               |
| **Front-end libraries**.<br />Additional features that run in the browser and linked to the current page. | Built-in library manager enables installation, update and removal of libraries from npm (to allow runtime use without Internet), GitHub or local (server) code. Uses standard npm tooling under the skin. Resulting URL's are all catalogued and shown.<br />Managed libraries are automatically made into Node-RED web endpoints for easy loading onto web pages. Information is provided on the most likely link URL required to use each library.<br />Library links are manually added to `.html` files or can be dynamically added using no-/low-code features.<br />Socket.IO client library is integrated into the uibuilder client library. | No management of libraries available. Any libraries must be manually included onto pages using a `ui-template` node or pre-built into core or contributed nodes.<br />For use without the Internet at runtime, libraries must be manually installed somewhere that Node-RED can serve them and the appropriate URL worked out. |
| **Application Style**<br />Single- vs Multi-Page             | *Multi-page by default*. Each `uibuilder` node defines a new front-end app that contains a minimum of a default page. Any number of static sub-folders and pages can be defined. Custom API's can also be defined for dynamic endpoints.<br />*Single-page apps (SPA) also possible* by using the built-in `uib-router` JavaScript library. Allows pseudo-pages to be defined from static files or `<template>` sections in the html file.<br />Router pages can be un/-re-loaded or hidden/shown as desired on route changes.<!-- what about data retention --> | *Single-page app* (SPA) only. (Multi-page is planned for the future). Each defined "page" is a route in the SPA.<br />Router pages unload all page widgets on route change. , They have to be reloaded if coming back to the page.<br />Note: D2 calls SPA pages "Pages" which should not be confused with actual HTML pages. |
| **SPA Routing**.<br />Creating single-page web UI's that simulate multi-page through the use of a front-end *router*. | Optional. Uses the provided `uib-router` JavaScript library. Updates require a new version of uibuilder.<br />Routes and other settings are indepentent of uibuilder. The router can actually be used without uibuilder.<br />uibuilder is a *multi-site, multi-page* creator by default that also allows SPA creation via the optional router. | Built-in. Uses the pre-integrated 3rd-party `vue-router` package. Updates require a new version of Dashboard.<br />Configuration of routes is tied to the Dashboard configuration.<br />Dashboard 2 is *an SPA* creator ~~but allows you to create multiple Dashboards.~~ Not yet available. |
| Server page routing                                          | Multiple folders & pages part of inherent design and defined as static resources in the filing system.<br />Dynamic routes are available via the routing API, defined as Node.JS module files.<br />Server-side rendering is also available.<br />The uibuilder node's `url` setting is always used as the base url. It may be altered which will rename the server folders as well as the url on re-deployment. | New static routes will eventually be definable (not yet available) by defining a new `ui-base` config node.<br />URL is currently _fixed_ as `./dashboard`. |
| **Dynamic code**<br />HTML, CSS or JS code sent to clients. As opposed to dynamic data. | Should rarely be needed since static code files are preferred, generally more performant and more secure. However, uibuilder allows HTML, Markdown, CSS and JS code to be sent when needed. It can also update static files from within Node-RED flows.<br />Static content is efficient and easily cached, reducing network overheads and improving speed. | Everything is sent dynamically from Node-RED to each connected client.<br />This results in potentially high network traffic levels & is more difficult (if at all possible) to cache. |
| Charting                                                     | No built-in chart elements. Any charting library can be used. Examples are available. | Chart.js library built-in, chart widget available.<br />D2 v1.x requires the number of chart points to be limited otherwise browser performance is impacted. |
| Custom extensions                                            | Custom extensions can be built using low-code features without the need for any knowledge of uibuilder core development and not much knowledge of Node-RED development, all they need to do is output messages containing the `msg._ui` property.<br />No examples are provided yet however. [Some documentation is available](/dev/3rd-party-extensions.md). An [example using uPlot](https://github.com/TotallyInformation/nr-uibuilder-uplot) is started but not complete.<br />However, W3C web components with uibuilder integration are preferred in any case. Several examples already exist in the form of the built-in components (uib-var, uib-meta, & apply-template) as well as external components including the [HotNipi Gauge web component](https://github.com/TotallyInformation/gauge-hotnipi) and a set of [experimental web components](https://github.com/TotallyInformation/web-components). There is also a list of some [useful components in the documentation](/client-docs/custom-components,md). <br />Web components that integrate with uibuilder only require some reusable knowledge of building web components and some knowledge of the functions in the uibuilder client library (which are [well documented](/client-docs/functions.md)).<br />Web components _do_ require some web development knowledge but do not require any specific knowledge of Node-RED or uibuilder. | Some contributed widgets already published. Some documentation [here](https://dashboard.flowfuse.com/contributing/widgets/third-party.html).<br />Reasonable knowledge of web development, Dashboard 2.0, Node-RED development and VueJS development is required ([e.g.](https://discourse.nodered.org/t/how-to-sync-the-full-config-between-server-and-client-side-state/89252)). However a starter example is available. |
| Client size & performance                                    | Typically small, efficient pages and minimal data transfer. Use of static data allows for good transparent caching.<br />Example very simple page:<br />Uncached = 17 requests, **239kB** transferred, 341kB resources, 398ms.<br />Cached = 17 requests, **5.4kB** transferred, 341kB resources, 385ms. | Relatively large and complex resource loading and data transfer required to build the page.<br />Example very simple page: <br />Uncached = 19 requests, **2.4MB** transferred, 5.1MB resources, 723ms.<br />Cached = 19 requests, **1,0MB** transferred, 5.1MB resources, 569ms |
| Server (hosting) requirements                                | A filing system required on the Node-RED server.<br />By default, `~/.node-red/uibuilder/` is used to store configuration and instance data. This can, however, be moved to any location.<br />Because the commercial FlowFuse environments have a limited filing system, installation on FlowFuse will automatically set the correct `uibRoot` folder in `settings.js`. | No filing system required, can use a virtual FS. Designed to allow use with FlowFuse environments. |
| Internet access                                              | Not required for running.<br />Library manager can install from local folders or a local repository. Or libraries can be copied into place.<br />Full documentation is available both offline and online. | Not required for running.<br />Documentation is online only. |
| Offline client use                                           | Not as yet, on the roadmap.                                  | No.                                                          |
| Installable as an app                                        | Not as yet, on the roadmap.                                  | Yes.                                                         |
| Development                                                  | Open Source, Apache 2.0 license. Mostly a single developer with support from the community, including 11 contributors. Development has been continual since Apr. 2017, over 70 published versions (as of August 2024). Consistent 2000-3000 downloads per month since inception.<br />![GitHub Repo stars](https://img.shields.io/github/stars/totallyinformation/node-red-contrib-uibuilder) ![GitHub watchers](https://img.shields.io/github/watchers/totallyinformation/node-red-contrib-uibuilder)  ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/totallyinformation/node-red-contrib-uibuilder) ![GitHub repo size](https://img.shields.io/github/repo-size/totallyinformation/node-red-contrib-uibuilder)<br />[![Package Quality](https://camo.githubusercontent.com/093a41a984b9d2cf287f01c4f6ce6e5237ac83a6164d9df8a2c922a6e6d41fd3/687474703a2f2f6e706d2e7061636b6167657175616c6974792e636f6d2f736869656c642f6e6f64652d7265642d636f6e747269622d75696275696c6465722e706e67)](http://packagequality.com/#?package=node-red-contrib-uibuilder) [![DeepScan grade](https://camo.githubusercontent.com/8ea656cffd27c17a0c53f33c39d0a3ae0e89c2ecb945575f7e96b75e516db48d/68747470733a2f2f646565707363616e2e696f2f6170692f7465616d732f31333135372f70726f6a656374732f31363136302f6272616e636865732f3334303930312f62616467652f67726164652e737667)](https://deepscan.io/dashboard#view=project&tid=13157&pid=16160&bid=340901) [![CodeQL](https://github.com/TotallyInformation/node-red-contrib-uibuilder/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/TotallyInformation/node-red-contrib-uibuilder/actions/workflows/codeql-analysis.yml) | Open Source Apache 2.0 license, Commercial development by FlowFuse. Since Oct. 2023.<br />![GitHub Repo stars](https://img.shields.io/github/stars/flowfuse/node-red-dashboard) ![GitHub watchers](https://img.shields.io/github/watchers/FlowFuse/node-red-dashboard) ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/flowfuse/node-red-dashboard) ![GitHub repo size](https://img.shields.io/github/repo-size/flowfuse/node-red-dashboard)<br />[![Package Quality](https://packagequality.com/shield/node-red-dashboard.svg)](https://packagequality.com/#?package=node-red-dashboard) |

