{"id":51098011,"url":"https://github.com/gastonmorixe/mdstream","last_synced_at":"2026-06-24T08:02:16.224Z","repository":{"id":356191495,"uuid":"1192191227","full_name":"gastonmorixe/mdstream","owner":"gastonmorixe","description":"🌊 Markdown renderer for TUI in Rust. Modern real-time byte-by-byte.","archived":false,"fork":false,"pushed_at":"2026-05-07T02:28:37.000Z","size":158,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T03:13:11.552Z","etag":null,"topics":["color","formatter","markdown","markdown-formatter","markdown-render","markdown-viewer","md","rust","stream","terminal","tui"],"latest_commit_sha":null,"homepage":"https://gastonmorixe.com/mdstream","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gastonmorixe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-26T01:20:59.000Z","updated_at":"2026-05-07T02:28:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/gastonmorixe/mdstream","commit_stats":null,"previous_names":["gastonmorixe/mdstream"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/gastonmorixe/mdstream","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gastonmorixe%2Fmdstream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gastonmorixe%2Fmdstream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gastonmorixe%2Fmdstream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gastonmorixe%2Fmdstream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gastonmorixe","download_url":"https://codeload.github.com/gastonmorixe/mdstream/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gastonmorixe%2Fmdstream/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34722710,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["color","formatter","markdown","markdown-formatter","markdown-render","markdown-viewer","md","rust","stream","terminal","tui"],"created_at":"2026-06-24T08:02:14.009Z","updated_at":"2026-06-24T08:02:16.215Z","avatar_url":"https://github.com/gastonmorixe.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🌊 mdstream\n\n### Beautiful, byte-by-byte Markdown for your terminal.\n\n*Pipe in a stream. Watch it bloom in full color, in real time.*\n\n**⚡ Fast** \u0026nbsp;·\u0026nbsp; **🎨 24-bit color** \u0026nbsp;·\u0026nbsp; **🪄 Live re-render** \u0026nbsp;·\u0026nbsp; **📡 Real-time** \u0026nbsp;·\u0026nbsp; **🦀 Pure Rust**\n\n[![Release](https://img.shields.io/github/v/tag/gastonmorixe/mdstream?label=release\u0026color=blue\u0026logo=rust\u0026logoColor=white)](https://github.com/gastonmorixe/mdstream/releases)\n[![Edition](https://img.shields.io/badge/edition-2024-orange?logo=rust\u0026logoColor=white)](https://doc.rust-lang.org/edition-guide/rust-2024/index.html)\n[![MSRV](https://img.shields.io/badge/MSRV-1.94%2B-blueviolet?logo=rust\u0026logoColor=white)](https://blog.rust-lang.org/)\n[![Stars](https://img.shields.io/github/stars/gastonmorixe/mdstream?style=flat\u0026logo=github\u0026logoColor=white)](https://github.com/gastonmorixe/mdstream/stargazers)\n\n\u003c/div\u003e\n\nmdstream renders Markdown **the moment it arrives**. Pipe a partial document in and watch each line resolve into styled output as soon as its newline lands. Tables *repaint in place* when new rows show up. Code blocks pick up syntax highlighting. It's built for **streaming text producers** and anything else that emits text **a token at a time**.\n\nDocs: [streaming renderer internals](docs/how-mdstream-streaming-renderer-works.md)\nChangelog: [CHANGELOG.md](CHANGELOG.md)\n\n## Why mdstream\n\nMost terminal Markdown renderers **wait for stdin to close** before drawing anything. That's fine for files. It's painful for any stream where output trickles in *word by word* and you want to read along.\n\nmdstream takes the **opposite approach**. Raw partial lines stream straight to the terminal so you see characters appear *instantly*. The moment a newline arrives, the line is **erased and re-rendered** with full styling. Block-level state (tables, code fences, lists) persists across the stream so everything stays coherent. The result feels like a *chat UI*, but it's a plain terminal pipeline.\n\n## Features\n\n- 🌊 **Hybrid streaming**: raw character echo while bytes arrive, full re-render the moment a newline lands. EOF flushes any unterminated tail.\n- 🎨 **24-bit true color**: heading levels, list bullets, code highlighting, link styles, and table separators all carry SGR colors.\n- 📰 **Six heading levels**: distinct color for each. H1 underlined with `━`, H2 with a dimmed `─`, H3-H6 bold-colored only.\n- 📋 **Lists**: depth-rotating bullets (`•◦▪‣`), vertical indent guides, hierarchical ordered numbering (write `1.2.3. Section` literally and it renders), task checkboxes (`✔` / `☐`), and continuation-line alignment.\n- 📊 **Pipe tables**: promotion on the separator row, in-place repaint as new rows arrive, three alignment modes (left, right, center), and Unicode-correct column widths.\n- 💻 **Fenced code blocks**: `syntect`-backed highlighting with bundled built-in themes, vendored third-party themes, a custom mdstream house theme, foreground-only rendering by default, optional themed backgrounds, optional line numbers, and language-specific label colors for ~30 common languages including Rust, Python, JS/TS, Go, Ruby, Java, Swift, Bash, Zig, Elixir, Haskell, and friends.\n- ✨ **Inline formatting**: bold, italic, bold+italic, strikethrough, code spans, links, images, autolinks, bare URLs (with adjacency guard), and backslash escapes for the full Markdown punctuation set.\n- 💬 **Blockquotes**: depth tracking, tab- and unicode-whitespace-tolerant parsing, and dimmed `│` bars.\n- 🌐 **True Unicode display width**: via `unicode-width`, so CJK, fullwidth digits, and emoji all align correctly inside tables and wrap math.\n- 🛡️ **Broken-pipe safe**: piping into `head` or quitting `less` exits cleanly with code 0.\n- 📦 **Single static binary**: pure Rust, no C dependencies (`syntect` runs in `default-fancy` mode).\n\n## Install\n\n### Prebuilt release binaries\n\nEach versioned tag publishes `.tar.gz` archives for:\n\n- Linux x86_64\n- Linux arm64\n- macOS arm64\n\nDownload the archive for your platform from the [GitHub Releases page](https://github.com/gastonmorixe/mdstream/releases), extract it, and place the `mdstream` binary somewhere on your `$PATH`.\n\n### Build and install from source\n\n```bash\ngit clone https://github.com/gastonmorixe/mdstream\ncd mdstream\ncargo install --path .\n```\n\nThe `mdstream` binary lands in `~/.cargo/bin`. Make sure that directory is on your `$PATH`.\n\n## Quick examples\n\n```bash\n# Preview a slow stream\n{ printf '# Quicksort\\n'; sleep 0.5; printf '\\n'; sleep 0.5; printf '- divide\\n'; sleep 0.5; printf '- partition\\n'; } | mdstream\n\n# Render a file\nmdstream \u003c README.md\n\n# Stream a remote document\ncurl -sL https://raw.githubusercontent.com/owner/repo/main/README.md | mdstream\n\n# Page a long document (note the -R for ANSI escapes)\nmdstream \u003c long.md | less -R\n\n# Indent for centered terminals\nMDSTREAM_PADDING=4 mdstream \u003c README.md\n\n# Hide line numbers in code blocks\nmdstream --no-lineno \u003c script.md\n\n# Switch code highlighting theme\nmdstream --theme solarized-dark \u003c README.md\n\n# Try one of the bundled third-party themes\nmdstream --theme catppuccin-mocha \u003c README.md\n\n# Opt into themed code-block backgrounds\nmdstream --code-background \u003c README.md\n\n# Fake a slow stream and watch lines bloom in real time\n{ for s in '# Hello' '' '- one' '- two' '- three'; do echo \"$s\"; sleep 0.5; done; } | mdstream\n```\n\n## What gets rendered\n\n| Element | Markdown | Rendered as |\n|---|---|---|\n| Heading H1 | `# Title` | bold red, underlined with `━` |\n| Heading H2 | `## Title` | bold orange, underlined with dim `─` |\n| Heading H3-H6 | `### Title` | bold colored text (green, blue, purple, magenta) |\n| Horizontal rule | `---` | dim 40-char `─` |\n| Unordered list | `- item` | depth-rotating bullet (`•◦▪‣`) with vertical guides |\n| Ordered list | `1. item` | bold marker; literal `1.2.3.` is also accepted |\n| Task list | `- [x] done` | green `✔` / dim `☐` |\n| Blockquote | `\u003e quoted` | dim `│` prefix, depth-aware |\n| Code span | `` `code` `` | bold violet accent, no background |\n| Bold | `**text**` | bold |\n| Italic | `*text*` | italic |\n| Bold + italic | `***text***` | bold and italic |\n| Strikethrough | `~~text~~` | strikethrough |\n| Link | `[label](url)` | underlined blue label, dim url in parens |\n| Image | `![alt](url)` | `Image:` tag, magenta label, dim url |\n| Bare URL | `https://...` | underlined blue (skipped if glued to a word) |\n| Pipe table | `\\| h \\| ... \\|` | bold centered header, `━`/`─` separators, `│` columns |\n| Code fence | ```` ```rust ```` | colored language label, line numbers, syntect theme colors, optional backgrounds |\n\n## Configuration\n\nmdstream takes flags or environment variables. **Flags win** when both are set.\n\n| Flag | Environment variable | Default | Description |\n|---|---|---|---|\n| `--padding N` | `MDSTREAM_PADDING` | `0` | Left padding in spaces |\n| `--no-lineno` | `MDSTREAM_NO_LINENO` | off | Hide line numbers in fenced code blocks |\n| `--no-list-guides` | `MDSTREAM_NO_LIST_GUIDES` | off | Hide vertical guides on nested lists |\n| `--theme THEME` | `MDSTREAM_THEME` | `mdstream` | Code theme for fenced code blocks |\n| `--inline-code-color COLOR` | `MDSTREAM_INLINE_CODE_COLOR` | `h5` | Inline code accent from the `h1`-`h6` palette |\n| `--code-background` | `MDSTREAM_CODE_BACKGROUND` | off | Enable themed backgrounds in fenced code blocks |\n| `--no-code-background` | `MDSTREAM_NO_CODE_BACKGROUND` | off | Disable themed backgrounds in fenced code blocks |\n| `--table-fit` | `MDSTREAM_TABLE_FIT` | off | Cap tables at the live terminal width, soft-wrapping cells only when the natural table would overflow (auto-disables when no width can be detected) |\n| `--table-width-offset N` | `MDSTREAM_TABLE_WIDTH_OFFSET` | `0` | Cells to add (+) or subtract (-) from the table-fit cap width |\n\nRun `mdstream --help` for the full surface.\n\n## CI and releases\n\nThe repo has two GitHub Actions workflows:\n\n- `CI`: runs on pushes to `main` and pull requests, then executes `cargo fmt --check`, `cargo clippy --locked --all-targets --all-features -- -D warnings`, `cargo test --locked`, and `cargo build --release --locked`.\n- `Release`: runs when a semantic version tag such as `v0.2.1` is pushed. It reruns the same verification steps first, then builds and attaches native release tarballs for Linux x86_64, Linux arm64, and macOS arm64.\n\nTypical release flow:\n\n```bash\ncargo fmt --check\ncargo clippy --locked --all-targets --all-features -- -D warnings\ncargo test --locked\ncargo build --release --locked\ngit tag v0.2.1\ngit push origin main v0.2.1\n```\n\nAvailable themes:\n`mdstream`, `catppuccin-mocha`, `sublime-snazzy`, `dracula`, `inspired-github`, `solarized-dark`, `solarized-light`, `base16-eighties-dark`, `base16-mocha-dark`, `base16-ocean-dark`, `base16-ocean-light`.\n\nInline palette values:\n`h1`, `h2`, `h3`, `h4`, `h5`, `h6`.\n\nIf you run `mdstream` without piping anything in, it prints a usage banner to stderr and exits **non-zero**, so shell scripts can detect the misuse.\n\n## How it works\n\nmdstream is a **line-oriented state machine**, not a full Markdown parser. It reads stdin in **4 KB chunks**, splits on newlines, and routes each completed line through one of a handful of render paths based on what it looks like: heading, list item, table row, code line, blockquote, paragraph. Partial lines (the bytes after the last newline) print as-is, then get *erased and re-rendered* the moment their newline arrives.\n\nThat structure keeps the renderer **fast and small**. There's no AST. No parser stack. Each block type carries just enough state to do its job: lists track nesting depth, tables buffer rows so they can be repainted in place, code fences own an active `syntect` highlighter for the current language. **UTF-8 chunk boundaries** are buffered until the bytes are complete, so multi-byte characters split across chunks render correctly. Wrapped partial lines erase via cursor-up + clear-to-end-of-screen.\n\nAll **18 regex patterns** compile *lazily, once*, via `OnceLock`. The `syntect` syntax and theme sets are loaded the same way, on first use. *Cold-start cost stays in the binary, not in the user's reading latency.*\n\nCode highlighting goes through `syntect` with the bundled built-in themes and the `default-fancy` feature set, so the binary stays **pure Rust** with **no C dependencies**. mdstream now ships a custom `mdstream` theme plus vendored `Catppuccin Mocha`, `Sublime Snazzy`, and `Dracula` `.tmTheme` files in the binary. `mdstream` is the default theme, and fenced code stays foreground-only unless you opt into themed backgrounds with `--code-background`.\n\nIf you need a structurally correct **full-document** Markdown parser, look at [`comrak`](https://github.com/kivikakk/comrak) or [`pulldown-cmark`](https://github.com/raphlinus/pulldown-cmark). If you want fast, terminal-shaped, **streaming** rendering, mdstream is built for that one job.\n\n## Build from source\n\nmdstream targets **Rust 1.94 or later** (edition 2024).\n\n```bash\ncargo fmt --check\ncargo clippy --locked --all-targets --all-features -- -D warnings\ncargo test --locked\ncargo build --release --locked\n```\n\nThe test suite is **85 tests** across seven integration files plus in-crate unit tests: streaming chunk handling, every block-level renderer, inline formatting, the table promotion and repaint state machine, fenced code blocks, the CLI surface, the TTY-detection branch, and an *end-to-end snapshot* of a mixed-content document.\n\n## Contributing\n\nBug reports and pull requests are welcome at [github.com/gastonmorixe/mdstream](https://github.com/gastonmorixe/mdstream). Before opening a PR, please run `cargo fmt --check`, `cargo clippy --locked --all-targets --all-features -- -D warnings`, `cargo test --locked`, and `cargo build --release --locked`.\n\n## License\n\nMIT\n\nCreator: Gaston Morixe \u003cgaston@gastonmorixe.com\u003e\nRepository: https://github.com/gastonmorixe/mdstream\nCopyright 2026 Gaston Morixe\n\nSee [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgastonmorixe%2Fmdstream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgastonmorixe%2Fmdstream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgastonmorixe%2Fmdstream/lists"}