Skip to main content
Version: v2.3.1

Migrating from v1

Overviewโ€‹

Wails v2 is a significant change from v1. This document aims to highlight the changes and the steps in migrating an existing project.

Creating the Applicationโ€‹

In v1, the main application is created using wails.CreateApp, bindings are added with app.Bind, then the application is run using app.Run().

Example:

v1
 app := wails.CreateApp(&wails.AppConfig{
Title: "MyApp",
Width: 1024,
Height: 768,
JS: js,
CSS: css,
Colour: "#131313",
})
app.Bind(basic)
app.Run()

In v2, there is just a single method, wails.Run(), that accepts application options.

v2
    err := wails.Run(&options.App{
Title: "MyApp",
Width: 800,
Height: 600,
AssetServer: &assetserver.Options{
Assets: assets,
},
Bind: []interface{}{
basic,
},
})

Bindingโ€‹

In v1, it was possible to bind both arbitrary functions and structs. In v2, this has been simplified to only binding structs. The struct instances that were previously passed to the Bind() method in v1, are now specified in the Bind field of the application options:

v1
  app := wails.CreateApp(/* options */)
app.Bind(basic)
v2
    err := wails.Run(&options.App{
/* other options */
Bind: []interface{}{
basic,
},
})

In v1, bound methods were available to the frontend at window.backend. This has changed to window.go.``

Application Lifecycleโ€‹

In v1, there were 2 special methods in a bound struct: WailsInit() and WailsShutdown(). These have been replaced with 3 lifecycle hooks as part of the application options:

Note: OnDomReady replaces the wails:ready system event in v1.

These methods can be standard functions, but a common practice is to have them part of a struct:

v2
    basic := NewBasicApp()
err := wails.Run(&options.App{
/* Other Options */
OnStartup: basic.startup,
OnShutdown: basic.shutdown,
OnDomReady: basic.domready,
})
...
type Basic struct {
ctx context.Context
}
func (b *Basic) startup(ctx context.Context) {
b.ctx = ctx
}
...

Runtimeโ€‹

The runtime in v2 is much richer than v1 with support for menus, window manipulation and better dialogs. The signature of the methods has changed slightly - please refer the the Runtime Reference.

In v1, the runtime was available via a struct passed to WailsInit(). In v2, the runtime has been moved out to its own package. Each method in the runtime takes the context.Context that is passed to the OnStartup method.

Runtime Example
package main

import "github.com/wailsapp/wails/v2/pkg/runtime"

type Basic struct {
ctx context.Context
}

// startup is called at application startup
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
runtime.LogInfo(ctx, "Application Startup called!")
}

Assetsโ€‹

The biggest change in v2 is how assets are handled.

In v1, assets were passed via 2 application options:

  • JS - The application's JavaScript
  • CSS - The application's CSS

This meant that the responsibility of generating a single JS and CSS file was on the developer. This essentially required the use of complicated packers such as webpack.

In v2, Wails makes no assumptions about your frontend assets, just like a webserver. All of your application assets are passed to the application options as an embed.FS.

This means there is no requirement to bundle your assets, encode images as Base64 or attempt the dark art of bundler configuration to use custom fonts.

At startup, Wails will scan the given embed.FS for index.html and use its location as the root path for all the other application assets - just like a webserver would.

Example: An application has the following project layout. All final assets are placed in the frontend/dist directory:

.
โ”œโ”€โ”€ build/
โ”œโ”€โ”€ frontend/
โ”‚ โ””โ”€โ”€ dist/
โ”‚ โ”œโ”€โ”€ index.html
โ”‚ โ”œโ”€โ”€ main.js
โ”‚ โ”œโ”€โ”€ main.css
โ”‚ โ””โ”€โ”€ logo.svg
โ”œโ”€โ”€ main.go
โ””โ”€โ”€ wails.json

Those assets may be used by the application by simply creating an embed.FS:

Assets Example
//go:embed all:frontend/dist
var assets embed.FS

func main() {
err := wails.Run(&options.App{
/* Other Options */
AssetServer: &assetserver.Options{
Assets: assets,
},
})
}

Of course, bundlers can be used if you wish to. The only requirement is to pass the final application assets directory to Wails using an embed.FS in the Assets key of the application options.

Project Configurationโ€‹

In v1, the project configuration was stored in the project.json file in the project root. In v2, the project configuration is stored in the wails.json file in the project root.

The format of the file is slightly different. Here is a comparison:

v1v2Notes
namename
descriptionRemoved
author / nameauthor / name
author / emailauthor / email
versionversion
binarynameoutputfilenameChanged
frontend / dirRemoved
frontend / installfrontend:installChanged
frontend / buildfrontend:buildChanged
frontend / bridgeRemoved
frontend / serveRemoved
tagsRemoved
wailsjsdirThe directory to generate wailsjs modules
assetdirThe directory of the compiled frontend assets for dev mode. This is normally inferred and could be left empty.
reloaddirsComma separated list of additional directories to watch for changes and to trigger reloads in dev mode. This is only needed for some more advanced asset configurations.