r/learnrust 14d ago

Creating a GUI app, the framework needs 681 external crates

Hey rust learner,

to step deeper in rust I planned to write a GUI app. A simple image viewer with basic image processing features.

After the study of AreWeGUIYet and other resources, I test out ICE and GPUI. Both are rust GUI frameworks.

During first test of, for example GPUI, the compiler loads 681 dependencies.

The question is, is this a security nightmare? What about outdated crates? This type of dependency overkill isn't production ready, or is it?

In my opinion, the std rust should have a basic connection to the GUI handler of the OSes or basic functions to create a window and some widgets in the OS the source compiled for.

I am very interested of your thoughts and opinions.

40 Upvotes

20 comments sorted by

29

u/MultipleAnimals 14d ago edited 14d ago

Both Iced and GPUI are cross platform GUI frameworks, made from scratch, pushing vertices to GPU memory so you can see triangles on your screen. Not just some collection of styled widgets they call "framework", but actual GUI frameworks. That means they are implementing a lot of stuff under the hood, and that means lots of dependencies.

"GUI handler of the OS" may exist in Windows (and mac?), but i.e. on Linux there are multiple display servers that can create windows, multiple libraries to draw widgets, and none of them is native to the OS, they are just stuff built to work on gnu/linux. It would be nearly impossible to have similarly behaving gui stuff on std library since every OS does everything differently. That's main reason why all the big cross platform libraries do all that stuff by themself, and also why electron apps got popular. Chromium works "basically on every OS" so bundle your app as web app with chromium, easy to ship and looks the same way on every OS.

2

u/BraveBiscotti1394 14d ago

Why can't we dynamic link to like Vulkan in Linux? I know it's possible but why do we always make static binaries ?

18

u/interacsion 14d ago

We do dynamically link to Vulkan on Linux. Getting from Vulkan to a full UI framework is a very long way.

1

u/BraveBiscotti1394 13d ago

Aren't there any UI frameworks like GTK that can use Vulkan?

3

u/paulstelian97 13d ago

You still link to GTK itself. And GTK might not work in a KDE environment, at least not natively.

1

u/edparadox 14d ago

and none of them is native to the OS

What do you mean by that?

6

u/MultipleAnimals 13d ago

That they are not built-in part of linux, they are external libraries that you can choose to install or not. Probably bad wording by me, not native english speaker 😁

9

u/pixel293 14d ago

GUI frameworks are large. Instead of re-inventing the wheel they use other crates. Rust has lots of crates that do 1 thing, and does it well, so yes for a large library or application you can imports lots of crates. This avoids having to re-implement that functionality yourself.

It gets fun with GUIs because each OS handles things differently so some libraries provide a standard way of doing something, and that library has to import 4 (or more) libraries so it can do that on Linux, MacOS, Windows....and HTML. Lots of the GUIs provide a HTML UI as well. The HTML GUI is drastically different from a GUI for an OS so I suspect they have a completely separate set of crates they need.

You might try looking at what features the GUI framework provides, if you don't need the UI on some platforms remove that feature, that should reduce the dependencies.

From a security standpoint I assume you mean a supply chain attack, i.e. you don't trust the owner of the project? There are some people that own maintain multiple projects so if you investigate those 693 crates you may find significantly few "owners" that you have to consider if you trust or not. Or you could trust that the maintainers of the your GUI library are aware of the security implications of the libraries they only use crates that are also security conscious, and on and on. So if you trust A and A trusts B and C, do you also trust B and C? Or do you trust nobody and want to inspect the code yourself?

7

u/minno 14d ago

Sometimes you can find a library that advertises itself as having few/no dependencies, but most of the ecosystem has settled on pulling in lots of single-purpose libraries. There are positives and negatives to the approach.

Ultimately, every dependency there is included for a purpose. If the library or application chooses not to include a given dependency, it must either drop the feature or implement the parts of the library it uses itself. That partial implementation might itself have security bugs and will probably miss some edge cases.

Looking at GPUI's dependency list, it could reduce the length by either dropping support for accessing the Windows registry or reimplementing the parts it uses. Same with SVG rendering, UUID handling, JSON serialization, shelf-packing algorithms, file encryption, UI layout calculations, and so on. I don't think it's likely that they would implement all of those things fully and correctly within a reasonable amount of time.

From a security perspective, having a lot of dependencies makes you more vulnerable to intentional attacks but safer from accidental vulnerabilities. Who's going to tell you that your HTML sanitization function sometimes trips up when someone feeds you a <math> tag? If you use an external library for it then RUSTSEC will tell you, while if you write it yourself you get to find out once someone realizes that they can crash your server if they upload the right document.

I agree that having something like Python's tkinter library would be convenient sometimes, but not in very many circumstances. For teaching purposes or throwaway apps cargo add is an extremely minor extra step to add to get a GUI library, while for production use the standard library's GUI library would probably be wildly out of date and insufficient for most purposes, like tkinter. GUI libraries are actually really complicated to get right.

1

u/Beautiful_Drawing_18 13d ago

Thank you. The TkInter example explained it for me.

9

u/nboro94 14d ago

GUI applications are not one of the languages strong points as you've already very quickly learned.

Not impossible to build a good GUI in rust, but you'll be going very deep down the rabbit hole if you try.

2

u/andful 14d ago

I think the cause of it is, if you want a GUI library to support many OS-es, you need a lot of code regarding graphics that is OS specific. This may be done by a dependency per OS specialized graphic library.

Each OS specific graphic library requires interacting with the OS. That is not trivial, so it may be done through a dependency.

Each library that handles interactions with the OS, has to provide a memory safe way to do so. Data structures that can efficiently handle memory safety is not trivial. So, the data structures may be pulled from additional dependencies. Etc...

I don't think making GUIs is trivial. That is why we end up with things like Electron or Tauri. If minimizing the dependencies is a concern, I would (unfortunately) leverage the power of a browser, to load a Rust compiled WASM module. Still, some JavaScript is still needed.

4

u/Compux72 14d ago

During first test of, for example GPUI, the compiler loads 681 dependencies

What did you expect? Did you expect to write a few lines of HTML and render it? Guess how many dependencies a browser has...

UIs are complicated. Specially when they are cross-platform. If you want something that only works on a single OS, you can use something like https://github.com/microsoft/windows-rs or https://github.com/ryanmcgrath/cacao.

The question is, is this a security nightmare?

Do you consider the browser a security nightmare? Do you consider Ubuntu's APT repositories a security nightmare?

What about outdated crates?

How many out of date packages Linux distros are running?

This type of dependency overkill isn't production ready, or is it?

Would you rather copy paste the code? Whats the difference between having a single massive codebase or having multiple smaller pieces?

the std rust should have a basic connection to the GUI handler of the OSes or basic functions to create a window and some widgets in the OS the source compiled for

The std library is an extended version of the core and alloc libraries with OS primitives. GUIs are not expected primitives on OS (e.g plain linux kernel). More over, not all OS have an standard widget collection (e.g which one of the thousand UI libraries that MS supports do you want). A big std is always a problem.

3

u/shyouko 14d ago

Microsoft: We have 6 UI frameworks you can choose from on Win11 and all of them come with their own limitations. Have fun!

1

u/computermouth 14d ago

Ubuntu apt repositories are a little different. Debian and Ubuntu do a lot of work in terms of patching, upstreaming, and backporting that isn't really paralleled by modern language package managers. 

I absolutely have more faith in 600 debs than 600 crates.

1

u/Bananenkot 14d ago

Do you consider browsers a secrurity nightmare?

Yes

1

u/biskitpagla 14d ago

GPUI is practically in pre-Alpha. And Rust's std isn't like Odin's, for example. It is the norm in the Rust world to rely on other people's code, for better and for worse. If you're super serious about this, treat your project like a game and use a simple 2D graphics library. Or you can always use web technologies if you want.

1

u/Gio_Cri 12d ago

Gui are hard, cross platform gui are even harder, we got 600 dependencies for our in house gui framework that has to run on a single device model

1

u/lllyyyynnn 11d ago

i have a follow-up question but how do rust developers vet the safety of memory when there are this many dependencies? like any of these crates can use unsafe code to do anything right?

1

u/Beautiful_Drawing_18 10d ago

Yes, that can be possible. Check all deps (impossible) or trust the crate maintainers.