npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@oakoliver/glamour

v2.0.0

Published

Stylesheet-based markdown rendering for the terminal — a pure TypeScript port of charmbracelet/glamour

Downloads

334

Readme

@oakoliver/glamour

Stylesheet-based Markdown rendering for terminals. This TypeScript port tracks charmbracelet/glamour v2.0.1 and preserves the package's existing TypeScript API.

Glamour rendering a markdown document with headings, a syntax-highlighted TypeScript code block, a table and a task list in a terminal

Features

  • ANSI rendering with 16-color, 256-color, true-color, and no-color profiles
  • Seven built-in themes: dark, light, ascii, dracula, tokyo-night, pink, notty
  • CommonMark/GFM links, tables, task lists, strikethrough, code, and autolinks
  • Definition lists and opt-in GitHub emoji shortcodes
  • Table wrapping/truncation and inline or numbered-footer table links
  • OSC 8 hyperlinks, base-URL resolution, syntax highlighting, and CJK-aware wrapping
  • Node.js and Bun support

Install

npm install @oakoliver/glamour

Quick Start

import { render, renderWithStyle } from '@oakoliver/glamour';

// Render with the default dark theme
const output = render('# Hello World\n\nThis is **bold** and *italic* text.');
console.log(output);

// Render with a specific theme
const light = renderWithStyle('# Hello\n\nParagraph text.', 'light');
console.log(light);

Themes

Built-in themes: dark, light, ascii, dracula, tokyo-night, pink, notty.

The same markdown rendered with the dark, dracula, tokyo-night and ascii themes

The same release notes rendered with dracula and tokyo-night side by side, placed next to each other with @oakoliver/lipgloss: headings, a right-aligned table, nested lists, task items, a block quote and links

The light theme rendered in a light terminal

import { renderWithStyle } from '@oakoliver/glamour';

const out = renderWithStyle('# Dracula Theme\n\n> A blockquote', 'dracula');

Advanced Usage

Use TermRenderer for full control over rendering options:

import { TermRenderer, withStandardStyle, withWordWrap } from '@oakoliver/glamour';

const renderer = new TermRenderer(
  withStandardStyle('dark'),
  withWordWrap(100),
);

const output = renderer.render('# Custom Rendering\n\nWith word wrap at 100 columns.');
console.log(output);

Custom Styles

Pass a StyleConfig object to fully customize how each markdown element is rendered:

import { TermRenderer, withStyles } from '@oakoliver/glamour';
import type { StyleConfig } from '@oakoliver/glamour';

const myStyle: StyleConfig = {
  heading: { bold: true, color: '#ff6600', prefix: '>>> ' },
  paragraph: { margin: 1 },
  code: { prefix: '`', suffix: '`', color: '#00ff00' },
};

const renderer = new TermRenderer(withStyles(myStyle));
const output = renderer.render('# Orange Heading\n\nCustom styling.');

Output of the custom StyleConfig above: orange headings prefixed with >>> and green inline code

API

Top-level Functions

  • render(markdown, stylePath?) — Render with the default or selected style.
  • renderWithStyle(markdown, style) — Render with a named built-in style.
  • renderBytes(markdown, stylePath?) — Render to a Buffer.
  • renderWithEnvironmentConfig(markdown) — Read GLAMOUR_STYLE.

TermRenderer

  • new TermRenderer(...options) / newTermRenderer(...options) — Create a renderer.
  • renderer.render(markdown) / renderer.renderBytes(markdown) — Render immediately.
  • renderer.write(chunk), renderer.close(), renderer.read() — Buffered writer chain.

Option Functions

  • withStandardStyle, withStylePath, withStyles
  • withStylesFromJSON, withStylesFromJSONBytes, withStylesFromJSONFile
  • withWordWrap, withTableWrap, withInlineTableLinks
  • withPreservedNewLines, withBaseURL, withEmoji
  • withChromaFormatter, withColorProfile, withHyperlinks
  • withEnvironmentConfig, withAutoStyle, withOptions

Parser

The custom GFM parser is also exported for direct use:

import { parse, NodeKind } from '@oakoliver/glamour';

const ast = parse('# Hello\n\nWorld');
// Walk the AST...

Parity with Glamour v2.0.1

Apart from the differences below, output is byte-for-byte identical to Glamour v2.0.1. The test suite checks this against golden files rendered by the real Go library (every fixture in all seven styles at widths 40 and 80, plus Glamour's own renderer test corpus); the generator lives in tests/golden/generate.

Known differences:

  • Syntax highlighting. Upstream lexes code blocks with chroma; this port uses highlight.js mapped onto the same chroma style entries and writes tokens the way chroma's terminal formatters do. Text, wrapping and layout match, but token boundaries, and so the colors of individual tokens, can differ. Code in unknown or unspecified languages renders as plain text, as with chroma's fallback lexer, and matches exactly.
  • Named chroma themes. A code_block.theme without code_block.chroma rules (e.g. "solarized-dark") selects one of chroma's built-in palettes upstream. Those palettes are not ported; such blocks use the code_block colors.
  • Chroma theme registration. Upstream registers its code theme globally the first time it highlights code, so later renders with a different style in the same process reuse the first style's code colors. This port always uses the current style's colors. Where two palette colors are equally close to a style color, upstream's choice varies between runs; this port picks the first.
  • Default style. new TermRenderer() without a style option uses the dark style; upstream starts with an empty style.

Platform-specific behavior

Upstream styles.GetDefaultStyle("auto") (used by WithAutoStyle) probes the terminal background through Go's termenv.HasDarkBackground. Node.js and Bun do not expose an equivalent cross-platform terminal-background query, so this port resolves auto deterministically to the dark style. Explicit light and dark selection remains fully supported.

Examples

The pictures in this README are real output, recorded with @oakoliver/vhs from the tapes in assets/tapes. Run the examples yourself:

bun examples/render.ts examples/sample.md            # dark theme
bun examples/render.ts examples/theme.md dracula     # any built-in theme
bun examples/custom-style.ts                         # custom StyleConfig
bun examples/side-by-side.ts                         # two styles side by side (needs @oakoliver/lipgloss >= 1.1.0)

Attribution

This is a TypeScript port of glamour by Charmbracelet, Inc., licensed under MIT.

License

MIT