Writing GUI directly in HTML/CSS/JS is one of the very few ways to provide fully consistent UIs with responsiveness, among completely different devices, resolutions, DPIs and operating systems.
It works consistently on every minimally capable device in the world, today and in the future.
When done right, this is a good practice.
Having an independent layer for the UI is a good step in direction of separation of concerns, thus, it’s a good architecture practice (like front-end apps that communicates to back-ends through their APIs).
Also, it helps with mobile app encapsulation through Cordova or Capacitor. It can be extremely lightweight and fast as native when (1) reusing the mobile OS web engine (as webview on dekstop) and (2) when using a good processing model on JS side, like Svelte does with real reactivity.
This is not the only way.
We can use the same strategy of Tauri (see security), where they use the webview library but with no server nor open ports, using only the two-way language bindings for communication.
PS: The advantage of Axino (my experimental TS framework) is that an app written with Axino is 100% TS, so:
No complex bundler (no webpack config files). Jut Parcel.
It is compiled and packaged in one simple step.
There is compile-time check and type check etc. so it is basically safer than JS (and works better with VSCode).
But as I said in my previous post, it would be even simpler if it was 100% Crystal (if crystal could generate the JS or Wasm code needed on client-side).
This would make it possible to create apps in 100% Crystal (no HTML, CSS, JS, etc. needed for the users or the library).
In other words, it is possible to create 100% isomorphic apps (i.e. using Crystal on the « server-side » as well as on the « client-side »), hence resulting in a true app development kit 100% in Crystal.
To to put it another way : by using eval() and bind() the dom and its behavior (responding to events) can be written in Crystal, provided that the one creates a library which creates all the needed DOM elements from :
Crystal + eval() + bind()
Another way to look at it is : All that is needed to achieve an isomorphic app développement kit in Crystal / Webview is a an equivalent to Axino (or something similar) translated from TS to Crystal (which is a bit tedious to do, but not complicated).
I did the same thing for Golang (build a isomorphic GUI kit for Golang, which wraps JS code into Go functions):
Using GopherJS.
Using Go to Wasm compilation (transpiling).
And it works as expected.
(I have not published that code, because it is not ripe, but as an experiment it works)
I will try to test the concept with Crystal, as soon as I can install Webkit for Crystal on my Mac (does not work at the moment: I filed a bug report).
As of 2024, I’ve been working on a GUI library from the ground up.
It has fairly different design goals than other GUI frameworks that I’ve seen and the layout rules are quite different.
Features include
composable reactive components that can be templated together.
exposes a drawing API for freely rendering shapes / text / etc
decoupled from a backend (although currently only supports raylib out of the box)
automation capabilities baked in
some basic components provided
The library privileges the ability to easily create components as opposed to providing them. There is also support for font clamping/wrapping.
I’m in the process of learning a lot about a lot of technology I’ve taken for granted (a lot of ground to cover), so conversations are preferred over PRs and development will be a medium-slow burn.
If anyone wants to learn more, I put together a demo for a friend. (Thanks to nuclearbananana from reddit for compressing it). There are a few misteps and inaccuracies, but you’ll get the gist easily.
Why do you define UI and layout through templates (loosey strings, full of typos, which you need to parse at runtime?) and not through some similar nice DSL (pure code, checked by compiler)? What led you to this design? Thanks!
Hi, thanks for the criticism. I’m not sure what you mean by loosey strings full of typos, but the templates are parsed on mount. once. Decoupling the template from the code means that the code can focus on behavior and the presentation requires much less typing. Does this help?
I’m not sure what you mean by loosey strings full of typos,
I guess i can use some doc for lucky (it write template use purl Crystal) for explain what pfischer means.
Lucky uses Crystal methods for rendering HTML. The Crystal methods map as closely as possible to how HTML is used.
Using Lucky HTML adds an additional layer of type-safety, is auto-formatted with Crystal’s formatter, and can be much easier to refactor with regular Crystal methods as HTML gets larger.