# Step by step instruction and example how to create standalone applications for Windows with a \[G\]UI

**URL:** <https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274>\
**Category:** General Usage\
**Tags:** package-compiler, ui, gui\
**Created:** [April 21, 2025, 8:57pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274 "2025-04-21T20:57:53Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 21, 2025, 8:57pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/1 "2025-04-21T20:57:53Z")

</div>

After many hours of troubles, [discussions](https://discourse.julialang.org/t/how-to-create-standalone-applications-for-windows-with-a-g-ui-in-julia-1-11-or-1-12/127823) and problems, gave this issue a final try and [here is my solution](https://codeberg.org/donovaly/Juliastic/src/branch/main/Readme.md).

I created a [complete repository](https://codeberg.org/donovaly/Juliastic) called “Juliastic” that provides these features:

1. step by step instructions how to compile a DLL using PackageCompiler.  
**Note** : you must use Julia 1.10.x, with 1.11.4 I got a lot of issues I cannot explain.
2. instructions how to test the DLL in a C program
3. a small Lazarus example project that uses the DLL you will compile when following the above instructions

Summing it up over the last days, I had to spend many hours to resolve all issues.

Please give it a try and report any errors you encountered. Please also feel free to fix mistakes you see directly at the [Juliastic Wiki](https://codeberg.org/donovaly/Juliastic/wiki/Home).  
If you have instructions for other UI widgetsets and OSes, you can also directly create a Wiki page.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 21, 2025, 9:16pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/2 "2025-04-21T21:16:13Z")

</div>

I have one issue I did not yet understand: In the [examples folder](https://github.com/JuliaLang/PackageCompiler.jl/tree/master/examples/MyLib/build) of PackageCompiler there is a file “[additional\_precompile.jl](https://github.com/JuliaLang/PackageCompiler.jl/blob/master/examples/MyLib/build/additional_precompile.jl)”. What does it do, why is it there and why can’t is content be directly part of “[generate\_precompile.jl](https://github.com/JuliaLang/PackageCompiler.jl/blob/master/examples/MyLib/build/generate_precompile.jl)”.

@ianshmean, @kristoffer.carlsson , do you know this maybe?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 21, 2025, 9:24pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/3 "2025-04-21T21:24:45Z")

</div>

Glad you figured it out and thanks for reporting back! This is great.

> [@uwestoehr](#):
>
> I have one issue I did not yet understand: In the [examples folder](https://github.com/JuliaLang/PackageCompiler.jl/tree/master/examples/MyLib/build) of PackageCompiler there is a file “[additional\_precompile.jl](https://github.com/JuliaLang/PackageCompiler.jl/blob/master/examples/MyLib/build/additional_precompile.jl)”. What does it do, why is it there and why can’t is content be directly part of “[generate\_precompile.jl](https://github.com/JuliaLang/PackageCompiler.jl/blob/master/examples/MyLib/build/generate_precompile.jl)”.

It could be! There’s nothing fundamentally special about _either_ mechanism for specifying what should get compiled. You can either generate such a list of `precompile` statements by hand, or semi-automatically (e.g., with an interactive `julia --trace-compile=additional_precompile.jl` session) or fully automatedly with the execution file. I’m sure the example is only using both so it can demonstrate both kwargs in its doc:

```Julia-repl
julia> create_library("MyLib", "MyLibCompiled";
                      lib_name="libinc",
                      precompile_execution_file="MyLib/build/generate_precompile.jl",
                      precompile_statements_file="MyLib/build/additional_precompile.jl",
                      header_files = ["MyLib/build/mylib.h"])

```

Neither of these kwargs are required; you can use both methods, one, or none. Use what works best for you!

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 21, 2025, 9:35pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/4 "2025-04-21T21:35:40Z")

</div>

> [@mbauman](#):
>
> Neither of these kwargs are required

Thanks. Now I need to understand what `precompile(Tuple{typeof(MyLib.increment64), Clong})`  
actually does.

And last but not least to understand the concept of precompilation correctly. I mean in [generate\_precompile.jl](https://github.com/JuliaLang/PackageCompiler.jl/blob/master/examples/MyLib/build/generate_precompile.jl) a function is called 10 times in a row. Why that, why not just once, 4, 9 or 100 times?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 21, 2025, 9:43pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/5 "2025-04-21T21:43:55Z")

</div>

It’s just telling Julia what functions to compile for which argument types (ahead of time). `precompile(Tuple{typeof(MyLib.increment64), Clong})` means “compile `MyLib.increment64(::Clong)`”. It’s the mechanism to move Julia’s just-barely-ahead-of-time (JIT) compiler further ahead of time.

What you pass to `precompile_execution_file` could indeed be just a single iteration. Or maybe two. Whatever Julia compiles in the process of running that file, will effectively become a `precompile` directive like that. The more representative your precompiles are, the less time you’ll spend waiting for the JIT later on.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 22, 2025, 12:00am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/6 "2025-04-22T00:00:44Z")

</div>

> [@mbauman](#):
>
> What you pass to `precompile_execution_file` could indeed be just a single iteration. Or maybe two.

Thanks. I performed now some tests and the outcome is:

- no matter of precompile() is run 10 times or the function is executed 10 times, the resulting library runs in both cases with the same speed
- executing the function more than 5 times brings no benefit

I updated my repository accordingly.

---

<div class="post-metadata">

**Author:** ![GHTaarn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ghtaarn/32/216007_2.png) [@GHTaarn](https://discourse.julialang.org/u/GHTaarn)\
**Post date:** [April 22, 2025, 2:55am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/7 "2025-04-22T02:55:35Z")

</div>

> [@uwestoehr](#):
>
> Please also feel free to fix mistakes you see directly at the [Juliastic Wiki](https://codeberg.org/donovaly/Juliastic/wiki/Home).

Do you need a Codeberg account to do this?

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [April 22, 2025, 4:12am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/8 "2025-04-22T04:12:52Z")

</div>

great work, thanks.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 22, 2025, 1:07pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/9 "2025-04-22T13:07:21Z")

</div>

> [@GHTaarn](#):
>
> Do you need a Codeberg account to do this?

Yes.  
By the way, I recently discovered [Codeberg](https://en.wikipedia.org/wiki/Codeberg) as alternative to GitHub and it is working well (as far as I can tell after just 1 month of actively using it). It is organized the same way as e.g. KDE - a German assembly where everybody can become a member. So in contrast to GitHub and Gitlab, there is no big tech company behind it.

---

<div class="post-metadata">

**Author:** ![GeorgeGkountouras](https://avatars.discourse-cdn.com/v4/letter/g/77aa72/32.png) [@GeorgeGkountouras](https://discourse.julialang.org/u/GeorgeGkountouras)\
**Post date:** [April 22, 2025, 3:12pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/10 "2025-04-22T15:12:07Z")

</div>

Thanks, this is certainly a step forward!

I didn’t see any mention of codesigning. This is a requirement if you intend to distribute executables. How do you handle it? Perhaps Windows is more lenient in that respect?

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 22, 2025, 11:54pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/11 "2025-04-22T23:54:02Z")

</div>

> [@GeorgeGkountouras](#):
>
> I didn’t see any mention of codesigning.

Thanks for having a look. Yes, I did not mention this because this is part of the release process of a program (e.g. on Windows you would sign the installer).

My instruction only covers the process of using the compiled DLL for another UI program. From then on the program can be developed as usual (creating installers, beta testing etc.) but this is independent of whether it contains a DLL created with Julia.

---

<div class="post-metadata">

**Author:** ![GeorgeGkountouras](https://avatars.discourse-cdn.com/v4/letter/g/77aa72/32.png) [@GeorgeGkountouras](https://discourse.julialang.org/u/GeorgeGkountouras)\
**Post date:** [April 23, 2025, 11:38am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/12 "2025-04-23T11:38:24Z")

</div>

> [@uwestoehr](#):
>
> From then on the program can be developed as usual (creating installers, beta testing etc.) but this is independent of whether it contains a DLL created with Julia.

This has not been my experience on MacOS. I’m shipping libraries, not executables.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 23, 2025, 12:15pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/13 "2025-04-23T12:15:59Z")

</div>

> [@GeorgeGkountouras](#):
>
> This has not been my experience on MacOS

I have no access to MacOS.  
That is why I setup [a Wiki](https://codeberg.org/donovaly/Juliastic/wiki/Home). I would be happy, if you

- make a Codeberg login
- click on the link for the MacOS Wiki page and create a new page
- fill in the instructions for MacOS.

The aim is to help people. The information can later be put into other Wiki, official docs or whatever. Important is in my opinion to collect them at first.

---

<div class="post-metadata">

**Author:** ![GeorgeGkountouras](https://avatars.discourse-cdn.com/v4/letter/g/77aa72/32.png) [@GeorgeGkountouras](https://discourse.julialang.org/u/GeorgeGkountouras)\
**Post date:** [April 23, 2025, 12:21pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/14 "2025-04-23T12:21:23Z")

</div>

I can help write the instructions once I get it to work.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 24, 2025, 11:01pm UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/15 "2025-04-24T23:01:46Z")

</div>

Just for the records: [I added now](https://codeberg.org/donovaly/Juliastic/releases/tag/0.4) code that shows how Julia structs and tensors can be exported and used in C or Lazarus.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [April 30, 2025, 3:36am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/16 "2025-04-30T03:36:11Z")

</div>

Just for the records: [I added now](https://codeberg.org/donovaly/Juliastic/releases/tag/0.5) code that shows how C-arrays of double can be imported to Julia and how bools are handled in Lazarus.

(For the array handling it was surprisingly tricky to find out how it is done.)

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [May 3, 2025, 1:50am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/17 "2025-05-03T01:50:04Z")

</div>

> [@uwestoehr](#):
>
> For the array handling it was surprisingly tricky

And it was more tricky. I used the code my my real-life application and got random crashes. It turned out that two things are crucial:

- assure that Julia does not own the data from the external C-caller (in function unsafe\_wrap). Otherwise the garbage collector of Julia might free it. The owner is the C-caller and he will free it when no longer used.
- for every data that is output as pointer, one must create a persistent copy and allocate memory for it. The memory must be free’d once Julia is closed.

I updates the repository accordingly. I also added an example how to input/output a static array to/from Julia.

I made [a new release](https://codeberg.org/donovaly/Juliastic/releases).

Since I use the code for a real-world application (that I will also publish here when completely ready), and I stress-tested it now for a while, I treat the code as production-ready. Therefore the release got the version “1.0”.

---

<div class="post-metadata">

**Author:** ![uwestoehr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwestoehr/32/216201_2.png) [@uwestoehr](https://discourse.julialang.org/u/uwestoehr)\
**Post date:** [May 8, 2025, 12:58am UTC](https://discourse.julialang.org/t/step-by-step-instruction-and-example-how-to-create-standalone-applications-for-windows-with-a-g-ui/128274/18 "2025-05-08T00:58:20Z")

</div>

> [@uwestoehr](#):
>
> I will also publish here when completely ready

It is ready and I published it in [this new thread](https://discourse.julialang.org/t/an-example-for-cross-platform-standalone-gui-application/128822).

Regarding the repository with the instructions, I made a [final release](https://codeberg.org/donovaly/Juliastic/releases/tag/1.1).  
Thereby I improved the Julia code to make it more flexible for vectors and tensors in different data types and added some safe guards to the Lazarus example program.  
The latter turned out to be important in case the compiled library has issues. Now the Lazarus code tests if the library contains every C-callable function and if not, the program terminates correctly.

As I consider the task to get a step by step instruction done and as i was able to use it for a feature-complete real-world program, I treat this thread as resolved.
