Brick: A Declarative Haskell Toolkit for Terminal User Interfaces
A declarative Unix terminal UI library written in Haskell
At a glance
- What is it?
- Brick is a Haskell TUI library that describes interfaces as functions of application state and handles input through event transformation. It builds on vty and uses declarative layout combinators instead of a widget construction sequence.
- Who is it for?
- Brick fits Haskell developers building interactive terminal applications that benefit from declarative layout and pure state transformation. It is less suitable for projects that need a web interface, a non-terminal desktop UI, or a toolkit with no dependency on vty.
- Can I use it commercially?
- Yes. BSD-3-Clause 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 27 days ago.
- What is it written in?
- Mainly Haskell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Brick's State and Rendering Model
Brick targets interactive terminal programs written in Haskell. Its central design is a pure function that describes how the interface should appear from the current application state, paired with a state transformation function that handles incoming events. This separates the description of a screen from the decision about what the next screen should represent.
The distinction matters for terminal applications because a terminal interface must continually respond to resizing, key events, and application-level state changes. Brick's model gives the programmer a place to express those concerns separately: a rendering function describes the current interface, while an event handler updates the state that drives the next render. The README does not claim that Brick removes all event-loop or terminal setup work. It presents the programming model as the main API benefit.
The intended users are Haskell developers who want to build TUIs without assembling a long sequence of widget creation and layout calls. Brick is also relevant to tools that behave like small interactive applications rather than ordinary command-line filters. Its examples include games, account viewers, file managers, monitoring interfaces, and Haskell toolchain frontends. Those examples indicate a library aimed at full terminal interaction rather than a narrow display component.
Declarative Layout Combinators in Brick
Brick exposes declarative layout combinators for constructing an interface. The README's example combines a labeled border, centered text, and a vertical divider into one layout expression. The expression is short because each combinator describes a structural relationship instead of asking the application to manage coordinates through a separate construction procedure.
The example uses `joinBorders`, `withBorderStyle`, `borderWithLabel`, `str`, `center`, and the `<+>` and `vBorder` combinators. This is a useful indication of the API's direction. Text is represented with `str`, containers are composed through layout operators, and decoration is added around an existing widget. The example does not demonstrate every available primitive, but it makes clear that layout is expressed as a value that can be composed.
This approach can make a screen definition easier to inspect than a long imperative construction sequence. It also gives application state a direct role in rendering, since the function that produces the layout can choose different content based on state. The tradeoff is that developers still need to understand the underlying terminal model. Brick states that it builds upon vty, and some knowledge of vty is necessary. Brick is therefore a higher-level interface over terminal rendering rather than an independent terminal backend.
Vty, Platform Support, and the Layering Boundary
Brick depends on `vty-crossplatform`, and the README says that Brick should work anywhere Vty works on Unix and Windows. The current version's platform boundary is different from older Brick releases: releases prior to 2.0 only supported Unix-based systems. That distinction should be checked when selecting a version for a cross-platform application.
The dependency also defines the kinds of issues that may belong outside Brick. Terminal capability detection, rendering primitives, and low-level terminal behavior are associated with Vty according to the README. Brick adds application-facing layout and event transformation concepts, but it does not present itself as a replacement for Vty. A developer debugging terminal compatibility may therefore need to consult both projects rather than treating Brick as the whole terminal stack.
This layering is a concrete adoption constraint for teams that already have a different rendering architecture. A project built around a browser, a desktop GUI, or a non-Vty terminal abstraction will not gain much by adopting Brick. Even for a terminal application, the application may need to account for terminal dimensions and event types defined below Brick's API. The README does not document a higher-level compatibility matrix, so platform claims should be confirmed against the relevant Brick and Vty releases.
Repository Structure and Available Examples
The repository contains `src/`, `tests/`, `programs/`, `docs/`, and supporting Haskell package files such as `brick.cabal`, `Setup.hs`, and `cabal.config`. The README points readers to `programs/ReadmeDemo.hs` for the interface example, which gives the documentation a concrete starting point beyond the short README snippet.
The repository also includes `FAQ.md`, `CHANGELOG.md`, and a `LICENSE` file. The project is distributed under BSD-3-Clause. The presence of tests and a changelog shows that the repository has dedicated areas for verification and release history, although the README does not describe test commands, compatibility guarantees, or a release process. There are no GitHub releases listed for the repository.
The README's featured project list includes applications such as `ghcup`, `hledger-ui`, `clifm`, `matterhorn`, `hledger-iadd`, and several games and utilities. These are examples of projects using Brick, not claims that Brick provides their domain features. Their range suggests that the library is general enough for account tooling, developer utilities, communication clients, and interactive command-line workflows. It does not establish how many production applications depend on it.
Installing Brick and Running the README Demo
The README does not give an installation command, package-manager invocation, or a complete dependency setup procedure. It identifies the Haskell package and links conceptually to vty through the package description, while the repository includes `brick.cabal` and related Cabal files. The repository therefore provides Haskell package metadata, but the README does not state the exact command a new user should run.
The first concrete use documented by the project is the layout expression from `programs/ReadmeDemo.hs`. The following is the interface fragment shown in the README:
joinBorders $
withBorderStyle unicode $
borderWithLabel (str "Hello!") $
(center (str "Left") <+> vBorder <+> center (str "Right"))This fragment combines a joined border structure, selects the Unicode border style, adds a label, and arranges two centered text regions with a vertical border between them. According to the README, its result is a labeled box containing `Left` and `Right`. A reader following the example should expect that structure once the fragment is placed in a complete Brick application and rendered through the surrounding Vty setup.
The README does not show the imports, event handler, initialization call, or runnable `main` for the demo. It also does not document a rollback procedure for an installation. Those omissions matter for a first-use tutorial: the layout demonstrates the declarative API, but the excerpt alone is not a complete application.
Where Brick Is the Wrong Tool
Brick is the wrong choice when the required interface is not a terminal interface. The library depends on Vty and is designed for terminals, so it does not provide a browser rendering model, a native desktop widget hierarchy, or a screen-independent graphical canvas. Its layout combinators also do not replace application-specific models for files, accounts, network requests, or persistence.
A second limitation is conceptual. Brick's declarative API does not remove the need to define application state and event semantics. If a product requires immediate-mode graphical interactions, hardware-accelerated rendering, or a platform-specific desktop integration, those requirements exceed the scope described by the README. A command-line program that only prints output or accepts a finite input sequence may also gain little from adopting a full TUI toolkit.
The README is intentionally focused on the library's main idea and examples. It does not document performance limits, terminal feature fallbacks, accessibility behavior, or migration procedures. Those omissions do not prove that such issues exist, but they mean an adopter must verify them rather than infer guarantees from the API style.
Brick Compared with Direct Vty Application Code
The closest architectural alternative is direct application code on top of vty. Vty provides the lower terminal abstraction that Brick explicitly builds upon. An application written directly against vty would handle more of the rendering and layout details itself, while Brick supplies a declarative set of layout combinators and an application-level pattern centered on rendering from state.
This difference is not a replacement of one library with another at the same level. Brick reduces the amount of interface description written as an imperative widget and layout construction sequence. Direct vty work gives the programmer finer control over the underlying terminal layer, but it also removes Brick's higher-level composition model. The README specifically contrasts Brick with toolkits that require long widget creation and layout setup sequences.
For a Haskell TUI, Brick is the more direct fit when the application naturally has a state value and a pure description of its current screen. Direct vty code is the relevant comparison when low-level terminal behavior is central to the application. The README does not provide a feature-by-feature comparison or migration instructions, so the choice should be based on the boundary between Brick's layout API and the Vty behavior an application is prepared to own.
Maintenance, License, and Upgrade Boundaries
The repository is not archived, and its last push was on 2026-09-26. That is recent activity in the repository history, but the repository has no GitHub releases listed. The README does not define a release cadence, supported Haskell compiler range, or long-term compatibility policy. The absence of GitHub releases is a repository fact, not evidence that releases are unavailable through another channel.
Brick is licensed under BSD-3-Clause. The license identifier indicates the stated licensing model, but it does not by itself answer application-specific compliance questions. An organization should inspect the repository's `LICENSE` file and account for the licenses of `vty`, `vty-crossplatform`, and other dependencies when distributing an application.
Upgrades require attention to the Vty boundary and the documented platform change. Applications moving across Brick versions should check `CHANGELOG.md`, the package metadata in `brick.cabal`, and the corresponding Vty dependency behavior. The README does not provide a dedicated upgrade guide, rollback command, or migration procedure.
Editorial conclusion
Brick fits Haskell developers building interactive terminal applications that benefit from declarative layout and pure state transformation. It is less suitable for projects that need a web interface, a non-terminal desktop UI, or a toolkit with no dependency on vty. Before adoption, verify the application can work with vty and the terminal platforms you intend to support, then confirm that the project's event model and layout primitives cover the required interface.
Frequently asked questions
What is Brick used for in Haskell?
Brick is a terminal user interface programming toolkit. It lets developers describe an interface as a function of application state and transform that state when handling events.
Does Brick support Windows?
The README says Brick depends on `vty-crossplatform` and should work anywhere Vty works on Unix and Windows. Releases prior to 2.0 only supported Unix-based systems.
Does Brick require Vty knowledge?
The README states that some knowledge of Vty is necessary because Brick is built upon vty. Brick provides declarative layout and event-handling patterns above that terminal layer.
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/jtdaugherty-brick)Was this useful?