Lanterna: a text-mode GUI toolkit in pure Java, layered three deep
Java library for creating text-based GUIs
At a glance
- What is it?
- The Java library behind a lot of terminal UIs, organised as terminal, screen, and GUI layers, with a Swing fallback that lets you develop in an IDE.
- Who is it for?
- Lanterna's design decision worth stealing is the layered one: you can drop to raw terminal control when a library API does not fit, use the screen buffer for custom drawing, or use `gui2` for widgets, and each layer is useful on its own. The Swing fallback is the second practical win, since it means the same code runs in an IDE output window during development and on a headless server in production, which is the actual reason many Java terminal tools pick it.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 95 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why a curses library for Java at all
The README states the case plainly: Lanterna is a Java library for writing semi-graphical user interfaces in a text-only environment, very similar to the C library curses but with more functionality. It supports xterm-compatible terminals and emulators such as konsole, gnome-terminal, putty and xterm.
The headline benefit is stated without hedging. Lanterna does not depend on any native library and runs entirely in pure Java. That is a real constraint for a toolkit that has to draw boxes and handle cursor addressing, since the usual approach for Java means loading a JNI library and dealing with native packaging per platform.
The supported-terminal list matters too, and it is a compatibility statement rather than a marketing one. If your target terminal is not xterm-compatible, cursor addressing and modifiers behave differently, and this is the kind of library where that shows up as misaligned boxes rather than an error.
Three layers you pick between, not stack
The architectural claim is that Lanterna is structured into three layers, each built on the other, and you choose the one that fits. That framing is more useful than it sounds, because it means each layer is independently usable.
The first layer is a low-level terminal interface giving the most basic control of the terminal text area: move the cursor around, enable special modifiers for characters written to the screen. Those classes live in `com.googlecode.lanterna.terminal`.
The second is a full screen buffer, the whole text screen in memory, allowing writes before flushing changes to the actual terminal. The README makes the analogy explicit: this makes writing to the terminal screen similar to modifying a bitmap. Classes are in `com.googlecode.lanterna.screen`.
The third is a full GUI toolkit with windows, buttons, labels and other components, using a simple window management system described as basically all windows being modal, which is quick and easy to use. Classes live in `com.googlecode.lanterna.gui2`.
So if you want a status line, layer one is enough. If you are drawing a custom view, layer two. If you want buttons, layer three, and you accept a modal world.
The Swing fallback that makes IDE development work
This is the feature that decides whether you can build a terminal UI at all, and it is buried in the second paragraph of the README.
When Lanterna runs on a machine with a graphical environment, such as Windows or Xorg, a bundled terminal emulator written in Swing is used instead of standard output. The stated benefit is that you can develop as usual from your IDE, because most IDEs do not support ANSI control characters in their output window, and then deploy to a headless server without changing any code.
That is a genuine architectural answer rather than a workaround. Without it, a Swing-based IDE console renders your carefully drawn box-drawing characters as a column of question marks, and you would end up maintaining a separate code path for development.
The repository tree backs the claim with a `native-integration/` directory, alongside `src/`, `docs/`, `pom.xml`, `jitpack.yml` and `License.txt`. Note that the README makes no claim about native integration being required: its stated benefit is the opposite, that nothing native is needed.
The Maven coordinates still carry the old package name
Lanterna is available on Maven Central through Sonatype OSS hosting, and the README gives the coordinates directly:
<dependency>
<groupId>com.googlecode.lanterna</groupId>
<artifactId>lanterna</artifactId>
<version>3.1.2</version>
</dependency>The groupId is the part that surprises people. It reads `com.googlecode.lanterna`, which is a leftover from the project's origin as a Google Code project, long before that service shut down. The library is now maintained by mabe02 under its own name, but the coordinates were kept so existing builds keep resolving. There is nothing wrong with it, and changing it would break every user for no benefit, but it does mean a search for the vendor gives you nothing useful.
The version in the README is 3.1.2. JavaDoc is published for that line at mabe02.github.io, and the README notes that JavaDocs for 2.1 and 3.0 remain available as well, which is a reasonable courtesy for a library where a lot of code is still pinned to older lines.
What the README does not tell you
This is a short README and it is not shy about pointing elsewhere. The development guide is in `docs/contents.md` in the repository, described as containing examples and guides. Discussion happens on a Google group for lanterna-discuss, though the README recommends raising issues directly on GitHub instead.
There is a list of projects using Lanterna and the README flags it as incomplete, inviting additions. The three named are a Clojure binding, a project terminal, and a Scala matrix rain visualiser. That sample is small but informative about the shape of use: other-language wrappers and terminal-native applications rather than mainstream business software.
What is genuinely absent from the README is anything about the programming model. There is no mention of threading, no explanation of how input events are delivered, and no guidance on whether components redraw synchronously. For a library whose third layer is a windowing system, those are not minor details, and they are exactly what a reader will need. They are in the development guide and the JavaDoc, not on this page.
The repository also carries `licenseheader.txt` alongside `License.txt` and a `CHANGELOG.md`, and the license is reported as LGPL-3.0. That is worth pausing on for an application you intend to ship: LGPL obligations attach when you distribute the library rather than merely use it, and the specific terms are in `License.txt`.
Reading the repository shape and the open question count
The tree is compact: `src/`, `docs/`, `native-integration/`, `pom.xml`, `jitpack.yml`, `License.txt`, `licenseheader.txt`, `RELEASE.txt`, `CHANGELOG.md` and `README.md`. A `jitpack.yml` means the project can also be built straight from a commit hash through JitPack, which is useful for pinning a specific fix without waiting for a release.
`RELEASE.txt` sitting separately from `CHANGELOG.md` suggests version notes live in a form the build or maintainer consumes, which is common for Java projects releasing by hand rather than through a plugin.
The number that stands out is 96 open issues against 2,620 stars and 276 forks, which is a much higher open-issue count than the star count alone would suggest for a library this old. The last push to the default branch, `master`, was 2026-07-07. There are no GitHub releases and no homepage field on the repository, so version history has to come from Maven Central and the changelog file rather than from the releases page.
None of that means the library is unmaintained. It means the documentation you would use to judge it is not on the repository front page, and that the published JavaDoc is a better guide to the current state than the README is.
Editorial conclusion
Lanterna's design decision worth stealing is the layered one: you can drop to raw terminal control when a library API does not fit, use the screen buffer for custom drawing, or use `gui2` for widgets, and each layer is useful on its own. The Swing fallback is the second practical win, since it means the same code runs in an IDE output window during development and on a headless server in production, which is the actual reason many Java terminal tools pick it. What the README does not tell you is anything about thread safety, event models, or how components map to specific widgets, and that documentation lives in `docs/contents.md` and the published JavaDoc rather than on this page. Add the Maven dependency at version 3.1.2, start with the screen layer if you are drawing something custom, and read the development guide before reaching for widgets.
Frequently asked questions
What language is lanterna?
Java. The library is published to Maven Central with coordinates `com.googlecode.lanterna:lanterna`, and the README stresses that it runs in pure Java with no native library dependency. The `com.googlecode` groupId is a leftover from the project's original Google Code hosting rather than any involvement with Google today.
What is a lanterna?
In this repository, a Java library for building semi-graphical interfaces in a text terminal, comparable to the C curses library but with more functionality. The word also names a paper lantern and various unrelated things, which is why search results for it are mostly noise.
What are the three layers in Lanterna?
A low-level terminal interface for cursor movement and character modifiers, in the `terminal` package. A full screen buffer held in memory that you write to before flushing, in the `screen` package. And a widget toolkit with windows, buttons and labels, in the `gui2` package, where all windows are modal. Each layer builds on the one below it and each is usable on its own.
Can I develop a Lanterna UI in an IDE on Windows?
Yes, and that is the reason the bundled Swing terminal emulator exists. On a machine with a graphical environment, Lanterna renders through that emulator instead of standard output, because most IDEs do not interpret ANSI control characters in their output window. The same code then runs unchanged on a headless server.
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/mabe02-lanterna)