Frontend Runtime
The Wails frontend runtime is the standard library for Wails applications. It provides a number of features that may be used in your applications, including:
- Window management
- Dialogs
- Browser integration
- Clipboard
- Menus
- System information
- Events
- Context Menus
- Screens
- WML (Wails Markup Language)
The runtime is required for integration between Go and the frontend. There are 2 ways to integrate the runtime:
- Using the
@wailsio/runtimepackage - Using a pre-built bundle
Using the npm package
Section titled “Using the npm package”The @wailsio/runtime package is a JavaScript package that provides access to
the Wails runtime from the frontend. It is used by all standard templates
and is the recommended way to integrate the runtime into your application.
By using the @wailsio/runtime package, you will only include the parts of the runtime that you use.
The package is available on npm and can be installed using:
npm install --save @wailsio/runtimeUsing a pre-built bundle
Section titled “Using a pre-built bundle”Some projects will not use a Javascript bundler and may prefer to use a pre-built bundled version of the runtime. This version can be generated locally using the following command:
wails3 generate runtimeThe command will output a runtime.js (and runtime.debug.js) file in the current
directory. This file is an ES module that can be imported by your application scripts
just like the npm package, but the API is also exported to the global window object,
so for simpler applications you can use it as follows:
<html> <head> <script type="module" src="./runtime.js"></script> <script> window.onload = function () { wails.Window.SetTitle("A new window title"); } </script> </head> <!--- ... --></html>Initialisation
Section titled “Initialisation”Apart from the API functions, the runtime provides support for context menus and window dragging. These features will only work as expected after the runtime has been initialised. Even if you don’t use the API, make sure to include a side-effect import statement somewhere in your frontend code:
import "@wailsio/runtime";Your bundler should detect the presence of side-effects and include all required initialisation code in the build.
Vite Plugin for Typed Events
Section titled “Vite Plugin for Typed Events”The runtime includes a Vite plugin that enables HMR (Hot Module Replacement) support for typed events during development.
Add the plugin to your vite.config.ts:
import { defineConfig } from 'vite'import wails from '@wailsio/runtime/plugins/vite'
export default defineConfig({ plugins: [wails()],})Benefits
Section titled “Benefits”- Automatic Reloading: Event bindings are automatically regenerated and reloaded when you run
wails3 generate bindings - Development Mode: Works seamlessly with
wails3 devfor instant updates - Type Safety: Full TypeScript support with autocomplete and type checking
Usage with Event Registration
Section titled “Usage with Event Registration”Register your events in Go:
type UserData struct { ID string Name string}
func init() { application.RegisterEvent[UserData]("user-updated")}Generate bindings:
wails3 generate bindings
# Or, to include TypeScript definitionswails3 generate bindings -ts
# For more options, see:wails3 generate bindings -helpUse typed events in your frontend:
import { Events } from '@wailsio/runtime'import { UserUpdated } from './bindings/events'
// Type-safe event with autocompleteEvents.Emit(UserUpdated({ ID: "123", Name: "John Doe"}))API Reference
Section titled “API Reference”The runtime is organized into modules, each providing specific functionality. Import only what you need:
import { Events, Window, Clipboard } from '@wailsio/runtime'Events
Section titled “Events”Event system for communication between Go and JavaScript.
Register a callback for an event.
function On(eventName: string, callback: (event: WailsEvent) => void): () => voidfunction On<T>(eventType: EventType<T>, callback: (event: WailsEvent<T>) => void): () => voidReturns: Unsubscribe function
Example:
import { Events } from '@wailsio/runtime'
// Basic event listeningconst unsubscribe = Events.On('user-logged-in', (event) => { console.log('User:', event.data.username)})
// With typed events (TypeScript)import { UserLogin } from './bindings/events'
Events.On(UserLogin, (event) => { // event.data is typed as UserLoginData console.log('User:', event.data.username)})
// Later: unsubscribe()Once()
Section titled “Once()”Register a callback that runs only once.
function Once(eventName: string, callback: (event: WailsEvent) => void): () => voidfunction Once<T>(eventType: EventType<T>, callback: (event: WailsEvent<T>) => void): () => voidExample:
import { Events } from '@wailsio/runtime'
Events.Once('app-ready', () => { console.log('App initialized')})Emit()
Section titled “Emit()”Emit an event to Go backend or other windows.
function Emit(name: string, data?: any): Promise<boolean>function Emit<T>(event: Event<T>): Promise<boolean>Returns: Promise that resolves to true if the event was cancelled, false otherwise
Example:
import { Events } from '@wailsio/runtime'
// Basic event emissionconst wasCancelled = await Events.Emit('button-clicked', { buttonId: 'submit' })
// With typed events (TypeScript)import { UserLogin } from './bindings/events'
const cancelled = await Events.Emit(UserLogin({ UserID: "123", Username: "john_doe", LoginTime: new Date().toISOString()}))
if (cancelled) { console.log('Login was cancelled by a hook')}Remove event listeners.
function Off(...eventNames: string[]): voidExample:
import { Events } from '@wailsio/runtime'
Events.Off('user-logged-in', 'user-logged-out')OffAll()
Section titled “OffAll()”Remove all event listeners.
function OffAll(): voidWindow
Section titled “Window”Window management methods. The default export is the current window.
import { Window } from '@wailsio/runtime'
// Current windowawait Window.SetTitle('New Title')await Window.Center()
// Get another windowconst otherWindow = Window.Get('secondary')await otherWindow.Show()Visibility
Section titled “Visibility”Show() - Shows the window
function Show(): Promise<void>Hide() - Hides the window
function Hide(): Promise<void>Close() - Closes the window
function Close(): Promise<void>Size and Position
Section titled “Size and Position”SetSize(width, height) - Sets window size
function SetSize(width: number, height: number): Promise<void>Size() - Gets window size
function Size(): Promise<{ width: number, height: number }>SetPosition(x, y) - Sets absolute position
function SetPosition(x: number, y: number): Promise<void>Position() - Gets absolute position
function Position(): Promise<{ x: number, y: number }>Center() - Centers the window
function Center(): Promise<void>Example:
import { Window } from '@wailsio/runtime'
// Resize and centerawait Window.SetSize(800, 600)await Window.Center()
// Get current sizeconst { width, height } = await Window.Size()Window State
Section titled “Window State”Minimise() - Minimizes the window
function Minimise(): Promise<void>Maximise() - Maximizes the window
function Maximise(): Promise<void>Fullscreen() - Enters fullscreen
function Fullscreen(): Promise<void>Restore() - Restores from minimized/maximized/fullscreen
function Restore(): Promise<void>IsMinimised() - Checks if minimized
function IsMinimised(): Promise<boolean>IsMaximised() - Checks if maximized
function IsMaximised(): Promise<boolean>IsFullscreen() - Checks if fullscreen
function IsFullscreen(): Promise<boolean>Window Properties
Section titled “Window Properties”SetTitle(title) - Sets window title
function SetTitle(title: string): Promise<void>Name() - Gets window name
function Name(): Promise<string>SetBackgroundColour(r, g, b, a) - Sets background color
function SetBackgroundColour(r: number, g: number, b: number, a: number): Promise<void>SetAlwaysOnTop(alwaysOnTop) - Keeps window on top
function SetAlwaysOnTop(alwaysOnTop: boolean): Promise<void>SetResizable(resizable) - Makes window resizable
function SetResizable(resizable: boolean): Promise<void>Focus and Screen
Section titled “Focus and Screen”Focus() - Focuses the window
function Focus(): Promise<void>IsFocused() - Checks if focused
function IsFocused(): Promise<boolean>GetScreen() - Gets the screen the window is on
function GetScreen(): Promise<Screen>Content
Section titled “Content”Reload() - Reloads the page
function Reload(): Promise<void>ForceReload() - Forces page reload (clears cache)
function ForceReload(): Promise<void>SetZoom(level) - Sets zoom level
function SetZoom(level: number): Promise<void>GetZoom() - Gets zoom level
function GetZoom(): Promise<number>ZoomIn() - Increases zoom
function ZoomIn(): Promise<void>ZoomOut() - Decreases zoom
function ZoomOut(): Promise<void>ZoomReset() - Resets zoom to 100%
function ZoomReset(): Promise<void>Printing
Section titled “Printing”Print() - Opens the native print dialog
function Print(): Promise<void>Example:
import { Window } from '@wailsio/runtime'
// Open print dialog for current windowawait Window.Print()Note: This opens the native OS print dialog, allowing the user to select printer settings and print the current window content. Unlike window.print() which may not work in webviews, this uses the native platform printing API.
Clipboard
Section titled “Clipboard”Clipboard operations.
SetText()
Section titled “SetText()”Set clipboard text.
function SetText(text: string): Promise<void>Example:
import { Clipboard } from '@wailsio/runtime'
await Clipboard.SetText('Hello from Wails!')Text()
Section titled “Text()”Get clipboard text.
function Text(): Promise<string>Example:
import { Clipboard } from '@wailsio/runtime'
const clipboardText = await Clipboard.Text()console.log('Clipboard:', clipboardText)System
Section titled “System”Low-level system methods for direct communication with the backend.
invoke()
Section titled “invoke()”Sends a raw message directly to the backend. This bypasses the standard binding system and is handled by the RawMessageHandler in your application options.
function invoke(message: any): voidExample:
import { System } from '@wailsio/runtime'
// Send a raw message to the backendSystem.invoke('my-custom-message')
// Send structured data as JSONSystem.invoke(JSON.stringify({ action: 'update', value: 42 }))For more details, see the Raw Messages Guide.
Application
Section titled “Application”Application-level methods.
Show()
Section titled “Show()”Shows all application windows.
function Show(): Promise<void>Hide()
Section titled “Hide()”Hides all application windows.
function Hide(): Promise<void>Quit()
Section titled “Quit()”Quits the application.
function Quit(): Promise<void>Example:
import { Application } from '@wailsio/runtime'
// Add quit buttondocument.getElementById('quit-btn').addEventListener('click', async () => { await Application.Quit()})Browser
Section titled “Browser”Open URLs in the default browser.
OpenURL()
Section titled “OpenURL()”Opens a URL in the system browser.
function OpenURL(url: string | URL): Promise<void>Example:
import { Browser } from '@wailsio/runtime'
await Browser.OpenURL('https://wails.io')Screens
Section titled “Screens”Screen information and management.
GetAll()
Section titled “GetAll()”Gets all screens.
function GetAll(): Promise<Screen[]>GetPrimary()
Section titled “GetPrimary()”Gets the primary screen.
function GetPrimary(): Promise<Screen>GetCurrent()
Section titled “GetCurrent()”Gets the current active screen.
function GetCurrent(): Promise<Screen>Screen Interface:
interface Screen { ID: string Name: string ScaleFactor: number X: number Y: number Size: { Width: number, Height: number } Bounds: { X: number, Y: number, Width: number, Height: number } WorkArea: { X: number, Y: number, Width: number, Height: number } IsPrimary: boolean Rotation: number}Example:
import { Screens } from '@wailsio/runtime'
// List all screensconst screens = await Screens.GetAll()screens.forEach(screen => { console.log(`${screen.Name}: ${screen.Size.Width}x${screen.Size.Height}`)})
// Get primary screenconst primary = await Screens.GetPrimary()console.log('Primary screen:', primary.Name)Dialogs
Section titled “Dialogs”Native OS dialogs from JavaScript.
Info()
Section titled “Info()”Shows an information dialog.
function Info(options: MessageDialogOptions): Promise<string>Example:
import { Dialogs } from '@wailsio/runtime'
await Dialogs.Info({ Title: 'Success', Message: 'Operation completed successfully!'})Error()
Section titled “Error()”Shows an error dialog.
function Error(options: MessageDialogOptions): Promise<string>Warning()
Section titled “Warning()”Shows a warning dialog.
function Warning(options: MessageDialogOptions): Promise<string>Question()
Section titled “Question()”Shows a question dialog with custom buttons.
function Question(options: QuestionDialogOptions): Promise<string>Example:
import { Dialogs } from '@wailsio/runtime'
const result = await Dialogs.Question({ Title: 'Confirm Delete', Message: 'Are you sure you want to delete this file?', Buttons: [ { Label: 'Delete', IsDefault: false }, { Label: 'Cancel', IsDefault: true } ]})
if (result === 'Delete') { // Delete the file}OpenFile()
Section titled “OpenFile()”Shows a file open dialog.
function OpenFile(options: OpenFileDialogOptions): Promise<string | string[]>Example:
import { Dialogs } from '@wailsio/runtime'
const file = await Dialogs.OpenFile({ Title: 'Select Image', Filters: [ { DisplayName: 'Images', Pattern: '*.png;*.jpg;*.jpeg' }, { DisplayName: 'All Files', Pattern: '*.*' } ]})
if (file) { console.log('Selected:', file)}SaveFile()
Section titled “SaveFile()”Shows a file save dialog.
function SaveFile(options: SaveFileDialogOptions): Promise<string>WML (Wails Markup Language)
Section titled “WML (Wails Markup Language)”WML provides declarative attributes for common actions. Add attributes to HTML elements:
Attributes
Section titled “Attributes”wml-event - Emits an event when clicked
<button wml-event="save-clicked">Save</button>wml-window - Calls a window method
<button wml-window="Close">Close Window</button><button wml-window="Minimise">Minimize</button>wml-target-window - Specifies target window for wml-window
<button wml-window="Show" wml-target-window="settings"> Show Settings</button>wml-openurl - Opens a URL in the browser
<a href="#" wml-openurl="https://wails.io">Visit Wails</a>wml-confirm - Shows confirmation dialog before action
<button wml-window="Close" wml-confirm="Are you sure you want to close?"> Close</button>Example:
<div> <button wml-event="save-clicked">Save</button> <button wml-window="Minimise">Minimize</button> <button wml-window="Close" wml-confirm="Close window?">Close</button> <a href="#" wml-openurl="https://github.com/wailsapp/wails">GitHub</a></div>Complete Example
Section titled “Complete Example”import { Events, Window, Clipboard, Dialogs, Screens } from '@wailsio/runtime'
// Listen for events from GoEvents.On('data-updated', (event) => { console.log('Data:', event.data) updateUI(event.data)})
// Window managementdocument.getElementById('center-btn').addEventListener('click', async () => { await Window.Center()})
document.getElementById('fullscreen-btn').addEventListener('click', async () => { const isFullscreen = await Window.IsFullscreen() if (isFullscreen) { await Window.UnFullscreen() } else { await Window.Fullscreen() }})
// Clipboard operationsdocument.getElementById('copy-btn').addEventListener('click', async () => { await Clipboard.SetText('Copied from Wails!')})
// Dialog with confirmationdocument.getElementById('delete-btn').addEventListener('click', async () => { const result = await Dialogs.Question({ Title: 'Confirm', Message: 'Delete this item?', Buttons: [ { Label: 'Delete' }, { Label: 'Cancel', IsDefault: true } ] })
if (result === 'Delete') { await Events.Emit('delete-item', { id: currentItemId }) }})
// Screen informationconst screens = await Screens.GetAll()console.log(`Detected ${screens.length} screen(s)`)screens.forEach(screen => { console.log(`- ${screen.Name}: ${screen.Size.Width}x${screen.Size.Height}`)})Best Practices
Section titled “Best Practices”- Import selectively - Only import what you need
- Handle promises - All methods return promises
- Use WML for simple actions - Cleaner than JavaScript
- Check return values - Especially for dialogs
- Unsubscribe events - Clean up when done
❌ Don’t
Section titled “❌ Don’t”- Don’t forget await - Most methods are async
- Don’t block UI - Use async/await properly
- Don’t ignore errors - Always handle rejections
TypeScript Support
Section titled “TypeScript Support”The runtime includes full TypeScript definitions:
import { Events, Window } from '@wailsio/runtime'
Events.On('custom-event', (event) => { // TypeScript knows event.data, event.name, event.sender console.log(event.data)})
// All methods are fully typedconst size: { width: number, height: number } = await Window.Size()