Desktop App Development
Grit supports building native desktop applications with Wails. One command scaffolds a complete desktop project with Go backend, React frontend, authentication, CRUD, data export, and GORM Studio -- all compiled into a single executable.
What is Grit Desktop?
Grit Desktop extends the framework beyond web applications. Using Wails, it combines a Go backend with a React frontend (Vite + TanStack Router + TanStack Query) to produce native desktop apps for Windows, macOS, and Linux.
This single command generates a fully working desktop application with SQLite or PostgreSQL, JWT authentication, blog and contact CRUD, PDF and Excel export, a custom title bar, dark theme, and GORM Studio for database browsing.
Install Grit
You need Go 1.21+, Node.js 18+, and Wails v2 installed. Then install the Grit CLI:
Scaffold a new desktop app and start developing:
Architecture
Instead of HTTP requests between client and server, Wails uses direct Go bindings. The React frontend calls Go functions directly, with Wails handling the bridge between the two runtimes.
Go Backend (Wails Bindings)
Business logic lives in Go structs. Methods on the App struct are automatically exposed to the frontend via Wails bindings. No HTTP server needed.
React Frontend (Vite)
A Vite-powered React app with TanStack Router (file-based routing) and TanStack Query for state management. Calls Go functions through the generated Wails bindings.
SQLite / PostgreSQL
GORM handles the database layer. SQLite is the default for portable desktop apps. PostgreSQL is supported for networked setups.
Single Binary Output
The entire application -- Go backend, React frontend, and all assets -- compiles into a single executable that you distribute.
Routing with TanStack Router
Grit Desktop uses TanStack Router with file-based routing. Instead of declaring routes in a centralized file, each page is a self-contained route file in the routes/ directory. The TanStack Router Vite plugin automatically discovers route files and generates a type-safe route tree at build time.
File-Based Routes
Each page is a file in routes/_layout/. The filename determines the URL: blogs.index.tsx maps to /blogs, blogs.$id.edit.tsx maps to /blogs/:id/edit. No route registry to maintain.
Type-Safe Navigation
Route params, search params, and navigation are fully typed. Route.useParams() returns typed params scoped to the current route. navigate({ to: "/blogs/$id/edit", params: { id } }) is validated at compile time.
Pathless Layouts
The _layout.tsx file creates a layout route (auth guard + sidebar) without adding a URL segment. All pages inside _layout/ inherit this wrapper automatically.
Zero-Config for Generation
When grit generate resource creates a new resource, it simply creates route files. No imports to add, no route registry to update. Deleting a resource just deletes the files.
TanStack Router uses createHashHistory() for desktop apps, so routes work correctly when the app is loaded from disk (no web server needed). The Vite plugin generates routeTree.gen.ts automatically — this file is gitignored and regenerated on every build.
Built-in Features
Every scaffolded desktop project includes the following out of the box:
Web vs Desktop
Both modes share Grit conventions (GORM models, code generation, Studio), but the runtime and distribution model are different.
| Aspect | Web (grit new) | Desktop (grit new-desktop) |
|---|---|---|
| Backend | Gin HTTP server | Wails bindings (direct Go calls) |
| Frontend | Next.js (App Router) | Vite + React + TanStack Router |
| Database | PostgreSQL | SQLite (default) or PostgreSQL |
| Project Structure | Turborepo monorepo | Single project directory |
| State Management | React Query + fetch | React Query + Wails bindings |
| Distribution | Deploy to cloud / VPS | Distribute .exe / .app / binary |