Skip to main content

Overview

Glow can be configured through a YAML configuration file, command-line flags, or environment variables. The configuration system uses Viper for flexible configuration management with automatic precedence handling.

The glow config Command

Glow provides a convenient command to edit your configuration:
glow config
This command will:
  1. Create the config file if it doesn’t exist (with defaults)
  2. Open it in your $EDITOR
  3. Save and report the config file location
You can also specify a custom config location:
glow config --config path/to/config.yml
The glow config command uses EDITOR environment variable to determine which editor to launch. If not set, it falls back to sensible defaults based on your system.

Configuration File Location

Glow searches for configuration files in the following order (first match wins):
1

GLOW_CONFIG_HOME environment variable

If set, Glow looks for glow.yml in this directory:
export GLOW_CONFIG_HOME=~/my-configs
# Glow will use ~/my-configs/glow.yml
2

XDG_CONFIG_HOME environment variable

If set, Glow looks in $XDG_CONFIG_HOME/glow/glow.yml:
export XDG_CONFIG_HOME=~/.config
# Glow will use ~/.config/glow/glow.yml
3

Platform-specific config directories

Glow uses go-app-paths to determine the default user config directory:
  • Linux/BSD: ~/.config/glow/glow.yml
  • macOS: ~/Library/Application Support/glow/glow.yml
  • Windows: %APPDATA%\glow\glow.yml
The logic from main.go:426-468:
func tryLoadConfigFromDefaultPlaces() {
    scope := gap.NewScope(gap.User, "glow")
    dirs, err := scope.ConfigDirs()
    if err != nil {
        fmt.Println("Could not load find configuration directory.")
        os.Exit(1)
    }

    if c := os.Getenv("XDG_CONFIG_HOME"); c != "" {
        dirs = append([]string{filepath.Join(c, "glow")}, dirs...)
    }

    if c := os.Getenv("GLOW_CONFIG_HOME"); c != "" {
        dirs = append([]string{c}, dirs...)
    }

    for _, v := range dirs {
        viper.AddConfigPath(v)
    }

    viper.SetConfigName("glow")
    viper.SetConfigType("yaml")
    viper.SetEnvPrefix("glow")
    viper.AutomaticEnv()

    if err := viper.ReadInConfig(); err != nil {
        if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
            log.Warn("Could not parse configuration file", "err", err)
        }
    }
}

Default Configuration

When you run glow config for the first time, this default config is created:
# style name or JSON path (default "auto")
style: "auto"

# mouse support (TUI-mode only)
mouse: false

# use pager to display markdown
pager: false

# word-wrap at width
width: 80

# show all files, including hidden and ignored.
all: false
This default is defined in config_cmd.go:16-26.

Configuration Options

style

Set the rendering style for markdown output. Type: String
Default: "auto" (detects terminal background)
Flag: --style, -s
Options:
  • auto - Automatically choose dark or light based on terminal background
  • dark - Dark theme
  • light - Light theme
  • pink - Pink theme
  • dracula - Dracula theme
  • notty - Plain text (used automatically when piping)
  • Path to custom JSON style file: /path/to/mystyle.json
Example:
style: "dark"
glow README.md --style pink
glow README.md -s ~/.config/glow/ocean.json
If the style is not a built-in name, Glow validates that the file exists at the given path. The path is expanded using utils.ExpandPath() to support ~ and environment variables.

mouse

Enable mouse wheel scrolling in TUI mode. Type: Boolean
Default: false
Flag: --mouse, -m (hidden flag)
TUI-mode only: Yes
Example:
mouse: true
glow --mouse
When enabled, Glow calls tea.WithMouseCellMotion() to enable mouse support in the Bubble Tea program (main.go:44-46).

pager

Pipe rendered output through your system pager (like less). Type: Boolean
Default: false
Flag: --pager, -p
Example:
pager: true
glow README.md --pager
Glow uses the $PAGER environment variable, defaulting to less -r if not set (main.go:316-328).
The pager and tui options are mutually exclusive. Setting both will cause an error: “cannot use both pager and tui” (main.go:175-177).

width

Set the word-wrap width for rendered output. Type: Integer (unsigned)
Default: 0 (auto-detect terminal width, max 120)
Flag: --width, -w
Example:
width: 100
glow README.md --width 100
glow README.md -w 0  # disable word wrap
Behavior:
  • 0 - Auto-detect terminal width (capped at 120 for readability)
  • > 0 - Wrap at specified width
  • If terminal width can’t be detected, falls back to 80

all

Show all files including hidden and .gitignored files in TUI mode. Type: Boolean
Default: false
Flag: --all, -a
TUI-mode only: Yes
Example:
all: true
glow --all
glow -a ~/my-docs
When true, Glow uses gitcha.FindAllFilesExcept() instead of gitcha.FindFilesExcept(), showing files that would normally be ignored by Git (ui/ui.go:384-389).

Additional TUI Options

These options are available via flags but not included in the default config file:

showLineNumbers

Flag: --line-numbers, -l
Type: Boolean
Default: false
TUI-mode only: Yes
glow --line-numbers

preserveNewLines

Flag: --preserve-new-lines, -n
Type: Boolean
Default: false
glow README.md --preserve-new-lines
Tells Glamour to preserve the original newlines in the markdown instead of reformatting spacing.

Viper Configuration Binding

Glow uses Viper to bind command-line flags to configuration values. This means:
  1. Config file is loaded first
  2. Environment variables with GLOW_ prefix override config
  3. Command-line flags override both
The binding is set up in main.go:409-421:
// Config bindings
_ = viper.BindPFlag("pager", rootCmd.Flags().Lookup("pager"))
_ = viper.BindPFlag("tui", rootCmd.Flags().Lookup("tui"))
_ = viper.BindPFlag("style", rootCmd.Flags().Lookup("style"))
_ = viper.BindPFlag("width", rootCmd.Flags().Lookup("width"))
_ = viper.BindPFlag("debug", rootCmd.Flags().Lookup("debug"))
_ = viper.BindPFlag("mouse", rootCmd.Flags().Lookup("mouse"))
_ = viper.BindPFlag("preserveNewLines", rootCmd.Flags().Lookup("preserve-new-lines"))
_ = viper.BindPFlag("showLineNumbers", rootCmd.Flags().Lookup("line-numbers"))
_ = viper.BindPFlag("all", rootCmd.Flags().Lookup("all"))

viper.SetDefault("style", styles.AutoStyle)
viper.SetDefault("width", 0)
viper.SetDefault("all", true)

Environment Variables

Glow supports environment variable configuration with the GLOW_ prefix:
# Set the style
export GLOW_STYLE=dark

# Set width
export GLOW_WIDTH=100

# Enable pager by default
export GLOW_PAGER=true

# Show all files
export GLOW_ALL=true
Viper automatically maps these to the corresponding config keys (via viper.SetEnvPrefix("glow") and viper.AutomaticEnv()).

Special Environment Variables

Some environment variables are read directly by the TUI Config struct:
type Config struct {
    Gopath           string `env:"GOPATH"`
    HomeDir          string `env:"HOME"`
    GlamourStyle     string `env:"GLAMOUR_STYLE"`
    HighPerformancePager bool `env:"GLOW_HIGH_PERFORMANCE_PAGER" envDefault:"true"`
    GlamourEnabled       bool `env:"GLOW_ENABLE_GLAMOUR"         envDefault:"true"`
}
These are parsed using github.com/caarlos0/env:
# Override glamour style for TUI
export GLAMOUR_STYLE=pink

# Disable high-performance rendering
export GLOW_HIGH_PERFORMANCE_PAGER=false

# Disable glamour rendering (debugging)
export GLOW_ENABLE_GLAMOUR=false

Configuration Precedence

Configuration is resolved in this order (highest to lowest priority):
  1. Command-line flags: glow README.md --style dark --width 100
  2. Environment variables: GLOW_STYLE=dark GLOW_WIDTH=100 glow README.md
  3. Config file: Values from glow.yml
  4. Defaults: Hardcoded defaults in Viper and the code

Example Configurations

Minimal Setup

# ~/.config/glow/glow.yml
style: "dark"
width: 100

Power User Setup

# ~/.config/glow/glow.yml
# Use a custom style
style: "/home/user/.config/glow/ocean.json"

# Enable mouse support in TUI
mouse: true

# Always use pager for CLI mode
pager: true

# Wider width for large monitors
width: 120

# Show all files including hidden
all: true

CI/CD Environment

# Use plain style for CI logs
style: "notty"

# Fixed width for consistent output
width: 80

# Never use pager (non-interactive)
pager: false

Validation

Glow validates configuration during startup (main.go:165-208):

Style Validation

func validateStyle(style string) error {
    if style != "auto" && styles.DefaultStyles[style] == nil {
        style = utils.ExpandPath(style)
        if _, err := os.Stat(style); errors.Is(err, fs.ErrNotExist) {
            return fmt.Errorf("specified style does not exist: %s", style)
        } else if err != nil {
            return fmt.Errorf("unable to stat file: %w", err)
        }
    }
    return nil
}
If you specify a custom style file that doesn’t exist, Glow will exit with an error.

Option Conflicts

if pager && tui {
    return errors.New("cannot use both pager and tui")
}
Glow will refuse to start if conflicting options are set.

Troubleshooting

Run glow config and it will tell you the location when it saves.Or check these locations:
# Linux/BSD
ls ~/.config/glow/glow.yml

# macOS
ls ~/Library/Application\ Support/glow/glow.yml

# Custom location
echo $GLOW_CONFIG_HOME
echo $XDG_CONFIG_HOME
Check the precedence:
  1. Are you using command-line flags that override it?
  2. Do you have environment variables set?
  3. Is the config file in the right location?
  4. Is the YAML syntax valid?
You can see which config is loaded by checking Glow’s debug output.
Ensure:
  1. The path is absolute or uses ~ for home directory
  2. The file exists and is readable
  3. The JSON is valid Glamour style format
# Test if file exists
ls -la ~/.config/glow/mystyle.json

# Validate JSON
cat ~/.config/glow/mystyle.json | jq .
Note that --mouse is a hidden flag. Make sure:
  1. Your terminal supports mouse events
  2. You’re in TUI mode (not CLI mode)
  3. The flag is properly set in config or via CLI
mouse: true

TUI Mode

Configure TUI-specific options like mouse and all files

CLI Mode

Set defaults for CLI rendering like pager and width

Build docs developers (and LLMs) love