iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To create a GTK window in Haskell, use the haskell-gi bindings: construct a Gtk.Application, connect its activation callback, create an application window in that callback, and run the application event loop. The callback is where your program responds when GTK activates the app; it is not just a one-time window-construction function.
Choose the Haskell GTK binding
The haskell-gi project provides generated Haskell bindings for GObject-based libraries, including GTK 4. Its README demonstrates a GTK 4 application using GI.Gtk, facilities from Data.GI.Base, Gtk.Application, an activation handler, and Gtk.ApplicationWindow. The GTK Project’s getting-started tutorial explains the underlying GTK concepts, but its code examples are in C; use the binding documentation for Haskell-specific syntax and APIs.
This first window uses the direct, imperative binding style shown in the project README. The README also links to higher-level approaches, but their current maintenance and suitability are not established here, so they are not needed to get a basic app running.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Prepare the toolchain and dependencies
You need a working GHC and Cabal setup, GTK 4 development files, and GObject Introspection support. The required system package names and installation steps vary by operating system. The haskell-gi README gives platform-specific installation guidance and directs Windows users to its Windows instructions; follow the current instructions for your platform rather than assuming a package name from another operating system.
#1 Best Overall
For a Cabal project, add gi-gtk4 and haskell-gi-base as dependencies. The README’s inline example declares base >= 4.16; that is a constraint in that example, not a universal recommendation for every project. Its record-dot syntax uses OverloadedRecordDot, which requires GHC 9.2 or later. Confirm compatible package and compiler versions in your own project configuration.
Create and run the application
GTK applications normally enter through Gtk.Application. It provides lifecycle behavior beyond initializing a window: the GTK API describes application uniqueness, session management, desktop-shell integration, exported actions and menus, and lifecycle tracking of top-level windows. GTK recommends using it with Gtk.ApplicationWindow.
Rank #2
The following is the shape of the Haskell implementation in the haskell-gi README. It shows the essential calls; adapt imports, callback syntax, and dependency versions to the current README and your project setup.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
{-# LANGUAGE OverloadedRecordDot #-}
import qualified GI.Gtk as Gtk
import Data.GI.Base
main :: IO ()
main = do
app <- new Gtk.Application
[ #applicationId := "org.example.FirstGtkApp" ]
on app #activate $ application -> do
window <- new Gtk.ApplicationWindow
[ #application := application
, #title := "First GTK window"
]
window.present
app.run Nothing
- Create the application. Give it a stable application ID. The example ID is illustrative; choose one appropriate to your own app.
- Connect activation. The
activatehandler is the entry point for setting up or presenting the app’s primary window. - Create an application window. Associate the window with the application, set a title, and present it from the handler.
- Run the app. Calling
app.runstarts GTK’s event loop. The program then waits for events and dispatches them to handlers instead of simply constructing a window and exiting.
GTK 4’s window API uses present in this example. The binding README distinguishes GTK 4’s window.show form from the GTK 3 showAll form; do not transfer older GTK 3 tutorials’ calls into a GTK 4 program without checking the binding API.
Rank #3
Understand activation and window reuse
Activation is not guaranteed to happen only once. GTK’s Gtk.Application API reference warns that activation, open, and command-line handlers can be emitted multiple times. A handler that always constructs a new window can therefore produce duplicates. In a fuller application, look up an existing active window and present it when appropriate; create a new one only when none should be reused.
The GTK Project’s C-based Getting Started with GTK 4 tutorial follows the same lifecycle: create the application, connect activate, run the application, and create and present a window from the callback. It also describes GTK as event-driven: “GTK is event-driven. The toolkit listens for events such as a click on a button, and passes the event to your application.”
Rank #4
Add a widget and connect an event
Once the empty window opens, give it a child widget. GTK windows act as the main container in a widget hierarchy; buttons and input fields are examples of child widgets. Then connect a callback to the widget’s event or signal so your Haskell code can respond to user action. GTK’s getting-started tutorial builds incrementally from an empty window to a button, a useful order for debugging: first verify application startup and window presentation, then add widgets and handlers.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsKnow what this first window does not include
A window that runs locally is the starting point, not a fully integrated desktop release. GTK’s getting-started material also discusses distribution and desktop integration, including an application binary, desktop file, icon, optional settings schema, and other resources. Those packaging tasks are separate from creating and running the first window.
Best Value
The GTK reference page used here identifies GTK library version 4.24.1 and generated documentation version 2026.1. The haskell-gi README is a rolling project page, so its dependency and installation details can change. Check the linked documentation and your platform’s current packages when setting up a new project.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

