Build cross-platform modern desktop apps in Go + HTML5

Lorca

Build Status GoDoc Go Report Card

Lorca

A very small library to build modern HTML5 desktop apps in Go. It uses Chrome browser as a UI layer. Unlike Electron it doesn't bundle Chrome into the app package, but rather reuses the one that is already installed. Lorca establishes a connection to the browser window and allows calling Go code from the UI and manipulating UI from Go in a seamless manner.


Features

  • Pure Go library (no cgo) with a very simple API
  • Small application size (normally 5-10MB)
  • Best of both worlds - the whole power of HTML/CSS to make your UI look good, combined with Go performance and ease of development
  • Expose Go functions/methods and call them from JavaScript
  • Call arbitrary JavaScript code from Go
  • Asynchronous flow between UI and main app in both languages (async/await and Goroutines)
  • Supports loading web UI from the local web server or via data URL
  • Supports embedding all assets into a single binary
  • Supports testing your app with the UI in the headless mode
  • Supports multiple app windows
  • Supports packaging and branding (e.g. custom app icons). Packaging for all three OS can be done on a single machine using GOOS and GOARCH variables.

Also, limitations by design:

  • Requires Chrome/Chromium >= 70 to be installed.
  • No control over the Chrome window yet (e.g. you can't remove border, make it transparent, control position or size).
  • No window menu (tray menus and native OS dialogs are still possible via 3rd-party libraries)

If you want to have more control of the browser window - consider using webview library with a similar API, so migration would be smooth.

Example

ui, _ := lorca.New("", "", 480, 320)
defer ui.Close()

// Bind Go function to be available in JS. Go function may be long-running and
// blocking - in JS it's represented with a Promise.
ui.Bind("add", func(a, b int) int { return a + b })

// Call JS function from Go. Functions may be asynchronous, i.e. return promises
n := ui.Eval(`Math.random()`).Float()
fmt.Println(n)

// Call JS that calls Go and so on and so on...
m := ui.Eval(`add(2, 3)`).Int()
fmt.Println(m)

// Wait for the browser window to be closed
<-ui.Done()

Also, see examples for more details about binding functions, embedding assets and packaging binaries.

Hello World

Here are the steps to run the hello world example.

cd examples/counter
go get
go run main.go

How it works

Under the hood Lorca uses Chrome DevTools Protocol to instrument on a Chrome instance. First Lorca tries to locate your installed Chrome, starts a remote debugging instance binding to an ephemeral port and reads from stderr for the actual WebSocket endpoint. Then Lorca opens a new client connection to the WebSocket server, and instruments Chrome by sending JSON messages of Chrome DevTools Protocol methods via WebSocket. JavaScript functions are evaluated in Chrome, while Go functions actually run in Go runtime and returned values are sent to Chrome.

What's in a name?

There is kind of a legend, that before his execution Garcia Lorca have seen a sunrise over the heads of the soldiers and he said "And yet, the sun rises...". Probably it was the beginning of a poem. (J. Brodsky)

Lorca is an anagram of Carlo, a project with a similar goal for Node.js.

License

Code is distributed under MIT license, feel free to use it in your proprietary projects as well.

Owner
Serge Zaitsev
Turning complex problems into a lightweight and simple software solutions.
Serge Zaitsev
Comments
  • Application dies after a few seconds

    Application dies after a few seconds

    I compiled both the example and the following program on Linux and Windows. They run fine for a few seconds and then they exit automatically with no errors. Should they not stay running until I close the browser?

    I am using Go version go1.11.2 and Chrome 70.0.3538.102 (Official Build) (64-bit)

    package main

    import ( "fmt" "os"

    "github.com/zserge/lorca"
    

    )

    func main() {

    ui, err := lorca.New("", "", 480, 320)
    
    if err != nil {
    	fmt.Fprintf(os.Stderr, "fatal: %v\n", err)
    	os.Exit(1)
    }
    
    
    defer ui.Close()
    
    // Bind Go function to be available in JS. Go function may be long-running and
    // blocking - in JS it's represented with a Promise.
    ui.Bind("add", func(a, b int) int { return a + b })
    
    // Call JS function from Go. Functions may be asynchronous, i.e. return promises
    n := ui.Eval(`Math.random()`).Float()
    fmt.Println(n)
    
    // Call JS that calls Go and so on and so on...
    m := ui.Eval(`add(2, 3)`).Int()
    fmt.Println(m)
    
    // Wait for the browser window to be closed
    <-ui.Done()
    

    }

  • Support Chromium based Microsoft Edge

    Support Chromium based Microsoft Edge

    I took the liberty of creating this issue so we can track and centralize discussion around supporting the upcoming Chromium engine based Microsoft Edge.

    Microsoft's official announcement (archive.org copy) (PDF copy) (Gist markdown copy)

    What

    Today we’re announcing that we intend to adopt the Chromium open source project in the development of Microsoft Edge on the desktop to create better web compatibility for our customers and less fragmentation of the web for all web developers.

    When

    Over the next year or so, we’ll be making a technology change that happens “under the hood” for Microsoft Edge, gradually over time, and developed in the open so those of you who are interested can follow along.

    My take

    This is potentially great news for Lorca on Windows if future Edge provides the features that Lorca needs. Current version of Edge on Windows 10 spawns a private Edge session for me when running:

    start shell:AppsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge -private https://github.com

    image

    But my understanding is that Lorca also relies on Chrome DevTools Protocol. I hope to see that available in the new Edge.

  • Running main readme example, gives: ./main.go:68:36: undefined: FS

    Running main readme example, gives: ./main.go:68:36: undefined: FS

    I'm on Ubuntu 20.10: Linux G14 5.10.4-051004-generic #202012301142 SMP Wed Dec 30 11:44:55 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

    > (base) rw3iss@G14:~/Sites/go/lorca$ cd examples/counter
    > (base) rw3iss@G14:~/Sites/go/lorca/examples/counter$ go get
    > go: downloading golang.org/x/net v0.0.0-20200222125558-5a598a2470a0
    > (base) rw3iss@G14:~/Sites/go/lorca/examples/counter$ go run main.go
    > # command-line-arguments
    > ./main.go:68:36: undefined: FS
    

    Any ideas?

  • feat: added RawValue interface

    feat: added RawValue interface

    To allow for the detection of a nil return, a new interface is added (to maintain backwards compatibility) and implemented by value. This interface, RawValue, allows the retrieval of the raw bytes but requires a type assertion.

    Fixes #126

  • ui.Eval does not return a value

    ui.Eval does not return a value

    Grabbing HTML value from document via Eval returns no value. Not sure if this is a bug or I have bad HTML. I do not get any runtime errors.

    My code

    package main
    
    import (
    	"fmt"
    	"net/url"
    
    	"github.com/zserge/lorca"
    )
    
    var (
    	ui1        lorca.UI
    	HTML_entry string = `
    <html>
        <body>
            <input hidden type="text" name="MYVAR" value="testVal">
            <input type="submit" onclick="golangfunc()"
        </body>
    </html>
    `
    )
    
    func main() {
    	ui1, _ = lorca.New("data:text/html,"+url.PathEscape(HTML_entry), "", 480, 320)
    	ui1.Bind("golangfunc", golangfunc)
    	defer ui1.Close()
    	<-ui1.Done()
    }
    
    func golangfunc() {
    	htmlvar := ui1.Eval(`document.getElementsByName('MYVAR').value`).String()
    	fmt.Println(htmlvar)
    }
    
  • Chromium parameters not being passed correctly

    Chromium parameters not being passed correctly

    System information:

    • Arch Linux with kernel 4.19.101-1
    • Go version go1.13.8 linux/amd64

    Steps to reproduce:

    • Create a new go file and paste the example code from https://github.com/zserge/lorca#example
    • Run the file using go run or build and run (it does not seem to make any difference)
    • Get the pid of the running application and take a look to all of it's child processes (this can be done manually using htop with tree view, or by running ps --forest -o pid,tty,stat,time,cmd -g $(ps -o sid= -p PID_OF_PARENT))

    Current behavior: There is a whitespace that gets inserted in between parameters, it appears randomly between arguments, for example sometimes it turns --disable-background-networking into --disable-background- etworking or --disable-background-timer-throttling into --disable-ba kground-timer-throttling. The whitespace is not a visual issue as it appears even if redirecting the output to a text file.

    See the whitespace affecting --disable-ba kground-timer-throttling In the example below:

    $ ps --forest -o pid,tty,stat,time,cmd -g $(ps -o sid= -p 67930)
        PID TT       STAT     TIME CMD
      51417 pts/10   Ss   00:00:00 /bin/bash
      67834 pts/10   Sl+  00:00:00  \_ go run hello.go
      67930 pts/10   Sl+  00:00:00      \_ /tmp/go-build688287313/b001/exe/hello
      67936 pts/10   Sl+  00:00:02          \_ /usr/lib/chromium/chromium --disable-background-networking --disable-ba kground-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-infobars --disable-extensions --disable-features=site-per-process --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --disable-translate --metrics-recording-only --no-first-run --safebrowsing-disable-auto-update --enable-automation --password-store=basic --use-mock-keychain --app=data:text/html,<html></html> --user-data-dir=/tmp/lorca366230083 --window-size=480,320 --remote-debugging-port=0
      67939 pts/10   S+   00:00:00              \_ /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca366230083
      67941 pts/10   S+   00:00:00              |   \_ /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca366230083
      67970 pts/10   Sl+  00:00:00              |       \_ /usr/lib/chromium/chromium --type=renderer --disable-background-timer-throttling --disable-breakpad --enable-automation --disable-webrtc-apm-in-audio-service --remote-debugging-port=0 --field-trial-handle=intentionally-hidden --disable-features=site-per-process --lang=en-US --user-data-dir=/tmp/lorca366230083 --disable-client-side-phishing-detection --disable-oor-cors --enable-auto-reload --num-raster-threads=4 --enable-main-frame-before-activation --renderer-client-id=4 --shared-files=v8_snapshot_data:100
      67960 pts/10   Sl+  00:00:00              \_ /usr/lib/chromium/chromium --type=gpu-process --field-trial-handle=intentionally-hidden --disable-features=site-per-process --disable-breakpad --user-data-dir=/tmp/lorca366230083 --gpu-preferences=KAAAAAAAAAAgAAAgAAAAAAAAYAAAAAAAEAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAA --shared-files
      67962 pts/10   Sl+  00:00:00              \_ /usr/lib/chromium/chromium --type=utility --field-trial-handle=intentionally-hidden --disable-features=site-per-process --lang=en-US --service-sandbox-type=network --disable-webrtc-apm-in-audio-service --user-data-dir=/tmp/lorca366230083 --shared-files=v8_snapshot_data:100
    

    Expected behavior: No whitespace gets inserted between parameters

  • go version 1.12 not allowed

    go version 1.12 not allowed

    when I use go version 1.12 and 1.12.3 build my exe,I cannot open my exe, when I double click exe nothing to show, then I use go version 1.11.3 window/amd64 build, then it works , I cant find why, hope an cool person to help me, thank you very much

  • undefined: FS

    undefined: FS

    Getting when running the counter example or anything similar

    # command-line-arguments
    .\main.go:32:36: undefined: FS
    
    ln, err := net.Listen("tcp", "127.0.0.1:0")
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer ln.Close()
    	go http.Serve(ln, http.FileServer(FS)) // FS here is what undefined?
    	ui.Load(fmt.Sprintf("http://%s", ln.Addr()))
    
  • No easy way to terminate whole application

    No easy way to terminate whole application

    I was trying to close my lorca app in two ways:

    1. By binding go function which runs os.Exit(0) and running it in js (actually it was vue, but I think that it doesn't matter)
    2. By running kill <my-app-ID-number>

    Both ways terminated only code written in go, but rest of app (chromium UI layer) was still in its place.

    I observed that after killing my app manually by clicking Ctrl + c in terminal output of ps aux | grep chromium was following: karol 9725 0.0 0.0 6208 888 pts/2 S+ 22:13 0:00 grep chromium, however by killing my app by kill <my-app-ID-number>, output of ps aux | grep chromium was following:

    karol     9494  2.4  1.9 3012884 156584 pts/0  SLl  22:13   0:00 /usr/lib/chromium/chromium --show-component-extension-options --enable-gpu-rasterization --no-default-browser-check --disable-pings --media-router=0 --enable-remote-extensions --load-extension= --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-infobars --disable-extensions --disable-features=site-per-process --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --disable-translate --metrics-recording-only --no-first-run --safebrowsing-disable-auto-update --enable-automation --password-store=basic --use-mock-keychain --app=data:text/html,<html></html> --user-data-dir=/tmp/lorca025088096 --window-size=720,720 --class=Lorca --remote-debugging-port=0
    karol     9508  0.0  0.0   5740  1772 pts/0    S    22:13   0:00 /usr/lib/chromium/chrome-sandbox /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
    karol     9509  0.1  0.7 408188 60800 pts/0    SL   22:13   0:00 /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
    karol     9511  0.0  0.1 408188 14264 pts/0    S    22:13   0:00 /usr/lib/chromium/chromium --type=zygote --user-data-dir=/tmp/lorca025088096
    karol     9534  1.0  1.4 1226304 117532 pts/0  SLl  22:13   0:00 /usr/lib/chromium/chromium --type=gpu-process --field-trial-handle=5158464758563543256,8617488245687844448,131072 --disable-features=site-per-process --disable-breakpad --enable-gpu-rasterization --user-data-dir=/tmp/lorca025088096 --gpu-preferences=KAAAAAAAAACAAAAAAQAAAAAAAAAAAGAAAAAAAAEAAAAIAAAAAAAAAAgAAAAAAAAA --service-request-channel-token=5379940991211926664
    karol     9684  1.1  1.1 1389292 93324 pts/0   Sl   22:13   0:00 /usr/lib/chromium/chromium --type=renderer --disable-background-timer-throttling --disable-breakpad --enable-automation --field-trial-handle=5158464758563543256,8617488245687844448,131072 --disable-features=site-per-process --disable-gpu-compositing --service-pipe-token=921988823902182683 --lang=en-US --user-data-dir=/tmp/lorca025088096 --disable-client-side-phishing-detection --enable-offline-auto-reload --enable-offline-auto-reload-visible-only --num-raster-threads=2 --enable-main-frame-before-activation --service-request-channel-token=921988823902182683 --renderer-client-id=5 --shared-files=v8_context_snapshot_data:100,v8_natives_data:101
    karol     9725  0.0  0.0   6208   888 pts/2    S+   22:13   0:00 grep chromium
    

    So technically go layer is an actual app, but UI layer isn't actually an app, but chromium process(es). Can we "merge" these two layers to one my-app process?

  • Stability question

    Stability question

    I understand Lorca does not ship with as much garbage as Electron because it uses an installed version of Chrome by the user instead of shipping with it's own version. How does it handle a situation where chrome is non-existent on the installed machine or chrome is too old on the installed machine causing some things in my web application to not function right?

  • Ctrl-t and ctrl-n open new browser window

    Ctrl-t and ctrl-n open new browser window

    On Windows, standard chrome shortcuts ctrl-t and ctrl-n open a new, empty browser window, which is probably not what any application writer wants.

    If possible, they should be blocked. Better yet, it would be good if that was routed through logic in Go program so that user of library can decide if this should be blocked or allowed to proceed. If allowed to proceed, there should be a way to specify which html file or url to load.

  • make html form data trigger another function

    make html form data trigger another function

    Hello friend, is there any way to make a page in lorka trigger another function, for example, write to an external database?

    func form_html() { // Create UI with basic HTML passed via data URI

    ui, err := lorca.New("data:text/html,"+url.PathEscape(`
    <form method="post">
    <legend>form</legend>
    <fieldset>
    <div>
        <label for="name">name:</label>
        <input type="text" id="name" name="name"  maxlength="18"/>
    </div>
    <div>
    <label for="valor">email:</label>
      <input type="email" id="email" name="email"  maxlength="18"/>
    </div>
    </fieldset>
    <div class="button">
        <button type="submit">commit</button>
    </div>
    
    `), "", 480, 320) if err != nil { log.Fatal(err)
    	insert_db("name", "email")
    
    }
    
    defer ui.Close()
    // Wait until UI window is closed
    <-ui.Done()
    

    Friends, reading the documentation, I managed to do this, but I still haven't figured out how to return the page to the beginning after submitting I click the commit button, or maybe generate a popup, is there any way to do this?

  • Seperate Chromium and Edge UI's

    Seperate Chromium and Edge UI's

    Seperate the chromium and EDGE UI's into lorca.NewChromium and lorca.NewEdge so that the user can choose to use Edge instead of chrome when they have booth installed. Also, do not automatically add in all the default arguments. Instead make these public through AdditionalEdgeArgs and AdditionalChromiumArgs so that the user is not forced to use all the default arguments.

  • Adds support for acting as a Chrome wrapper without the --app flag, passing custom arguments to Chrome, and Brave Browser

    Adds support for acting as a Chrome wrapper without the --app flag, passing custom arguments to Chrome, and Brave Browser

    I would like to use Lorca as a way of pre-configuring Chromium browsers to work in particular environments, in particular as a means of configuring Chromium's to browse the I2P anonymous overlay network. This PR adds support for running Chrome without passing the --app flag and no longer appearing as a "kiosk" type browser. It's also adds the ability to pass custom arguments when operating in this mode. That way I can do things like pass --proxy settings and load unpacked extensions off the filesystem. I'm currently using Lorca in this fashion in the package https://github.com/eyedeekay/aluminumoxynitride which is an I2P wrapping Browser for Chromium.

    I also added support for Brave, a popular Chromium fork with a supposed focus on privacy and emerging web technologies. This was actually partly because it presents a solution the difficulties a visually-impaired user was having getting their Brave Browser configured for I2P. Personally I am not a Brave user, but this user suggested that they preferred the accessibility features of Chrome-based browsers and chose Chrome on that basis. https://old.reddit.com/r/i2p/comments/t9q812/i2p_with_brave_on_mac_os_x/

  • You should use the devtools protocol and not websockets

    You should use the devtools protocol and not websockets

    Hello my name is Frank Lemanschik i am a german Engineer and i am working on exact the same project but with a other runtime not go based. But i guess my Studies will help you.

    i try to create https://github.com/open-pwa/open-pwa and your welcome to join that effort as it would be great if we would implement also go runners with the same protocol and api.

    Open Pwa is in it's Core about Connections between the Host System and the Browser so like your project.

    Your using Websockets at present to do the Message Exchange while that works it is highly insecure under many situations and is not useable at scale on a single machine like a Desktop PC that whants to install many diffrent apps.

    I Guess your using lorca as foundation "Electron" Replacement

    https://github.com/GoogleChromeLabs/carlo look at this for example that is exactly what you need to implement it uses the process pipe + devtools protocol.

    Some more short details about open-pwa

    It is Designed to get a Platform to Install and Run Apps it offers the Installer and User Interactions that are needed to handle Application Permissions.

    • It will design and work out a Api like the existing PWA one That will turn any Browser and Host Os or even only a Host Os into a Android like OS that kann install applications and give them diffrent permissions and Isolations.
    • open-pwa could be written in go and we could reuse and integrate your code rebranded and we could exchange patches and concepts.
An example desktop system tray application that can launch HTML5 windows. Go source with a build process for Windows, Mac and Linux.

ExampleTrayGUI An example cross-platform (Mac, Windows, Linux) system tray application that can launch HTML5 windows, developed in Go including functi

Dec 3, 2022
An example desktop system tray application that can launch HTML5 windows. Go source with a build process for Windows, Mac and Linux.

An example cross-platform (Mac, Windows, Linux) system tray application that can launch HTML5 windows, developed in Go including functional build process. This repository is intended as a quick reference to help others start similar projects using the referenced libraries and will not be actively maintained.

Dec 3, 2022
An example desktop system tray application that can launch HTML5 windows. Go source with a build process for Windows, Mac and Linux.

ExampleTrayGUI An example cross-platform (Mac, Windows, Linux) system tray application that can launch HTML5 windows, developed in Go including functi

Dec 3, 2022
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by Electron)

Thanks to go-astilectron build cross platform GUI apps with GO and HTML/JS/CSS. It is the official GO bindings of astilectron and is powered by Electr

Jan 9, 2023
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs)
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs)

gowd Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs) How to use this library: Download and install nwjs Install this library g

Dec 11, 2022
Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase
Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

Kita is a declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase. Inspired by Flutter, React. S

Apr 18, 2022
UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase
 UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

UIKit - A declarative, reactive GUI toolkit for build cross platform apps with web technology with single codebase

Apr 18, 2022
Create desktop apps using Go and Web Technologies.
Create desktop apps using Go and Web Technologies.

Build desktop applications using Go & Web Technologies. The traditional method of providing web interfaces to Go programs is via a built-in web server

Dec 29, 2022
A package to build progressive web apps with Go programming language and WebAssembly.
A package to build progressive web apps with Go programming language and WebAssembly.

go-app is a package to build progressive web apps (PWA) with Go programming language and WebAssembly. It uses a declarative syntax that allows creatin

Dec 28, 2022
Cross platform GUI in Go based on Material Design
Cross platform GUI in Go based on Material Design

About Fyne is an easy to use UI toolkit and app API written in Go. It is designed to build applications that run on desktop and mobile devices with a

Jan 3, 2023
An experimental Go cross platform UI library.

GXUI - A Go cross platform UI library. Notice: Unfortunately due to a shortage of hours in a day, GXUI is no longer maintained. If you're looking for

Jan 6, 2023
Tiny cross-platform webview library for C/C++/Golang. Uses WebKit (Gtk/Cocoa) and Edge (Windows)

webview A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs. Also, there are Rust bindings, Python bindings, Ni

Dec 28, 2022
RobotGo, Go Native cross-platform GUI automation @vcaesar

Robotgo Golang Desktop Automation. Control the mouse, keyboard, bitmap, read the screen, Window Handle and global event listener. RobotGo supports Mac

Jan 7, 2023
Cross-platform Go library to place an icon in the host operating system's taskbar.

trayhost Package trayhost is a cross-platform Go library to place an icon in the host operating system's taskbar. Platform Support macOS - Fully imple

Nov 6, 2022
Cross-platform GUI for go is never this easy and clean.
Cross-platform GUI for go is never this easy and clean.

gimu Strongly suggest NOT to use this project anymore, the auto-generated cgo wrapper of Nuklear has a random crash issue which is hard to fix (becaus

Jul 12, 2022
Go cross-platform library for displaying dialogs and input boxes

dlgs dlgs is a cross-platform library for displaying dialogs and input boxes. Installation go get -u github.com/gen2brain/dlgs Documentation Document

Dec 24, 2022
A cross-platform app-development module for Go.
A cross-platform app-development module for Go.

The cross-platform Go module for building apps (pronounced klo-va-seed). Usecases As a lightweight alternative to Electron Write your frontend and nat

Dec 1, 2022
pure go, cross-platform, MIT-licensed ui toolkit for developers
pure go, cross-platform, MIT-licensed ui toolkit for developers

duit - developer ui toolkit WARNING: this library is work in progress. backwards incompatible changes will be made. details duit is a pure go (*), cro

Dec 24, 2022
Cross platform rapid GUI framework for golang based on Dear ImGui.
Cross platform rapid GUI framework for golang based on Dear ImGui.

giu Cross platform rapid GUI framework for golang based on Dear ImGui and the great golang binding imgui-go. Any contribution (features, widgets, tuto

Dec 28, 2022