CLI tool that renders markdown files in the browser with mermaid diagram support. Rails 8 + Hotwire.
- HTML 54.9%
- Ruby 30.4%
- CSS 6.3%
- Dockerfile 4%
- JavaScript 3.2%
- Other 1.2%
| .github | ||
| app | ||
| bin | ||
| config | ||
| docs | ||
| lib/tasks | ||
| log | ||
| public | ||
| script | ||
| tmp | ||
| vendor | ||
| .dockerignore | ||
| .gitattributes | ||
| .gitignore | ||
| .rubocop.yml | ||
| .ruby-version | ||
| config.ru | ||
| Dockerfile | ||
| Gemfile | ||
| Gemfile.lock | ||
| Rakefile | ||
| README.md | ||
mdview
CLI tool that renders any markdown file in the browser with mermaid diagram support. Built on Rails 8 + Hotwire. Gruvbox dark theme.
Install
cd ~/mdview
bundle install
ln -sf ~/mdview/bin/mdview ~/.local/bin/mdview
Requires Ruby 3.4+ and Bundler. No Node.js, no database, no other system dependencies. bundle install handles everything.
Usage
mdview path/to/file.md
Opens http://localhost:3137. Re-running mdview with a different file automatically stops the previous server and starts a new one -- no manual cleanup needed.
Relative links to other .md files work. If your README links to docs/guide.md, clicking it navigates to the rendered guide. Click "back to root" to return.
Ctrl-C stops the server.
mdview ~/mdview/README.md # read these docs through the tool itself
mdview ~/some-project/README.md # render any project's docs
Docs
Learn how this app works -- and learn Rails along the way:
- The Filetree -- every file, what it does, what's idle, what "convention" means, and why Rails ships so much
- Dependencies -- every gem, what it does, which ones we actually use, and how Gemfile/Bundler work
- Request Lifecycle -- what happens from URL to rendered page
- MVC in Practice -- how Model-View-Controller plays out in this app
- Hotwire Explained -- Turbo Drive, Stimulus, and importmaps
- CSS Architecture -- design tokens, Propshaft, and the gruvbox theme
- File Map -- quick reference table of every file
Architecture
graph TD
CLI["bin/mdview file.md"] --> ENV["MDVIEW_FILE env var"]
ENV --> Puma["Puma :3137"]
Puma --> Router["config/routes.rb"]
Router --> Controller["MarkdownController"]
Controller --> Redcarpet["Redcarpet: MD → HTML"]
Redcarpet --> LinkRewrite["Rewrite .md links"]
LinkRewrite --> ERB["show.html.erb"]
ERB --> Layout["application.html.erb"]
Layout --> Browser["Browser"]
Browser --> Stimulus["mermaid_controller.js"]
Stimulus --> MermaidJS["Mermaid.js CDN"]
MermaidJS --> SVG["SVG diagrams"]
style CLI fill:#3c3836,stroke:#d79921,color:#ebdbb2
style Browser fill:#3c3836,stroke:#8ec07c,color:#ebdbb2
style Controller fill:#3c3836,stroke:#83a598,color:#ebdbb2
Stack
| Layer | Tool | Role |
|---|---|---|
| Language | Ruby 3.4 | Server-side logic |
| Framework | Rails 8.1 | MVC structure, routing, asset pipeline |
| Server | Puma | HTTP server (listens on :3137) |
| Markdown | Redcarpet | Converts .md to HTML server-side |
| Diagrams | Mermaid.js 11 | Converts fenced blocks to SVG client-side |
| JS Framework | Stimulus | Manages mermaid rendering lifecycle |
| Page Navigation | Turbo Drive | SPA-like page transitions without a SPA |
| Assets | Propshaft | Serves CSS/JS as static files, no build step |
| JS Delivery | Importmap | ESM imports without bundling (Webpack/esbuild) |
| Theme | Gruvbox Dark | Warm dark palette via CSS custom properties |