State & Plans of GUI development with Crystal

At first my plan was to convert lfm (and maybe also dfm, fmx) files to crystal cofe using automated tool. This way you would be able to edit form in Lazarus as usual, then tool produce .cr file similar to pascal unit where you can edit event handlers.
But then i discovered reactive ui concept. In short: most usual thing in guis i made is a list of frames, each corresponding to some model object. Like a listview, but more customized, because items can have own lists, and don’t have to be positioned vertically. For example: list of columns for each category, each consists of border, caption and list of cards for issues in this category, each card consists of some text and a checklist for items in this issue. For the sake of example let checkboxes in it be somewhat customized too - say they include progressbar and some icon. In a lazarus/delphi i have to create a frame for each thing (column, card, checkbox), write a procedure that syncronize thing with model item (category/issue/subissue), maintain a lists of categories/issues/subitems and then my syncronization procedure will add/delete/modify things once something changed. It works, vut require some boilerplate, so each time we need to add another list it is tedious.
With reactive ui like a Vue, i describe one column/card/checkbox and then add “v-for: issue in category.issues” to make a list of them. You don’t even need to make them separate files - if element is simple it is easier to describe it inplace, all above example will fit in one small file.
This is so beautiful, I’m now thinking that DSL with such feature IS a way to do complex GUI.
I haven’t tried this approach at work though, only at pet project, so am not sure how this will work with buttons drawn in Photoshop and other things where drag-n-drop editor usually shine. Maybe some parts still have to be designed visually.


Just want to add this to the conversation. I am working on a GUI framework for Crystal based off of LibUI. Granted LibUI itself has a long way to go, but I plan on keeping up with development and updating the library accordingly.


When Crystal reaches Windows support the one and only framework to create bindings for is Sciter!

1 Like

This “Sciter” ? looks like it’s already multiplatform . There are already bindings on Windows for libraries like CrSFML. Is there a limitation for waiting on this one?

1 Like

You can create the bindings now it’s just I would say Sciter is a bit Windows scentric.

1 Like

I’m planning on building a pure GUI library for crystal after I finish my 3d game engine. The 3d Engine will serve as the rendering framework. See this forum post 3D Rendering Engine (game engine).

My original thought was to build a UI toolkit based on material design, but I’m open to suggestions.

FYI by pure I mean not binding to an existing gui library or rendering engine. Right now the only bindings I have are to opengl and glfw.



Creator of Sciter is my old friend. I helped him to port C-smile (that is what TIScript is based on) to Linux/UNIX back in 2001/2002.
It also has Linux/macOS version so we can reuse it for Lunux and macOS as well. It is very flexible and fastest HTML/CSS renderer as well.
I always can ask him for help if needed.

1 Like

That would be awesome. I actually dont really want sciter to get popular since it’s my secret super weapon XD.

I would love to have decent bindings for Crystal though but someone has to maintain it.
Also I am quite sure Andrew does not want to have anything to do with “obscure languages” (think the D wounds are still real).

Wow I didn’t know about sciter before. Why have I been using electron all this time?

1 Like

Because sciter is not free.

Yeah just saw that… :upside_down_face:

It is not his responsibility to create the bindings but I always can ask him about some technicalities if needed. :smiley:

It is free but not open source.


Yeah but the free tier is limited to dynamic libraries provided by the vendor. If you want to provide statically linked distributables where you only need to download a single file, you need to buy a license.

Just checked out your rendering engine, and its awesome! I have no idea how to make a GUI library, and have really wanted one for crystal. I used Hedron (libui wrapper) for a while, but libui is terrible.

Right, it make sense, this part was overlooked by me.

Sad day, sciter looks awesome

I am using the Gambas GUI environment as a sort of GUI server via scripting or via TCP sockets. Gambas supports both GTK/QT in an event driven way.
-Accessing Gambas (GUI)objects and properties by their Name from Crystal works fine.
-Forwarding GUI events to Crystal as plain text is also working fine.
-Gambas has a RAD GUI designer, which is drag and drop like in Visual Basic.

Demo App in cystal using Gambas(GTK,QT) for RAD GUI design.

require "socket"

class GuiClient
  property send_time = true
  @client =    #define var
  def connect
    @client =,GUI_PORT)
  rescue err
    puts err.message  

def send (object,value)
    puts "send(object,value)"     
    @client << object + "," + value + "\n"  #send to GUI_SERVER
    sleep 0.1    

def send (object)
  puts "send(object)"     
  @client << object + "\n"  #send to GUI_SERVER
  sleep 0.1

def disconnect

def receive  #handle events
spawn do  
        loop do    
            event = @client.gets
            puts event
            case event 
            when "Button1_clicked"  #stop button
            when "Button2_clicked"  #continue button
            when "Button3_clicked"  #clear textarea button
              send "textarea1.text",""    
            when "Button4_clicked"  #upcase textarea.text
              send "Textarea1.text" #request this value from gui elemen
              response = @client.gets
              puts "Response: ",response
              send "Textarea1.text",(response.not_nil! + "\n").upcase  #do upcase on string in textarea1
            when "Button5_clicked"  #upcase textarea.text
              send "Textarea1.text" #request this value from gui element
              response = @client.gets
              puts "Response: ",response
              send "Textarea1.text",(response.not_nil! + "\n").downcase  #do downcase on string in textarea1
            when "FMain_closed"     #Appilcation Window closed by user
#start the gambas gui server demo app
spawn do; system("~/src_gambas/gui_server/gui_server.gambas"); end
sleep 1   #give some time for startup
mygui =
mygui.send "textlabel1.text","crystal + gambas = crybas"
mygui.send "button1.text","stop"
mygui.send "button2.text","continue"
#mygui.send "button3.enabled","0"  #disable a button
mygui.send "button3.text","clear texrarea"
mygui.send "button4.text","do Text.upcase"
mygui.send "button5.text","do Text.downcase"
#send key,value pairs for GUI Objects based on GTK or QT 
mygui.send "FMain.Text","Crybas"   #set title of Application
mygui.send "Textarea1.Text","hello-textarea"

loop do   #Error writing to socket: Broken pipe when server closes
       mygui.send "Textbox1.Text",Time.local.to_s if mygui.send_time # display time in the gui
       sleep 1