Documentation Index
Fetch the complete documentation index at: https://mintlify.com/charmbracelet/glow/llms.txt
Use this file to discover all available pages before exploring further.
Glow can render markdown from various sources, making it flexible for different workflows.
Local Files
Render any markdown file by providing its path:
glow /path/to/document.md
glow ~/Documents/notes.md
Glow supports both relative and absolute paths, with automatic expansion of ~ and environment variables.
Directories
When you provide a directory path, Glow searches for README files:
glow .
glow /path/to/project
README Discovery
Glow searches for these filenames in order (main.go:35):
readmeNames = []string{"README.md", "README", "Readme.md", "Readme", "readme.md", "readme"}
The discovery process (main.go:112-131):
st, err := os.Stat(arg)
if err == nil && st.IsDir() {
var src *source
_ = filepath.Walk(arg, func(path string, _ os.FileInfo, err error) error {
if err != nil {
return err
}
for _, v := range readmeNames {
if strings.EqualFold(filepath.Base(path), v) {
r, err := os.Open(path)
if err != nil {
continue
}
u, _ := filepath.Abs(path)
src = &source{r, u}
// abort filepath.Walk
return errors.New("source found")
}
}
return nil
})
Glow walks through the directory and renders the first matching README file found.
Read markdown from stdin using - or by piping content:
Explicit stdin with Dash
echo "# Hello World" | glow -
Automatic Pipe Detection
Glow automatically detects piped input:
curl https://example.com/doc.md | glow
The pipe detection logic (main.go:211-220):
func stdinIsPipe() (bool, error) {
stat, err := os.Stdin.Stat()
if err != nil {
return false, fmt.Errorf("unable to open file: %w", err)
}
if stat.Mode()&os.ModeCharDevice == 0 || stat.Size() > 0 {
return true, nil
}
return false, nil
}
HTTP/HTTPS URLs
Fetch and render markdown from any HTTP(S) URL:
glow https://raw.githubusercontent.com/charmbracelet/glow/main/README.md
glow https://example.com/documentation.md
The URL handling (main.go:87-102):
// HTTP(S) URLs:
if u, err := url.ParseRequestURI(arg); err == nil && strings.Contains(arg, "://") {
if u.Scheme != "" {
if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("%s is not a supported protocol", u.Scheme)
}
resp, err := http.Get(u.String())
if err != nil {
return nil, fmt.Errorf("unable to get url: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP status %d", resp.StatusCode)
}
return &source{resp.Body, u.String()}, nil
}
}
Only http:// and https:// protocols are supported. Other schemes will return an error.
GitHub Repositories
Glow provides convenient shortcuts for GitHub repositories:
GitHub URL Patterns
# Standard GitHub URL
glow https://github.com/charmbracelet/glow
# Without protocol
glow github.com/charmbracelet/glow
# Using github:// protocol
glow github://charmbracelet/glow
All three formats fetch the repository’s README using the GitHub API.
GitHub API Integration
Glow uses the GitHub API to find the README (github.go:14-57):
func findGitHubREADME(u *url.URL) (*source, error) {
owner, repo, ok := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
if !ok {
return nil, fmt.Errorf("invalid url: %s", u.String())
}
type readme struct {
DownloadURL string `json:"download_url"`
}
apiURL := fmt.Sprintf("https://api.%s/repos/%s/%s/readme", u.Hostname(), owner, repo)
res, err := http.Get(apiURL)
if err != nil {
return nil, fmt.Errorf("unable to get url: %w", err)
}
This approach:
- Parses owner and repository from the URL
- Calls GitHub’s README API endpoint
- Downloads the README content
- Works regardless of README filename (README.md, readme.md, etc.)
GitLab Repositories
Similar to GitHub, Glow supports GitLab repository shortcuts:
GitLab URL Patterns
# Standard GitLab URL
glow https://gitlab.com/owner/project
# Without protocol
glow gitlab.com/owner/project
# Using gitlab:// protocol
glow gitlab://owner/project
GitLab API Integration
Glow uses the GitLab API v4 (gitlab.go:14-61):
func findGitLabREADME(u *url.URL) (*source, error) {
owner, repo, ok := strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")
if !ok {
return nil, fmt.Errorf("invalid url: %s", u.String())
}
projectPath := url.QueryEscape(owner + "/" + repo)
type readme struct {
ReadmeURL string `json:"readme_url"`
}
apiURL := fmt.Sprintf("https://%s/api/v4/projects/%s", u.Hostname(), projectPath)
The process:
- Extracts owner and project name
- URL-encodes the project path
- Calls GitLab’s projects API
- Converts blob URL to raw URL for content
- Downloads the README
Source Resolution Order
Glow resolves sources in this order (main.go:72-148):
Check for stdin (-)
If argument is -, read from standard input
Try GitHub/GitLab URL
Attempt to parse as GitHub or GitLab repository
Try HTTP(S) URL
Parse as regular HTTP/HTTPS URL
Try Directory
Check if path is directory and search for README
Try Local File
Attempt to open as local file
Examples
Local Files and Directories
# Current directory's README
glow
# Specific file
glow CHANGELOG.md
# Directory with README
glow ~/projects/myapp
Remote Sources
# GitHub shortcut
glow github.com/charmbracelet/glow
# GitLab project
glow gitlab.com/gitlab-org/gitlab
# Direct markdown URL
glow https://raw.githubusercontent.com/owner/repo/main/docs/guide.md
# From pipe
cat notes.md | glow
# From heredoc
glow <<EOF
# Quick Note
This is **important**!
EOF
# From curl
curl -s https://example.com/api/docs.md | glow
Combining with Other Flags
# GitHub repo with custom style
glow github.com/charmbracelet/glow --style pink
# URL with pager
glow https://example.com/doc.md --pager
# Stdin with custom width
echo "# Test" | glow --width 60
When working with GitHub or GitLab repositories, using the URL shortcuts is faster than navigating to the raw file URL, as Glow handles README discovery automatically.