charmbracelet/glamour: Markdown Rendering for Go CLI Apps
Stylesheet-based markdown rendering for your CLI apps 💇🏻♀️
At a glance
- What is it?
- Glamour renders Markdown as ANSI-styled terminal output using stylesheets, and it is the rendering layer inside Glow and the GitHub CLI. It is a library, not a program, and its purity is both the design and the constraint.
- Who is it for?
- Adopt Glamour if you are writing a Go CLI that prints Markdown and you want styled output without hand-rolling an ANSI formatter; the module path is charm.land/glamour/v2 and the default styles cover common cases. Do not adopt it if your program is not Go, if you need a standalone renderer binary, or if you cannot accept a renderer that ignores terminal capabilities by default.
- Can I use it commercially?
- Yes. MIT 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 13 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 November 13, 2026, and from our analysis. They are not legal advice.
Star history
- charmbracelet/glamour3,756 ★ · +45
| Repository | 2026-09-24 | 2026-11-13 |
|---|---|---|
| charmbracelet/glamour | 3.7k | 3.8k |
45 Stars in the last 50 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What Glamour Is For, and Who Actually Needs It
If you have ever piped a README into a terminal and watched it arrive as a wall of unformatted text, you have met the problem Glamour exists to solve. Markdown is written for browsers and editors that turn headings, lists, links and code fences into layout. A terminal has no such layer. Glamour takes a Markdown string and returns a string containing ANSI escape sequences, so the same document prints with styled headings, indented lists and syntax-colored code blocks.
The target audience is narrow and specific: Go developers building command-line tools that display Markdown. The README lists the projects that already do this, and the list is a good map of the use case. Glow is a terminal Markdown reader built on it. The GitHub CLI, the GitLab CLI and the Gitea CLI use it to print issue bodies, pull request descriptions and release notes. Meteor uses it in a metadata collection framework. In each case the program is Go, the content is Markdown, and the output is a terminal.
If you are writing a CLI in Rust, Python or TypeScript, Glamour is not available to you. There is no standalone binary documented in the README, no server mode, and no language binding. The deliverable is a Go module, and the README's usage section is Go code from the first line.
How the Rendering Pipeline Works
The dependency list in go.mod tells you most of the architecture. Glamour sits on top of goldmark, the CommonMark parser, with goldmark-emoji added for emoji handling. Parsed content is turned into ANSI output, and the styling vocabulary comes from Lip Gloss. Chroma handles syntax highlighting inside fenced code blocks. Bluemonday appears in the dependency set, which points at HTML sanitization on the input side.
A stylesheet, not the terminal, decides what the output looks like. The README says you can create your own stylesheet or use one of the defaults, and the repository carries a styles directory plus a styles/gallery path for browsing the built-in options. A style is selected by name in the simple API, or by a file path through the environment variable route.
One design decision deserves attention because it shapes everything downstream. The README states that the renderer is designed to be pure and always produce the same output for the same input, and that as a consequence it does not have access to the terminal's capabilities. Color downsampling, the process of reducing a color palette to what a given terminal can display, is therefore not performed by default. Purity here means reproducibility: the same Markdown and the same style yield identical bytes regardless of where they run. That is a defensible property for golden-file testing, and the repository includes a golden testing dependency and a render benchmark file, which suggests the maintainers lean on exactly that property. It is also the source of the most common surprise, covered below.
Installing Glamour and Rendering Your First Document
Glamour is consumed as a Go module. Add it to a project with the module path shown in go.mod, then call the package-level Render function for the shortest possible path to output. The README's first example takes a Markdown string and a style name and returns a string.
import "charm.land/glamour/v2"
in := `# Hello World
This is a simple example of Markdown rendering with Glamour!
Check out the [other examples](https://github.com/charmbracelet/glamour/tree/main/examples) too.
Bye!
`
out, err := glamour.Render(in, "dark")
fmt.Print(out)Print the returned string and you should see the heading styled according to the dark default style. Note that Render returns both a string and an error, so check the error before printing. The README does not specify what conditions produce an error here.
When you need control over layout, build a renderer instead. The README's custom renderer example sets a word wrap width, and notes that the default is 80 columns.
import "charm.land/glamour/v2"
r, _ := glamour.NewTermRenderer(
// wrap output at specific width (default is 80)
glamour.WithWordWrap(40),
)
out, err := r.Render(in)
fmt.Print(out)Style selection has three documented routes. Pass a style name to Render, set the GLAMOUR_STYLE environment variable and call RenderWithEnvironmentConfig, or set GLAMOUR_STYLE and pass WithEnvironmentConfig to your own renderer. The environment variable accepts either a style name or a path to a style file.
If your output looks wrong on a limited-color terminal, the README's answer is to run the rendered string through Lip Gloss before printing, since Glamour itself will not downsample.
import (
"charm.land/glamour/v2"
"charm.land/lipgloss/v2"
)
r, _ := glamour.NewTermRenderer(
// wrap output at specific width (default is 80)
glamour.WithWordWrap(40),
)
out, err := r.Render(in)
if err != nil {
// handle error
}
// downsample colors based on terminal capabilities.
lipgloss.Print(out)That extra step is not optional polish. It is the documented way to get correct colors on terminals that cannot display the full palette the style assumes.
Where Glamour Stops Being the Right Tool
The purity constraint is the sharpest limitation, and it is deliberate. Because the renderer cannot inspect the terminal, it cannot know whether it is writing to a 256-color terminal, a 16-color one, or a pipe being redirected to a file. The output is the same in all three cases. If you print Glamour output directly, a user on a constrained terminal gets escape sequences tuned for capabilities they do not have, and a user redirecting output to a file gets escape sequences in the file. The README's remedy, routing through Lip Gloss, means the surrounding application has to own the terminal-awareness that the renderer refuses to own. That is a reasonable separation of concerns, but it shifts work onto every caller.
The README does not document rollback behavior, and there is no mention of a fallback mode that emits plain text when the output is not a terminal. If your CLI writes Markdown to stdout in a context where it may be piped, you need to handle that case in your own code.
There is also a version boundary worth understanding before you start. The repository carries an UPGRADE_GUIDE_V2.md at the top level, and the module path in go.mod is charm.land/glamour/v2, while the pkg.go.dev badge in the README points at the same v2 path. The most recent release is v2.0.1 from 2026-06-12, preceded by v2.0.0 on 2026-03-09. Anyone copying an older import path from a tutorial or from v1-era code will need to consult that upgrade guide rather than assume the API is unchanged.
Finally, Glamour renders Markdown. It is not a Markdown editor, not a file browser, and not a pager. If what you want is a program that opens a Markdown file in the terminal, that is Glow, which is built on Glamour rather than being a replacement for it.
Glamour Against a General Terminal Styling Library
The closest comparison in the Go ecosystem is Lip Gloss itself, which is already a Glamour dependency and which Glamour's own documentation recommends for the downsampling step. The difference is one of level. Lip Gloss is a general styling toolkit: you compose strings, borders, padding, alignment and color, and you decide what the layout means. It knows nothing about Markdown. Given a heading, Lip Gloss will style whatever string you hand it, but you are the one who has to parse the document, walk the syntax tree, and decide that an h2 gets one treatment and a blockquote gets another.
Glamour inverts that. You hand it a Markdown document and a stylesheet, and it makes all the structural decisions for you. Headings, lists, links, code fences and emphasis all have defined treatments that a style can override. The cost is that you are working inside Markdown's vocabulary. If your output is not Markdown, Glamour has nothing to offer and Lip Gloss is the right starting point. If your output is Markdown and you want it to look like Markdown, writing the parser and the style rules yourself is a substantial amount of work that Glamour has already done, and the README's list of adopters is evidence that the maintainers consider this a solved problem for CLI tools.
The two are not really competitors. Glamour's own documentation tells you to use both, with Glamour producing the styled string and Lip Gloss adapting it to the terminal. The question is only whether your project needs Markdown semantics at all.
Maintenance, Licensing and the Cost of Upgrading
The repository is not archived, and the last push was on 2026-09-22. The release cadence visible in the release list is modest and deliberate: v0.10.0 in April 2025, then a jump to v2.0.0 in March 2026, then v2.0.1 in June 2026. The gap between the v0 and v2 lines is the interesting part. Major version bumps in Go modules are not cosmetic, and the presence of UPGRADE_GUIDE_V2.md at the repository root says the maintainers expect existing users to migrate rather than absorb the change silently.
For adopters, the practical upgrade cost is the import path. The module is charm.land/glamour/v2, and the go.mod file pins go 1.25.13 as the minimum Go version. That is a real constraint: a project on an older Go toolchain cannot simply add this dependency without upgrading the toolchain first. The dependency tree is also not trivial. Lip Gloss, Chroma, goldmark, bluemonday and several Charm and golang.org/x packages come along, and the indirect list in go.mod includes terminal, color and width-handling libraries. None of that is unusual for a rendering library, but it is not a zero-dependency utility either.
The licence is MIT, stated in the README and present as a LICENSE file at the repository root. MIT is permissive: it allows use, modification and redistribution, including in proprietary software, provided the licence text and copyright notice are preserved. That is a description of the licence terms, not legal advice, and anyone with specific concerns about attribution in a distributed binary should read the LICENSE file and consult their own counsel.
Editorial conclusion
Adopt Glamour if you are writing a Go CLI that prints Markdown and you want styled output without hand-rolling an ANSI formatter; the module path is charm.land/glamour/v2 and the default styles cover common cases. Do not adopt it if your program is not Go, if you need a standalone renderer binary, or if you cannot accept a renderer that ignores terminal capabilities by default. Before committing, read UPGRADE_GUIDE_V2.md, because the import path differs from the v1 line, and check whether your existing call sites pass options to NewTermRenderer or rely on the package-level Render function.
Frequently asked questions
How do I install charmbracelet/glamour in a Go project?
Add it as a module dependency with the module path charm.land/glamour/v2, then import it and call glamour.Render with your Markdown string and a style name. The go.mod file requires Go 1.25.13 or later.
How do I use charmbracelet/glamour to render Markdown in a CLI?
Call glamour.Render with the input text and a style name such as dark, then print the returned string. For control over layout, build a renderer with glamour.NewTermRenderer and glamour.WithWordWrap, which defaults to 80 columns.
How do I set a custom style in charmbracelet/glamour?
There are three documented routes: pass a style name to glamour.Render, set the GLAMOUR_STYLE environment variable and call glamour.RenderWithEnvironmentConfig, or set GLAMOUR_STYLE and pass glamour.WithEnvironmentConfig to your own renderer. The variable accepts a style name or a path to a style file.
Why are the colors wrong when I render with charmbracelet/glamour?
The renderer is designed to be pure and does not have access to terminal capabilities, so color downsampling is not performed by default. The README's fix is to pass the rendered output through Lip Gloss before printing.
What is the import path for charmbracelet/glamour v2?
The module path in go.mod is charm.land/glamour/v2, and the README's examples import from that path. The repository includes UPGRADE_GUIDE_V2.md for projects moving from the earlier line.
What licence does charmbracelet/glamour use?
The README states MIT, and a LICENSE file sits at the repository root. MIT permits use, modification and redistribution provided the licence text and copyright notice are kept.
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/charmbracelet-glamour)Star history chart for your README
[](https://hysenlabs.com/projects/charmbracelet-glamour)Was this useful?