Build backwards compatible apps with Go and Wails.
Wails was created to make it easier for developers to create desktop apps using Go and web technologies.
However, I needed to be sure that the apps I intend to share would run on both current and older desktop platforms. So, my approach in this article, was to configure Vite to produce client code that will be backwards compatible.
Ultimately, I wished to explore how the experience of developing with Wails could be tailored, restructuring the folder and files Wails creates automatically; in order to accommodate my operational preferences.
I primarily use an Apple Mac and the following article outlines the steps I took to provide a coherent working environment for developing desktop apps with Go and Wails.
Wails requires two dependencies, Go 1.18+ and NPM (Node15+), so make sure they are installed before continuing.
One should also view the Wails installation document for platform specific guidance.
To install Wails, type the following into the CLI:
Latest version at the time of writing is: v2.3.1
Once installation has completed, it is recommended to run the Wails system check, making sure the correct Wails dependencies are also installed. At the CLI, type the following:
Wails app project initialisation
This section is about allowing Wails to initialise a project workspace.
Create the project folder in the workspace – substitute your own project name for ‘project-name’.
Initialise the new project workspace using Wails.
Flags used with the init command:
-nSet the name of the project – this is mandatory.
-dfollowed by the project directory; I specified ‘.’ meaning the current directory.
Wails will create the following folder and files structure.
- Within the
frontendfolder, remove the
srcfolder and its files.
- Rename the
- Within the renamed ‘src’ folder create folders for:
src/jscreate a new file labelled:
src/sasscreate a new file labelled:
srcfolder should be similar to the following:
src/index.html created by Wails is used to present the view and content within the desktop app window.
src/index.htmlfile, adding to the HTML
<head>element a link to our new
Lower down in the same
src/index.htmlfile, modify the script tag to source the
Now back in the CLI, change working directory to
At the CLI, install the following npm modules as dev dependencies:
$ npm i -D vite@latestRepeat for each listed npm module.
src/package.jsonfile, which should indicate the installed devDependencies:
Note: that installed version numbers indicated in your package.json file may differ from those above.
Create a Babel configuration file:
src/babel.config.jsonand place within it the following JSON:
Now create a Vite configuration file:
Adding a custom icon for our Desktop app
Our app will need an icon, giving it a unique visual identity wherever it is viewable on a target platform, e.g. the Mac OS Dock and Windows Taskbar.
Create a PNG image file (1024 × 1024 pixels) containing your custom icon artwork and place it within the
buildfolder, replacing the existing file:
Wails will use
appicon.pngas the application icon when building desktop app binaries.
Whilst in the
buildfolder, remove both the
windowsfolders. These will be rebuilt by Wails later, at which point our custom icon file will be utilised.
Set up Go dev environment
- Within the root of the project folder, edit the
go.modfile changing the
modulename, ‘changeme’ declared at the top, to something relevant to you and the project, e.g.
project-domain/project-name– substituting your own project name.
- Remove the
- Create a folder labelled: ‘go’. This folder will hold all the app Go packages and files.
- Within the new
gofolder, create a new subfolder labelled:
IPC(Inter-process Communication), and within that a file labelled:
go/IPC/service.gofile and add to the top:
service.goappend the following:
From the project's root folder, open to edit the
To keeps things simple at this level, the
main.gofile will contain only the definition of options for Wails and its instantiation, it will also import our IPC service API.
We are going to modify the code generated by the Wails initialisation process.
Edit the line embedding the assets for the client view to make sure it now points to our renamed
frontendmaking the embed command read as
distfolder is created by Vite and used by Wails to pull our client-side assets into the desktop app.
We wish also to embed our custom icon into our app binary, so that it can be used within desktop views, e.g. within an ‘About’ view. Add to the
main.gofile the lines:
func main()remove all the contained code and then insert the following line:
We also need to make sure we add to the upper part of
main.goan import statement for:
Further within the
func main()we will configure the Wails app. Add the following to
We also need to make sure we import the required packages:
Connecting up the IPC pipe
However, on the client-side, the IPC is also represented by a global object assigned to the
window object. I favour using the latter.
We can now, within our
src/js/index.js file, establish a connection to the Go app IPC service.
src/jsfolder open to edit
index.jsand add the following:
In the example code above, the
servicereference is a global but could be assigned any way deemed appropriate.
Any methods exported via the Go app service can be accessed via the
servicereference, e.g. to send a request to the Go runtime – using the Service API Request method – we would use:
Let's add some more to our
src/index.js file to make a simple request to the Service IPC to get content for our app main view.
When the Service request is made, we would expect the Promise to resolve with a response object returned from the Service IPC written in Go. The response object carries data with a
contentproperty value, which is set as the text inside our referenced
Let's also add some simple styling for our app view.
Open to edit
src/sass/index.sassand add the following:
Configure Wails for building our app
From the project root folder, open to edit the Wails configuration file:
Change the fields:
outputfilenameto a value you wish to use.
Add fields for:
reloaddirssetting each with the value of
"src". These tell Wails the name of our client code folder, in which it observes the Vite
distdirectory and that files within the
srcfolder should be watched for changes.
wails.jsonfile should now include the following properties and values:
Let's now take the opportunity to test that all is working Ok.
On the CLI in the root of the project folder, i.e. change directory up one level from
Wails will go through steps to prepare the client-side code, run Vite, then build and run a desktop app.
As a result you should see a desktop window open for your app, similar to figure 1 below.
You can exit out of watching mode by either quitting the open app, or pressing
Ctrl+C in the CLI.
Build a final binary
With the development phase working, let's now build a final binary file, one each to run on Mac and Windows.
On the CLI in the root of the project folder, type the build command:
Flags used with the build command:
-cleanremoves previous builds before compiling.
-platformfollowed by the platform types, separated by a comma, informs Wails which OS platforms to build binaries for. See more information on the supported platforms.
-ofollowed by a filename, specifies the output filename and extension to use, although this appears to apply only to Windows binaries.
build/bin should contain two versions of your app: one for Mac and another
.exe file for Windows.
The article outlined:
- Installing and configuring Wails.
- Adding an application custom icon.
- Building final binaries for Mac and Windows.
I hope this article has been helpful for you to begin developing desktop apps with Go and Wails.
Article relevant links:
- Example project files on Github to support this article.
- Go All releases downloads page: https://go.dev/dl/
- Node Downloads page: https://nodejs.org/en/download/
- Wails website: https://wails.io/
- Wails Introduction: https://wails.io/docs/introduction
- Wails Installation: https://wails.io/docs/gettingstarted/installation
- Configuring Vite: https://vitejs.dev/config/
- Rollup Plugins: https://vite-rollup-plugins.patak.dev/
- What is Babel? https://babeljs.io/docs/