A guide and explanation of Bun ui
Bun UI is a project i started a good while ago without a set goal per se, but it has grown to something i think is pretty cool, this is a explanation and introduction to it!
What is Bun UI⌗
In short it’s nodejs bindings for displaying RGB(a) buffers using GLFW layered in different levels of abstraction and a canvas based plotting drawing library.
How it came to be⌗
I didn’t mention this on the blog yet, but from time to time i like to do some data projects, as in i collect data from some services public api and then later do data things on it. My current project involves VATSIM btw.
But last year i started collecting data and needed a way to easily display aggregation of that data on the screen.
I knew i wanted to use node.js, as i prefer it over python(it’s personal preference, no bad blood). But i wanted to have easy, easy as in one/max two liners way to open a window on my desktop and display a graph/plot/pie chart. Like theres in python.
I had experience using GLFW and opengl prior so i quickly developed a plan of how i wanted to approach this, i did not want to use Electron as that was way to heavy for my planned usecase, But there wasn’t anything existing either which matched my needs.
Why Bun in Bun ui?⌗
When i started working on this project i was working at bun, bun has a FFI api slightly different from nodes and so i wanted to combine them in order to be able to discover bugs in bun aswell as develop the project.
Then bun let me go pretty unfairly. After which i also added node support via node-addon-api. But by then the name was set.
So how does it work⌗
Bun ui basically consists of a GLFW window with a RGBA texture shader with exposing a api to JS land. Then in JS land using the canvas module it also exposes a bunch of apis for drawing plots, graphs, pie charts and so on, besides some utility to save images to file system.
Building⌗
You will need a cpp compiler and cmake.
Then you can add a git dependency to a nodejs project via npm i --save https://github.com/liz3/bun-ui.git
.
When using Bun, here you are good to go, assuming there wheren’t any issues, canvas itself also needs some deps to build but they have a great wiki.
If you are on node, you will need to cd
into node_modules/bun-ui
and run npm run build-node
which will build the node.js bindings. Now everything is good to go.
The most simple example of displaying something⌗
import {toWindow, graph} from "bun-ui";
await toWindow("Hello BUN UI", graph("a Graph", [[0, 1]], [[0, "0"], [1, "1"]]));
Thats it, this will display a graph with one point x=0,y=0 and another x=1,y=1, and a line at 0 and another at 1. The window returns a promise which resolves once the window is closed by the user.
Bun uis plotting library entirely works with values normalized between 0/1, thats because you can rescale the buffer and the window. Independently of each other. You can make a graph with a very high resolution and display it on a small window and vise versa(even though that might be a bit pixelated).
Going down the abstraction⌗
The simple example is good but what if you want more control, can you update what’s displays, how the window behaves? Yes you can.
toWindow
and its version which uses arrow keys to display different images iterativeWindow
are all abstraction layers of Window
.
For toWindow
this looks like this:
// toWindow() -> easyWindowWithBounds:
export const easyWindowWithBounds = (
title,
buffer,
//...
) => {
return new Promise((resolve) => {
const window = new Window(title, ww, wh);
window.setCloseCallback(() => {
resolve();
});
window.create();
window.setClearColor(240, 240, 240);
if(winCb)
winCb(window);
window.updateBuffer(buffer, w, h, type);
});
};
This might give a better insight. The window class has a bunch of callbacks see github for a full list and functions which can be called again to mutate the windows state and so on. By default the event polling and re rendering is done for you but even that you can take control over! I should mention too that theres no thread stuffs going on here, the calls into native land happen on the main thread and are designed to be as short as possible to occupate the nodejs event loop as little as possible. windows poll with a interval.
Window has callbacks for mouse, key and close events among others. The clear color is for the parts of the window not covered by the buffer.
I should point out that you won’t be programming the next GTA with this, but as long as what you have can be represented in a RGB, RGBA or BGRA buffer you can display it with various levels of control. Which is what the plotting library also does, it uses node-canvas to create the plots and then passes that buffer to be displayed.
Bun ui is cross platform amd works on anything that runs nodejs and GLFW! the default build scripts work on mac, linux and windows.
Conclusion⌗
I do not think theres anything comparable and while i do not want to self compliment too much i believe this is a pretty cool small tool for anything involving display of pixel data on a screen. For more visit the Github