# How to create a GUI app using libui-ng on Windows?

**URL:** <https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361>\
**Category:** Help & Support\
**Created:** [January 22, 2024, 2:57pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361 "2024-01-22T14:57:27Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [January 22, 2024, 2:57pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/1 "2024-01-22T14:57:27Z")

</div>

Hi

I heard that Windows support has been [improved](https://crystal-lang.org/2024/01/19/windows-support-1.11/) in Crystal 1.11.

Can someone tell me how to create a GUI app using [libui-ng](https://github.com/libui-ng/libui-ng) and [libui.cr](https://github.com/Fusion/libui.cr)?  
Are static libraries sufficient instead of shared libraries on Windows?

[https://nightly.link/libui-ng/libui-ng/workflows/build/master](https://nightly.link/libui-ng/libui-ng/workflows/build/master)

([nightly.link](https://nightly.link/) keeps GitHub Actions artifact links up to date, a Crystal service created by oprypin)

I started up my Windows PC and tried it out a bit, but I couldn’t figure out how to do it with Windows. I thought it would be faster to ask the question on the forum, listen to what people have to say, and do what they say.

I’m interested in this because I’m writing a [libui bindings for Ruby](https://github.com/kojix2/LibUI).

---

<div class="post-metadata">

**Author:** ![existXFx](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/existxfx/32/1448_2.png) [@existXFx](https://forum.crystal-lang.org/u/existXFx)\
**Post date:** [January 22, 2024, 7:53pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/2 "2024-01-22T19:53:33Z")

</div>

> [@kojix2](#):
>
> Can someone tell me how to create a GUI app using [libui-ng](https://github.com/libui-ng/libui-ng) and [libui.cr](https://github.com/Fusion/libui.cr)?

I’ve used libui (not its fork libui-ng, but API is roughly similar) with macOS environment. I didn’t use the libraries you mentioned, it looks like they only offer low-level API, instead I used [iu](https://github.com/grkek/iu), a wrapper for the libui library API, which is nice to get started with, even though it’s probably no longer maintained. Basically you just need to layout the required components and register the callbacks.

A GUI application usually can’t run in a single thread, but AFAIK Crystal’s multithreading support on Windows isn’t ready yet, so you’ll need to create your own UI threads and worker threads, and take care that interface operations are performed in the UI threads.

> [@kojix2](#):
>
> Are static libraries sufficient instead of shared libraries on Windows?

I think so but not tested(on Windows), just make sure the linker can find the static library, then add the `-static` flag. there should be no need for header files, as these libraries map the API using the C binding.

Other thoughts: libui and libui-ng are great libraries, they have the advantage of being lightweight, but they are also missing many important features. If memory serves, when using libui a few years ago, it even lacked events in response to double clicks on table rows. Now I prefer to develop with imgui, also has [pretty great Crystal bindings](https://github.com/oprypin/crystal-imgui)(thanks @oprypin) and can develop native GUI programs with complex features.

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [January 23, 2024, 4:37am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/3 "2024-01-23T04:37:25Z")

</div>

Hi @existXFx

I would like to use ui too. But I think libui.cr is running on the backend of iu. So I wanted to run libui.cr first.

libui has been forked into libui-ng and some functions have been added, such as `uiTableOnRowDoubleClicked`.  
ImGui is complicated and doesn’t look very native, which is not really my taste.  
But hey, I have to try it at least once.

> A GUI application usually can’t run in a single thread, but AFAIK Crystal’s multithreading support on Windows isn’t ready yet, so you’ll need to create your own UI threads and worker threads, and take care that interface operations are performed in the UI threads.

Hmm, this seems quite difficult.

---

<div class="post-metadata">

**Author:** ![konovod](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/konovod/32/229_2.png) [@konovod](https://forum.crystal-lang.org/u/konovod)\
**Post date:** [January 24, 2024, 11:59am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/4 "2024-01-24T11:59:53Z")

</div>

Actually, you don’t need another thread - you can just call `Fiber.yield` in an idle event or a main loop (not sure how to do it in case of libui-ng). Then other fibers will execute when gui thread gives them time for it.

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [January 25, 2024, 1:44am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/5 "2024-01-25T01:44:40Z")

</div>

To be honest, I am not sure about something much more basic.

First, download the file from the link.  
[https://nightly.link/libui-ng/libui-ng/workflows/build/master/Mingw-x64-static-release.zip](https://nightly.link/libui-ng/libui-ng/workflows/build/master/Mingw-x64-static-release.zip)

Then you will find the file `builddir/meson-out/libui.a`

How to use `libui.a` on Windows?

libui.cr is written like this ↓

> <https://github.com/Fusion/libui.cr/blob/master/src/libui/libui.cr>

↑

1. Do I need to modify `@[Link("ui")]` ?
2. How do I specify build options such as `--link-flags` ?
3. Is `libui.a` enough? Do we need additional files such as `libui.lib`?

---

<div class="post-metadata">

**Author:** ![mdwagner](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/mdwagner/32/1077_2.png) [@mdwagner](https://forum.crystal-lang.org/u/mdwagner)\
**Post date:** [January 25, 2024, 4:23am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/6 "2024-01-25T04:23:20Z")

</div>

\*.a is for Linux, \*.lib is for Windows. You can use link-flags, but it’ll either be `-L/directory/path/of/a` (Linux) or `/LIBPATH:C:\directory\path\to\lib` (Windows).

---

<div class="post-metadata">

**Author:** ![HertzDevil](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hertzdevil/32/1023_2.png) [@HertzDevil](https://forum.crystal-lang.org/u/HertzDevil)\
**Post date:** [January 25, 2024, 9:28am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/7 "2024-01-25T09:28:32Z")

</div>

You should have these files somewhere in `CRYSTAL_LIBRARY_PATH`:

- `libui-static.lib`: Static library (built with MSVC)
- `libui-dynamic.lib`: DLL import library
- `<name of the DLL>.dll`: the actual dynamic library

then put `@[Link("ui", dll: "<name of the DLL>.dll")]`.

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [January 25, 2024, 10:19am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/8 "2024-01-25T10:19:19Z")

</div>

After much trial and error, I finally succeeded in opening a basic window, but I am not sure what worked and what did not.

```cr
require "../src/libui/libui.cr"

o = UI::InitOptions.new
err = UI.init pointerof(o)
if !ui_nil?(err)
  exit 1
end

mainwin = (UI.new_window "Writing Windows apps in Crystal? Don't be silly!", 450, 20, 1).not_nil!

# on_closing = ->(w : UI::Window*, data : Void*) {
# UI.control_destroy ui_control(mainwin)
# UI.quit
# 0
# }

UI.window_set_margined mainwin, 1
# UI.window_on_closing mainwin, on_closing, nil

UI.control_show ui_control(mainwin)

UI.main
UI.uninit

```

![image](https://canada1.discourse-cdn.com/flex036/uploads/crystal_lang/original/2X/9/951ce6bc14026fbe77f071c0029e521582620b22.png)

Besides, I get the following error.

```auto
Unhandled exception: passing a closure to C is not allowed (Exception)

```

So I had to comment out the callback.  
This is probably for the reason that @existXFx pointed out.

---

<div class="post-metadata">

**Author:** ![konovod](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/konovod/32/229_2.png) [@konovod](https://forum.crystal-lang.org/u/konovod)\
**Post date:** [January 25, 2024, 1:12pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/9 "2024-01-25T13:12:22Z")

</div>

For a callback, you can check [Callbacks - Crystal](https://crystal-lang.org/reference/1.10/syntax_and_semantics/c_bindings/callbacks.html#passing-a-closure-to-a-c-function)

as a simple fix - replace `mainwin` to `MAINWIN` (so a callback will access a constant, not local variable).

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [March 29, 2024, 3:59am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/10 "2024-03-29T03:59:18Z")

</div>

For those who came to this page searching for “Windows GUI Crystal language”.

I found it very easy to call `powershell.exe` and display the dialog. It may be useful in some cases.  
You can display the file selection dialog by doing the following

```cr
cmd = <<-CMD
powershell.exe -command
    Add-Type -AssemblyName System.Windows.Forms
    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $openFileDialog.initialDirectory = $InitialDirectory
    $openFileDialog.filter = "All files (*.*)| *.*"
    $openFileDialog.ShowDialog() > $null
    Write-Host $openFileDialog.Filename
CMD

ps = Process.new(cmd, shell: true, output: Process::Redirect::Pipe, error: Process::Redirect::Pipe)
stdout = ps.output
content = ps.output.gets_to_end
path = Path.windows(content.strip)
p File.exists?(path)

```

See : [powershell-gui-dialogs.ps1 · GitHub](https://gist.github.com/jonschoning/5503062)

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [March 30, 2024, 3:07am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/11 "2024-03-30T03:07:42Z")

</div>

I understand why you think the above example is silly, but being able to create Windows executables in Crystal is a dream come true.

I love Ruby, but creating an executable file that runs on Windows and creating and distributing a package is difficult with Ruby. That probably will not change in the future.

Crystal’s Windows support is not a “Ruby replacement”. It is a pure extension of what can be done for both Ruby and Crystal communities…

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [April 7, 2024, 3:07am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/12 "2024-04-07T03:07:06Z")

</div>

I have created a wrapper for [Zenity](https://github.com/ncruces/zenity).  
This simply calls Zenity from `Process.new` in a more Crystal-like syntax, which may be useful in some situations. However, this is not dependency free because it requires the Zenity executable for Windows.

> **[GitHub - kojix2/zenity.cr: Zenity wrapper for Crystal](https://github.com/kojix2/zenity.cr)**
>
> Zenity wrapper for Crystal. Contribute to kojix2/zenity.cr development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![konovod](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/konovod/32/229_2.png) [@konovod](https://forum.crystal-lang.org/u/konovod)\
**Post date:** [April 19, 2024, 9:34am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/13 "2024-04-19T09:34:55Z")

</div>

I want to mention NAppGUI ([https://nappgui.com/](https://nappgui.com/)) library - it has C API (easily wrappable in Crystal), works on Linux/Mac/Windows and is much more customizable (IMHO) than LibUI.

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [April 19, 2024, 9:47am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/14 "2024-04-19T09:47:07Z")

</div>

Thanks @konovod  
I’m involved with libui, so I can’t give an unbiased 🙃 opinion , but NAppGUI looks very promising. It’s just that many cross-platform lightweight GUI libraries start out active, but after a while development stops. May development continue 🚵‍♂️

---

<div class="post-metadata">

**Author:** ![mavu](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/mavu/32/213_2.png) [@mavu](https://forum.crystal-lang.org/u/mavu)\
**Post date:** [April 19, 2024, 1:04pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/15 "2024-04-19T13:04:21Z")

</div>

I didn’t know this project and it sounds interesting!

> Doesn’t use .NET, MFC, ATL and any other kind of redundant technology. The static linking will produce self-contained small binaries. NAppGUI neither use STL, only a small subset of The Standard C Library that also will be linked to the final product, so any VC++ Redistributable package will be required.

Do you happen to know of any crystal examples that use it?

---

<div class="post-metadata">

**Author:** ![konovod](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/konovod/32/229_2.png) [@konovod](https://forum.crystal-lang.org/u/konovod)\
**Post date:** [April 19, 2024, 1:14pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/16 "2024-04-19T13:14:38Z")

</div>

I don’t know about any crystal examples, but i’ve tried to create wrappers and low level wrappers work like charm. There is even a callback that is called 60 times a second (to do `Fiber.yield`).  
I’m still stuck on high-level DSL though.  
The only thing that was problematic for me when i tried - gui layouts are created at startup and not intended to be modified later. I think this was solved by [Add dynamic creation of window elements/widgets during runtime · Issue #74 · frang75/nappgui\_src · GitHub](https://github.com/frang75/nappgui_src/issues/74)

---

<div class="post-metadata">

**Author:** ![mavu](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/mavu/32/213_2.png) [@mavu](https://forum.crystal-lang.org/u/mavu)\
**Post date:** [April 19, 2024, 1:35pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/17 "2024-04-19T13:35:09Z")

</div>

very interesting!  
I have to give it a try.

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [April 19, 2024, 3:54pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/18 "2024-04-19T15:54:34Z")

</div>

I want to know the latest way to use the Crystal language with C libraries on Windows. I have looked at the instructions on the official site, but I am not sure about Windows.

[https://crystal-lang.org/reference/1.12/syntax\_and\_semantics/c\_bindings/lib.html](https://crystal-lang.org/reference/1.12/syntax_and_semantics/c_bindings/lib.html)

I recently found that Crystal 1.12 generates a single executable only if --static is appended, otherwise the dll is placed in the bin directory with the binary excutable.

Perhaps calling the C library on Windows is still under active development and we need to wait a bit until official announcements and the community finds best practices…

---

<div class="post-metadata">

**Author:** ![kojix2](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/kojix2/32/1583_2.png) [@kojix2](https://forum.crystal-lang.org/u/kojix2)\
**Post date:** [April 19, 2024, 3:59pm UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/19 "2024-04-19T15:59:37Z")

</div>

Good to hear.  
I would appreciate it if you could upload the code to GitHub or another hosting service. In fact, I went to your GitHub to see if the project was uploaded, but but could not find the corresponding project.

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 20, 2024, 6:11am UTC](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361/20 "2024-04-20T06:11:47Z")

</div>

C bindings work the same on Windows as on Unix systems. There’s really no significant difference. Since 1.12 also the linker behaviour is thr same in linking dynamically by default and statically with `--static` flag.  
Distribution of DLLs is a bit different because theres no system wide packaging system. So they’re usually shipped together with the application.

[Next page](https://forum.crystal-lang.org/t/how-to-create-a-gui-app-using-libui-ng-on-windows/6361.md?page=2)
