# Build simple GUIs with MiniFB

**URL:** <https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195>\
**Category:** General Usage\
**Tags:** announcement, guis\
**Created:** [September 7, 2020, 12:33pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195 "2020-09-07T12:33:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 7, 2020, 12:33pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/1 "2020-09-07T12:33:55Z")

</div>

I’d like to announce a little vacation project of mine. I’ve just released the first version of [MiniFB.jl](https://github.com/aviks/MiniFB.jl), a Julia wrapper around a small C library called [MiniFB](https://github.com/emoon/minifb).

MiniFB is possibly the simplest way to get a graphical window up on a screen in a cross platform way on modern OSs. The basic idea is to create a 32bit buffer of pixels yourself, and pass it on to the framework to display. So you’d write code like this:

```julia
window = mfb_open_ex("my display", 800, 600, MiniFB.WF_RESIZABLE);
while true
	#TODO: add some fancy rendering to the buffer of size 800 * 600
	state = mfb_update(window, buffer);
	if state < 0
	    break
     end
end

```

Note that this is not a full fledged GUI framework – in particular, there is no widget library. There is however support for mouse and keyboard input, so pretty sophisticated UIs are indeed possible.

So, in summary, if you want to throw up an [image viewer](https://juliahub.com/docs/MiniFB/NwZ6j/0.1.0/example/Image/) in a few dozen lines of code, with a TTFP of 1.5 seconds\* (after precompilation), this may be what you need.

Documentation here: [https://juliahub.com/docs/MiniFB/](https://juliahub.com/docs/MiniFB/)

Regards

Avik

\*(I fully expect ttfp to go down to less than a second after Elliot’s chages to jll loading in 1.6)

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 8, 2020, 7:14am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/2 "2020-09-08T07:14:48Z")

</div>

> [@avik](#):
>
> vacation project

Yep. There are those like us that like coding during vacations! Yay!

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 8, 2020, 7:18am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/3 "2020-09-08T07:18:29Z")

</div>

> [@avik](#):
>
> around a small C library called [MiniFB](https://github.com/emoon/minifb).

Theoretically, is it possible to write a MiniFB in pure Julia? Curious. I guess in that case it might take a while to compile. But I guess there would be a way to include Julia binaries in a \_jll package.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 8, 2020, 2:34pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/4 "2020-09-08T14:34:07Z")

</div>

> Theoretically, is it possible to write a MiniFB in pure Julia?

Yes, I suppose. But you’ll have to call into the platform libraries (win32, cooca, X etc) for most of the actual functionality. MiniFB is a really small library that basically just does that, abstracting accross the different platforms. Because it does not have a widget library of it’s own, it is pretty simple. So I don’t see much point personally…

Now, in the days before BinaryBuilder, I had a different opinion. But these days, using most C libraries is great.

Regards

Avik

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [September 8, 2020, 2:56pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/5 "2020-09-08T14:56:24Z")

</div>

Stupid, stupid, stupid question. We like Pluto.jl notebooks. I know Pluto used webby stuff - Javascript.  
Can we see a small toolkit like this being part of a Pluto notebook?

Sorry if I am proving my idiocy.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 8, 2020, 3:04pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/6 "2020-09-08T15:04:56Z")

</div>

No, that’s a valid question, but I think the answer is probably not.

So the this library is pretty focussed on desktop UIs. The thing is, opening a window and listening to its event queue is non-trivial to do in a platform agnostic manner. That is the problem that this library solves. In a web environment, the browser handles all of this internally, with a much higher level api access only via Javascript… so I’m not sure a library like this would be useful.

It might be an interesting idea for Pluto to provide access to the Canvas drawing primitves to Julia code, then you’ll be able to use something like Luxor and Javis to draw on the browser, but I’m not sure is that is a good idea, or even feasible.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 9, 2020, 8:44am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/7 "2020-09-09T08:44:03Z")

</div>

> [@avik](#):
>
> But you’ll have to call into the platform libraries (win32, cooca, X etc)

I guess that makes it not really worth it to do in Julia if there is something that exists. You can’t really compose that with Julia code anyway.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 9, 2020, 12:05pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/8 "2020-09-09T12:05:07Z")

</div>

How do you rate the stability of this vs Gtk.jl?

Gtk has a lot of problems (like on windows 😬) so it would be nice to swap out something simpler for my interface package [https://github.com/cesaraustralia/DynamicGridsGtk.jl](https://github.com/cesaraustralia/DynamicGridsGtk.jl). It already makes it’s own GUI with an array anyway, so Gtk is total overkill.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 10, 2020, 3:38pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/9 "2020-09-10T15:38:46Z")

</div>

So I honestly haven’t used it for anything too big or difficult, so in that sense it’s caveat emptor, but I havent seen any major problems in my limited experience. In particular, it works well on windows. If you are not using Gtk’s widget library (buttons, text boxes, menus etc), it may be worth trying.

If you can create an array of `Colors.jl/Colorant` objects, it will be trivial to render it using MiniFB.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 10, 2020, 3:46pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/10 "2020-09-10T15:46:17Z")

</div>

Great. That’s what we have already - and array of `ARGB32`.

It’s a trivial problem really, it would only be a 20 line package, DynamicGrids.jl does everything except actually putting the image on the screen. The refresh rate can be over 100fps sometimes, thats the only thing that could cause issues if it wasn’t optimized.

> it works well on windows.

Also this is great. Reliably cross-platform is what we need.

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 10, 2020, 5:28pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/11 "2020-09-10T17:28:41Z")

</div>

> It’s a trivial problem really, it would only be a 20 line package,

Yeah, I’ve always wondered why opening a window and displaying an image on it is not 5 lines of code. That’s one of the reasons why I was interested in this library.

> The refresh rate can be over 100fps sometimes,

This made me curious, so I changed my [image viewer demo](https://juliahub.com/docs/MiniFB/NwZ6j/0.1.0/example/Image/) to update the buffer every frame (rather than only on user input), and change the loop to go as fast as possible (using `while true` instead of `while mfb_wait_sync`). Every frame, we rezise the image, update the raw buffer with the image data, and then render the screen. This causes my laptop (two year old i7) to use about 25-30% cpu and results in a frame rate of 175 fps. If I constraint the frame rate to 100 using `mfb_set_target_fps` and `mfb_wait_sync`, CPU utilisation drops to around 15-18%, with an eventual frame rate of 96.

So a very simple test, takes a bit of CPU, but hopefully shows that things are not terrible. I can see there are some allocations that can be removed, so I hope this can be improved.

[Edit] to clarify, this was with a 600x400 pixel window.

Regards

Avik

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [September 10, 2020, 6:55pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/12 "2020-09-10T18:55:50Z")

</div>

Thanks for this!

To try it, I replaced GLFW with it in a simple project. You can see that it reduces the amount of boilerplate code by quite a bit!

[https://github.com/jebej/VoxelSpace/commit/15ba002d5dc6da2f05abb388e9ef0047521c09c8](https://github.com/jebej/VoxelSpace/commit/15ba002d5dc6da2f05abb388e9ef0047521c09c8)

---

<div class="post-metadata">

**Author:** ![avik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/avik/32/17_2.png) [@avik](https://discourse.julialang.org/u/avik)\
**Post date:** [September 10, 2020, 7:05pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/13 "2020-09-10T19:05:10Z")

</div>

Nice! Nothing makes an open source developer happier than to see their code being used by someone else.

What kind of FPS are you seeing compared to GLFW? As far as I understand, MiniFB renders everything on the CPU.

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [September 10, 2020, 7:16pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/14 "2020-09-10T19:16:28Z")

</div>

The FPS is largely constrained by the function computing the buffer. The work is all done on the CPU, and benchmarking it each execution takes ~6ms on my PC.

I get 100 to 120 FPS, so I assume MiniFB takes around 2 ms to update the window.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 10, 2020, 11:57pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/15 "2020-09-10T23:57:26Z")

</div>

That sounds pretty good. That’s often roughly the pixel size too, although we use 1200\*800 too, but that’s a little slower anyway

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 11, 2020, 12:18am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/16 "2020-09-11T00:18:32Z")

</div>

I couldn’t find anything online but I would’ve thought someone would have tried making a widgets library in minifb

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [September 11, 2020, 9:46am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/17 "2020-09-11T09:46:52Z")

</div>

Brilliant stuff, Avik.

 ![minifb](https://global.discourse-cdn.com/julialang/original/3X/a/7/a71fa35eda25b0503a51e9125df399dea6d2ffd3.gif)

Who needs Processing? 🙂

---

<div class="post-metadata">

**Author:** ![jebej](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jebej/32/1784_2.png) [@jebej](https://discourse.julialang.org/u/jebej)\
**Post date:** [September 11, 2020, 11:45am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/18 "2020-09-11T11:45:22Z")

</div>

Is the FPS counter/text a feature of MiniFB or do you just draw it manually on the buffer?

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [September 11, 2020, 11:48am UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/19 "2020-09-11T11:48:04Z")

</div>

Yes, just drawn with `Luxor.text()`. (And thanks for the code! 😹)

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [September 11, 2020, 12:08pm UTC](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195/20 "2020-09-11T12:08:09Z")

</div>

@cormullion would you be able to paste the example code for your animation above? it looks slick!

[Next page](https://discourse.julialang.org/t/build-simple-guis-with-minifb/46195.md?page=2)
