wails dev loop

Hot reload + dev tools.

6 mineasy

wails dev is Wails's hot-reload loop — Vite for the frontend, recompiles + reloads Go on save. ~1 second iteration for small changes. This lesson covers the loop + the dev tools.

Start it

Terminal
$cd field-pos
$wails dev

First run takes ~30s — installs npm deps, compiles Go, opens a window. Save a React file, the window reloads. Save app.go, Wails rebuilds Go and re-launches.

The two-way bridge

Wails Go-to-React binding

┌──────────────────────┐ │ main.go │ │ wails.Run({ │ │ Bind: []{ │ │ app, │ │ } │ │ }) │ └──────────┬───────────┘ │ │ generates ▼ ┌──────────────────────┐ │ frontend/wailsjs/ │ │ go/main/App.d.ts │ │ go/main/App.js │ │ │ │ App.GetUser(id) │ │ returns User │ └──────────┬───────────┘ │ │ imported by ▼ ┌──────────────────────┐ │ src/SomeComp.tsx │ │ │ │ GetUser(id) │ │ .then(user => …) │ └──────────────────────┘
One bind call exposes a Go method to the React side as a typed Promise. The wailsjs/ folder is auto-generated at build.

Whatever struct + method you expose in Go shows up in TypeScript with full types. No REST plumbing. No JSON-encoding boilerplate.

Exposing your first Go method

app.go
type App struct {
ctx context.Context
db *gorm.DB
}
// Exported = bound to React. Method name in TS = same.
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s from Go!", name)
}

And in React:

src/App.tsx
import { Greet } from '../wailsjs/go/main/App'
function App() {
const [greeting, setGreeting] = useState('')
return (
<button onClick={async () => setGreeting(await Greet('Alex'))}>
{greeting || 'Click me'}
</button>
)
}

Click the button — React calls Greet, Go runs, the return value lands in greeting. Zero plumbing.

The dev tools

  • Right-click in the app window → Inspect. Opens Chrome DevTools on the embedded WebView. Network tab, console, React DevTools — all the usual things.
  • Wails terminal output. Anything you log.Println in Go shows here. Add prints liberally while developing.
  • Hot reload paths. React: instant. Go: ~1-2s rebuild + window relaunch. Hot reload doesn't preserve state across Go changes — you re-login each time.
State loss on Go change. Saving an app.go file rebuilds + relaunches the binary, so any in-memory React state resets. Persist what you need to SQLite or localStorage so you don't lose work.

The first build is slow

First wails dev in a fresh project: ~30-60s. Subsequent starts: ~5s. The slow first start is npm install + Go module resolution. Be patient on day one.

Quick check

You added a new method to your Go App struct. You save the file. wails dev rebuilds. You try to call it from React but TypeScript says it doesn't exist. What's the cause?

Try it

Build the call-Go-from-React loop end-to-end:

  1. Add a Greet(name string) string method to app.go.
  2. In src/App.tsx, import it and wire it to a button.
  3. Run wails dev.
  4. Click the button — confirm the greeting appears.

Paste a screenshot of the working window in notes.md.

What's next

Last lesson of the chapter — wails build. Produce a real .exe / .app / .deb you can run without the CLI.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled — suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub