# What's new in v3? !!! note The features that will be included in the v3 release may change from this list. ## Multiple Windows It's now possible to create multiple windows and configure each one independently. ```go package main import ( _ "embed" "log" "github.com/wailsapp/wails/v3/pkg/application" ) //go:embed assets/* var assets embed.FS func main() { app := application.New(application.Options{ Name: "Multi Window Demo", Assets: application.AssetOptions{ FS: assets, }, }) window1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Window 1", }) window2 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Window 2", }) // load the embedded html from the embed.FS window1.SetURL("/") window1.Center() // Load an external URL window2.SetURL("https://wails.app") err := app.Run() if err != nil { log.Fatal(err.Error()) } } ``` ## Systrays Systrays allow you to add an icon in the system tray area of your desktop and have the following features: - Attach window (the window will be centered to the systray icon) - Full menu support - Light/Dark mode icons ```go package main import ( _ "embed" "log" "runtime" "github.com/wailsapp/wails/v3/pkg/application" "github.com/wailsapp/wails/v3/pkg/icons" ) func main() { app := application.New(application.Options{ Name: "Systray Demo", Mac: application.MacOptions{ ActivationPolicy: application.ActivationPolicyAccessory, }, }) window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Width: 500, Height: 800, Frameless: true, AlwaysOnTop: true, Hidden: true, Windows: application.WindowsWindow{ HiddenOnTaskbar: true, }, }) systemTray := app.NewSystemTray() // Support for template icons on macOS if runtime.GOOS == "darwin" { systemTray.SetTemplateIcon(icons.SystrayMacTemplate) } else { // Support for light/dark mode icons systemTray.SetDarkModeIcon(icons.SystrayDark) systemTray.SetIcon(icons.SystrayLight) } // Support for menu myMenu := app.NewMenu() myMenu.Add("Hello World!").OnClick(func(_ *application.Context) { println("Hello World!") }) systemTray.SetMenu(myMenu) // This will center the window to the systray icon with a 5px offset // It will automatically be shown when the systray icon is clicked // and hidden when the window loses focus systemTray.AttachWindow(window).WindowOffset(5) err := app.Run() if err != nil { log.Fatal(err) } } ``` ## Plugins Plugins allow you to extend the functionality of the Wails system. Not only can plugin methods be used in Go, but also called from Javascript. Included plugins: - kvstore - A key/value store - browser - open links in a browser - log - custom logger - oauth - handles oauth authentication and supports 60 providers - single_instance - only allow one copy of your app to be run - sqlite - add a sqlite db to your app. Uses the modernc pure go library - start_at_login - Register/Unregister your application to start at login ## Improved bindings generation v3 uses a new static analyser to generate bindings. This makes it extremely fast and maintains comments and parameter names in your bindings. By default, bindings are generated with calls using IDs instead of strings. This provides a performance boost and allows for using obfuscation tools such as [garble](https://github.com/burrowers/garble). Bindings are generated by simply running `wails3 generate bindings` in the project directory. ```js // @ts-check // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // This file is automatically generated. DO NOT EDIT import { main } from "./models"; window.go = window.go || {}; window.go.main = { GreetService: { /** * GreetService.Greet * Greet greets a person * @param name {string} * @returns {Promise} **/ Greet: function (name) { wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); }, /** * GreetService.GreetPerson * GreetPerson greets a person * @param person {main.Person} * @returns {Promise} **/ GreetPerson: function (person) { wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0)); }, }, }; ``` ## Improved build system In v2, the build system was completely opaque and hard to customise. In v3, it's possible to build everything using standard Go tooling. All the heavy lifting that the v2 build system did, such as icon generation, have been added as tool commands in the CLI. We have incorporated [Taskfile](https://taskfile.dev) into the CLI to orchestrate these calls to bring the same developer experience as v2. However, this approach brings the ultimate balance of flexibility and ease of use as you can now customise the build process to your needs. You can even use make if that's your thing! ```yaml title="Snippet from Taskfile.yml" build:darwin: summary: Builds the application platforms: - darwin cmds: - task: pre-build - task: build-frontend - go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}} - task: post-build env: CGO_CFLAGS: "-mmacosx-version-min=10.13" CGO_LDFLAGS: "-mmacosx-version-min=10.13" MACOSX_DEPLOYMENT_TARGET: "10.13" ``` ## Improved events Events are now emitted for a lot of the runtime operations, allowing you to hook into application/system events. Cross-platform (common) events are also emitted where there are common platform events, allowing you to write the same event handling methods cross platform. Event hooks can also be registered. These are like the `On` method but are synchronous and allow you to cancel the event. An example of this would be to show a confirmation dialog before closing a window. ```go package main import ( _ "embed" "log" "time" "github.com/wailsapp/wails/v3/pkg/application" "github.com/wailsapp/wails/v3/pkg/events" ) //go:embed assets var assets embed.FS func main() { app := application.New(application.Options{ Name: "Events Demo", Description: "A demo of the Events API", Assets: application.AssetOptions{ FS: assets, }, Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: true, }, }) // Custom event handling app.Events.On("myevent", func(e *application.WailsEvent) { log.Printf("[Go] WailsEvent received: %+v\n", e) }) // OS specific application events app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) { println("events.Mac.ApplicationDidFinishLaunching fired!") }) // Platform agnostic events app.On(events.Common.ApplicationStarted, func(event *application.Event) { println("events.Common.ApplicationStarted fired!") }) win1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ Title: "Takes 3 attempts to close me!", }) var countdown = 3 // Register a hook to cancel the window closing win1.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) { countdown-- if countdown == 0 { println("Closing!") return } println("Nope! Not closing!") e.Cancel() }) win1.On(events.Common.WindowFocus, func(e *application.WindowEvent) { println("[Event] Window focus!") }) err := app.Run() if err != nil { log.Fatal(err.Error()) } } ``` ## Wails Markup Language (wml) An experimental feature to call runtime methods using plain html, similar to [htmx](https://htmx.org). ```html Wails ML Demo

Wails ML Demo

This application contains no Javascript!

Hover over me
```