Wingo: a pure Go X window manager with tiling and a per-monitor workspace model
A fully-featured window manager written in Go.
At a glance
- What is it?
- Wingo is an X11 window manager written entirely in Go, with floating and tiling placement, workspaces per monitor and an INI-style configuration with no recompiling. Its author has put it in maintenance mode, so the project is stable rather than growing.
- Who is it for?
- Adopt Wingo if you want a window manager written in one language with an INI-style config you can edit without recompiling, and if you are willing to run something its author has frozen. Do not adopt it if you need manual tiling, a growing set of layouts, or software that is still being developed.
- Can I use it commercially?
- Yes. WTFPL is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 158 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Maintenance mode is the headline, and it changes the decision
The first thing in the README is a note, and it is the most important fact for anyone evaluating this project. Wingo is in maintenance mode. The author says Wingo is still used every day, but that because there are no tests, it is impossible to add new functionality, and that the work on it will be limited to what is required to make it work.
That is a candid statement of why the project is frozen, and it is worth reading carefully rather than as a formality. The reason given is not funding, not a change of interest, or a rewrite in progress. It is the absence of a test suite, which makes adding behaviour to a window manager risky in a way that it is not for most programs. A window manager sits between you and every window on the screen, and a regression there is not a failing function call but a frozen desktop.
The consequences for an adopter are concrete. You will not get new layouts, new features, or fixes for the features that were never built. You will get a window manager that keeps working, that is complete for what it does, and that is not going to surprise you. The README also describes Wingo as still very alpha and advises saving your work before running it in place of an existing window manager.
The repository is not archived, and the last push was on 2026-05-19. There are no GitHub releases, so there is no version to pin and no changelog to read. The default branch is master.
For a daily driver, a frozen window manager with a complete feature set is a perfectly reasonable proposition. For a platform team that expects upstream contributions, it is not.
Everything in Go, down to the font rendering
Wingo is an X window manager written in pure Go, and the README stresses that all of its dependencies are also in Go, from communicating with X up to drawing text on windows. That is the project's distinguishing technical claim, and it is verifiable from the module file.
go.mod requires github.com/BurntSushi/xgb, which is a pure Go implementation of the X protocol, rather than cgo bindings to libX11. Alongside it sit github.com/BurntSushi/xgbutil for X utility functions, github.com/BurntSushi/freetype-go for font rasterisation, github.com/BurntSushi/graphics-go for drawing, github.com/BurntSushi/gribble for the command system, github.com/BurntSushi/xdg for the XDG directories, github.com/BurntSushi/cmd for subprocess handling, and github.com/str1ngs/ansi for terminal escapes. The module requires Go 1.26.3.
The consequence is a build with no C toolchain, which matters for portability and for anyone who has fought a cgo dependency on a cross-compile. The trade is that you are bound to what these libraries cover. The README says Wingo is mostly ICCCM and EWMH compliant, and the repository carries a COMPLIANCE file, an ewmh_supported.go file, and a scripts/generate-supported script that regenerates that file, which is how the project tracks which EWMH properties it handles.
The Makefile shows the shape of the codebase. There are packages for the core window manager logic, layout, stack, focus, frame, heads, hook, prompt, render, text, workspace, wm, and the X client layer. The install target builds them all with go install, and the data directory holds embedded assets: the wingo.png icon, close, maximize and minimize button images, a DejaVuSans.ttf font, and a wingo.wav sound, all compiled into the binary with go-bindata style .syso and .c files. Nothing about the theme is fetched at runtime.
Installing it, replacing your window manager, and writing a fresh config
Installation assumes you already have Go installed and configured. The README gives a single command:
go get github.com/BurntSushi/wingoFor Arch Linux users the README notes that Wingo is in the AUR. The Makefile also carries an install target that builds the binary and every subpackage, plus a cmd target that installs wingo-cmd on its own, and a Makefile entry named supported that regenerates the EWMH support file.
The first start is normally from an xinitrc, and the README gives the exact line:
exec wingoIf you want to try it alongside a desktop environment, Wingo can take over from the current window manager:
wingo --replaceThe README is direct about the risk here: save your work, Wingo is still very alpha, and the phrasing is deliberately jokey. A window manager that replaces the running one and then misbehaves leaves you with a session you may not be able to recover without a keyboard shortcut you have not memorised yet.
A fresh set of configuration files is written with:
wingo --write-configThat places them in $HOME/.config/wingo, and each file is heavily documented. The INSTALL file at the top level of the repository is the reference for the build and install procedure, and HOWTO-CONFIGURE covers the configuration format in more depth than the README does.
INI-style config with variable substitution, and the Gribble command system
The configuration story is one of the project's real strengths, and the README is almost proud of it. All configuration uses an INI-like file format with support for simple variable substitution, which the author says makes theming a bit simpler. The pitch is concise: no XML, no recompiling, no scripting.
Bindings are not special-cased. Any of a large number of commands can be bound to a key or mouse press, window decorations can be themed, and hooks can be set up to fire on a set of match conditions. The command system is called Gribble.
The example in the README adds a named workspace:
AddWorkspace "cromulent"And then shows how to make it interactive by nesting the Input command as an argument, which pops up a graphical prompt and passes the typed text through:
AddWorkspace (Input "Enter your workspace name:")The HOWTO-COMMANDS file holds the full reference, and the author says the README has barely scratched the surface. The commands directory at the top level of the repository is where the command implementations live, and the hook/ directory handles the conditional firing.
The variable substitution deserves attention for theming, since it lets a theme define colours once and refer to them from several decoration definitions, rather than repeating literal values that drift apart when you change one of them.
wingo-cmd gives Wingo an IPC surface for scripting
The README first claims there is no scripting, then immediately corrects itself: you can kind of script Wingo using its IPC mechanism. The client is a separate binary that has to be installed:
go get github.com/BurntSushi/wingo/wingo-cmdWith Wingo running, you send it any command:
wingo-cmd 'AddWorkspace "embiggen"'The client can also describe a command without running it, which prints the parameters, their types and a description:
wingo-cmd --usage AddWorkspaceAnd it can list every command, with parameters and usage, even when Wingo is not running:
wingo-cmd --list-usageThe interesting capability is that commands can return data, which turns the window manager into something other pipelines can read. The README pipes the active window name into dzen2, polled every 500 milliseconds:
wingo-cmd --poll 500 'GetClientName (GetActive)' | dzen2That pattern generalises. The README notes that Wingo can provide enough information for people to script their own layouts in whatever language they like without ever dealing with X, provided the language can connect to unix domain sockets. In other words, the IPC layer is a public interface, not just a debugging convenience, and it is the part of Wingo most likely to be built on by others.
The ipc.go file at the repository root is the client side of this, and the wingo-cmd/ directory holds the command line tool.
Workspaces per monitor, and the EWMH assumption it breaks
The feature that sets Wingo apart, in the author's framing, is the combination of two things. The first is support for both floating and tiling placement policies. Wingo works as a regular floating or stacking window manager with decorations, maximization, sticky windows and the other expected features, and it can switch into a tiling mode where decorations disappear and windows are managed by tiling. The second is workspaces per monitor, where each monitor can display its own workspace independently of the others, and because placement policy is a property of the workspace, one monitor can be tiling while another is floating.
The author is quick to name the cost, and the README puts a warning on it. The workspaces-per-monitor model violates an implicit assumption made by EWMH, that one and only one workspace may be viewable at any point in time. As a result, in multi-head setups, pagers and taskbars may operate in confusing ways. In a single head setup, they should continue to operate normally. Wingo provides prompts that allow you to add and remove workspaces and select clients, which the author suggests may reduce the need for a pager or a taskbar at all.
That is an honest trade rather than a bug. If your workflow depends on a taskbar reflecting one global workspace model, the per-monitor behaviour will confuse you. If you use one monitor, the warning does not apply.
On tiling, the README is brief. Only simple tiling layouts are available, vertical and horizontal, and the reason given is that those are the layouts the author primarily uses, with more to be added as they are demanded. Manual tiling, where the user places a window, is something the author would like to add but describes as more complex, because it introduces the concept of containers, and containers can hold zero or more windows and an empty container may have focus. Wingo knows nothing about containers, and that is the reason it is not there.
What a frozen window manager means for your setup
The configuration model is a plain INI-like file in $HOME/.config/wingo, and that has a practical consequence worth spelling out. Because there is no scripting and no recompiling, a change to your layout or bindings is a text edit and a reload, and because the config is data rather than code, it diffs cleanly, which is exactly what you want if you keep your dotfiles in git and move between machines.
The counterweight is the same design decision seen from another angle. With no scripting layer beyond the Gribble command system, an unusual workflow that other window managers handle with a script has to be expressed as a command binding, a hook condition, or handled outside Wingo through wingo-cmd. The IPC path is a genuine escape hatch, and it is the one to plan around, but it means writing a small program rather than dropping a file into a config directory.
There is also a licensing angle worth a sentence rather than a paragraph. The licence is WTFPL, and the repository carries a COPYING file. The README's joke title aside, this is a very permissive licence, so there is nothing to clear before running it, and nothing to clear before reading its source to answer a question the documentation does not answer. HACKING and STYLE at the top level cover how to work on the code itself, and the githooks/ directory and session.vim file suggest the project carries a development environment with the author's own conventions.
The bottom line for an adopter is that you are choosing a complete, pleasant, small window manager that has stopped changing, in exchange for a workflow that is configuration-driven and readable. The exchange is a good one for a personal machine that runs X, and a poor one for anyone who expects the tool to grow with their needs.
Editorial conclusion
Adopt Wingo if you want a window manager written in one language with an INI-style config you can edit without recompiling, and if you are willing to run something its author has frozen. Do not adopt it if you need manual tiling, a growing set of layouts, or software that is still being developed. Verify first that your Go version satisfies the go 1.26.3 directive in go.mod, that your X server exposes the EWMH properties listed in COMPLIANCE, and that the workspace-per-monitor model is acceptable given the EWMH conflict the README documents, because a pager and a taskbar will behave confusingly on a multi-head setup.
Frequently asked questions
Is Wingo still being developed?
The README states the repository is in maintenance mode: Wingo is still used every day, but because there are no tests it is impossible to add new functionality, and work is limited to what is needed to make it work. The last push was on 2026-05-19 and there are no GitHub releases.
How do I install Wingo and start it?
With Go installed and configured, run `go get github.com/BurntSushi/wingo` and put `exec wingo` in your $HOME/.xinitrc. Wingo is also in the AUR for Arch Linux, and `wingo --replace` swaps it for a running window manager.
How do I configure Wingo without recompiling?
Configuration uses an INI-like file format with simple variable substitution. `wingo --write-config` writes a fresh documented set of files to $HOME/.config/wingo, and key or mouse bindings, decoration themes and hooks are all expressed through the Gribble command system.
Can I script Wingo from another program?
Yes, through the wingo-cmd client, installed with `go get github.com/BurntSushi/wingo/wingo-cmd`. It can send commands, print usage for a single command or list all of them, and poll a command on an interval, for example piping the active window name into dzen2.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/burntsushi-wingo)Was this useful?