Open-source project
MeanderingProgrammer/render-markdown.nvim avatar
MeanderingProgrammer/render-markdown.nvim

render-markdown.nvim: How to Render Markdown in Neovim Without Leaving the Buffer

Improve viewing Markdown in Neovim

5,119 stars143 forksLuaMIT

At a glance

What is it?
A Neovim plugin that draws headings, tables, callouts and LaTeX inside the buffer itself, with no external window, preview server or browser. It is for people who write Markdown in Neovim and want it to look like something while they type.
Who is it for?
Adopt it if you already live in Neovim, have nvim-treesitter with the markdown and markdown_inline parsers, and want formatting drawn in the buffer rather than in a browser tab. Do not adopt it as a Markdown-to-PDF or Markdown-to-HTML pipeline; the plugin has no export path, and its LaTeX support depends on external tools such as latex2text or utftex that you must install separately.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 16 days ago.
What is it written in?
Mainly Lua, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What render-markdown.nvim actually changes about editing Markdown in Neovim

Plain Neovim shows Markdown as source text. A heading is a line starting with `#`, a table is a grid of pipes, a callout is a blockquote with a marker inside it. Syntax highlighting colors those characters, but the structure stays textual. render-markdown.nvim replaces that view with a rendered one: the README lists headings, code blocks, inline code, horizontal breaks, list bullets, checkboxes, block quotes, callouts, tables, links, LaTeX blocks and org indent mode as components it draws. The plugin describes itself as "Contained: runs entirely inside Neovim with no external windows", so this is not a preview pane bolted onto the side. The buffer is the preview.

The intended audience is narrow and specific: people who write Markdown, or Markdown embedded in another file type, inside Neovim and do not want to switch to a browser to check how it looks. The README states the plugin is "File type agnostic: can render `markdown` injected into any file", and that it can run automatically on lazy-loaded file types defined in `lazy.nvim`'s `ft` key. That matters if you keep Markdown in docstrings, in comments, or in a notes plugin that uses its own file type.

The trade-off is that a rendered view is less useful for editing the thing you are looking at. If you need to change the alignment row of a table, or fix a stray asterisk in a bold span, the raw characters are what you edit. The plugin handles this with modal rendering: it switches between a `rendered` and a `raw` view based on the current mode, and an anti-conceal feature hides the virtual text it added on the cursor line. You are never far from the source, but you are also never looking at it for long.

How the rendering pipeline works: treesitter, virtual text and window options

The plugin does not reimplement a Markdown parser. Requirements list treesitter parsers: `markdown` and `markdown_inline` are required, while `html`, `latex` and `yaml` are optional and used for concealing HTML comments, extracting LaTeX blocks and rendering elements in frontmatter metadata respectively. So the parse comes from treesitter, and the plugin reads the resulting syntax tree to decide what to draw.

Drawing is done with virtual text and window options. The README lists "Window options: changes option values between `rendered` and `raw` view" as a feature, which means part of the visual change is not virtual text at all but the buffer's own display settings being swapped when you enter or leave a mode. The anti-conceal feature then removes the plugin's virtual text on the cursor line so you can see the characters you are editing.

Two mechanisms are worth knowing about because they affect what you can do with the plugin. First, "Injections: can directly manipulate treesitter to add logical `markdown` sections". That is how Markdown inside a non-Markdown file gets parsed as Markdown: the plugin adds a logical region to the syntax tree. Second, "Custom rendering: provides extension point where user can add anything". The README does not spell out in the excerpt what that extension point looks like, so treat it as a hook to investigate in `doc/` rather than something you can plan around from the README alone.

Large files get a specific treatment: "only renders visible range, can be entirely disabled based on size". This is a sensible design, but it also means the rendered view is a viewport effect, not a whole-document transformation. Scrolling changes what is drawn.

Installing render-markdown.nvim with lazy.nvim or vim.pack

The plugin is distributed as a normal Neovim plugin. The README documents four installation routes: `vim.pack`, `lazy.nvim`, `rocks.nvim` and `packer.nvim`. It is also published on LuaRocks, so `rocks.nvim` users install it with a single command.

For `lazy.nvim`, the README gives this spec. Note that treesitter is a dependency, and an icon provider is optional but needed for language icons above code blocks:

lua
{
    'MeanderingProgrammer/render-markdown.nvim',
    dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-mini/mini.nvim' },
    ---@module 'render-markdown'
    ---@type render.md.UserConfig
    opts = {},
}

If you prefer `nvim-web-devicons` over the `mini.nvim` suite, the README shows the alternative dependency line commented out in the same block. For `vim.pack`, the README's example adds treesitter, an icon provider and the plugin together, then calls setup:

lua
vim.pack.add({
    'https://github.com/nvim-treesitter/nvim-treesitter',
    'https://github.com/nvim-mini/mini.nvim',
    'https://github.com/MeanderingProgrammer/render-markdown.nvim',
})
require('render-markdown').setup({}) -- only mandatory if you want to set custom options

On `rocks.nvim`, the README gives a single Vim command:

vim
:Rocks install render-markdown.nvim

After installation, the plugin exposes a `:RenderMarkdown` command family. The README's command table maps `:RenderMarkdown toggle` to `require('render-markdown').toggle()` and `:RenderMarkdown buf_toggle` to `set_buf()`. The distinction is scope: the `buf_` variants act on the current buffer only, while the plain variants act globally. If you want to check whether rendering is active in the buffer you are in, `:RenderMarkdown buf_toggle` is the one to reach for. There is also a health check, `:checkhealth render-markdown`, which the `justfile` runs as `nvim -c "checkhealth render-markdown" -- -`.

The LaTeX, image and Mermaid gaps you should know before adopting

Three limitations are visible in the documentation and all three matter.

LaTeX rendering is conditional on external software. The README marks LaTeX blocks with a footnote requiring "`latex` parser and `pylatexenc`", and the system dependencies section lists `libtexprintf` (used to transform LaTeX strings to unicode via `utftex`) and `pylatexenc` (used via `latex2text`). So the plugin does not render math by itself. It converts LaTeX to unicode text using a tool you install outside Neovim. The output is unicode, not typeset math. Complex formulas will not come out looking like a PDF.

Images are not in the component list. The README enumerates headings, code blocks, code inline, horizontal breaks, list bullets, checkboxes, block quotes, callouts, tables, links, LaTeX blocks and org indent mode. Nothing there renders an image inline. If your Markdown is image-heavy and you want to see the picture while you edit, this plugin does not do that, and the README does not claim it does.

Mermaid is not mentioned anywhere in the README. The related searches include "render markdown nvim mermaid", but the feature list does not include diagram rendering, and no Mermaid dependency appears in the requirements. Treat that as out of scope until the documentation says otherwise.

The broader failure mode is visual rather than functional. The plugin draws icons, and the requirements state "Nerd font symbols" with a link to the wiki. Without a Nerd font configured in your terminal, the icons will render as fallback glyphs or boxes. This is not a bug in the plugin; it is a prerequisite the README states plainly.

How render-markdown.nvim differs from markdown-preview.nvim and glow

The obvious alternative is a browser-based preview plugin such as markdown-preview.nvim, which renders your buffer in a web view. The difference is architectural, not cosmetic. A browser preview runs a server, sends the document out of Neovim, and renders it with a full HTML and CSS engine. That gives you real image support, real math typesetting via MathJax or KaTeX, and a layout close to what you would publish. It also means a second process, a browser window, and a scroll position that does not track your cursor.

render-markdown.nvim inverts that. Rendering happens in the buffer, so the cursor and the rendered content are the same thing. There is no server and no second window. The cost is that the renderer can only use what Neovim can draw: virtual text, highlights and window options. That is why LaTeX becomes unicode instead of typeset math, and why images are absent.

A second comparison is a terminal Markdown viewer such as glow, which renders a file in the terminal. That is a read-only path: you view a document, you do not edit it. render-markdown.nvim is an editing mode, with modal switching back to raw text. If your workflow is "read a README in the terminal", a viewer is simpler. If your workflow is "write a README and see it as I go", the in-buffer approach is the one that keeps you in one place.

Maintenance, licence and what upgrading between versions costs

The repository is not archived, and the last push was on 2026-09-15. The most recent release is v8.14.0, dated 2026-09-15, following v8.13.0 on 2026-06-18 and v8.12.0 on 2026-03-09. That is roughly a quarterly cadence across the three releases shown, with the latest arriving in the same window as the last push.

The version numbering is the thing to watch. The project is on major version 8, and the releases shown are minor bumps within it. A major-version series at 8 implies the configuration surface has changed enough over time to warrant breaking releases, so pinning to a tag rather than tracking the default branch is the lower-risk choice if your config is nontrivial. The README does not document a migration path between major versions in the excerpt, so check `CHANGELOG.md` before moving across one.

Licensing is MIT, per the repository metadata and the `LICENSE` file at the top level. That is permissive: you can use, modify and redistribute the plugin, including in commercial settings, provided the licence text and copyright notice travel with it. This is a description of the licence, not legal advice; if the plugin ends up inside a product you ship, have someone qualified read the actual `LICENSE` file.

Upgrade cost is mostly configuration drift. Because all components, padding, icons and colors are configurable, a config that overrides defaults will need checking when those defaults move. The `justfile` in the repository runs `selene` and `stylua --check` as a `check` step and a busted test suite as `test`, so the project does have automated checks; that tells you changes are gated, not that your config is safe.

Editorial conclusion

Adopt it if you already live in Neovim, have nvim-treesitter with the markdown and markdown_inline parsers, and want formatting drawn in the buffer rather than in a browser tab. Do not adopt it as a Markdown-to-PDF or Markdown-to-HTML pipeline; the plugin has no export path, and its LaTeX support depends on external tools such as latex2text or utftex that you must install separately. Before wiring it into a config, verify two things: that your Neovim is at least 0.9.0 (0.10.0 if you want padding, link icons, table alignment or org indent mode), and that the plugin's own rendering actually survives your colorscheme and your font, since the icons it draws assume a Nerd font is present.

Frequently asked questions

What is Markdown rendering in the context of render-markdown.nvim?

It means drawing the structure of a Markdown document as formatted text inside the Neovim buffer, instead of showing only the raw source characters. render-markdown.nvim does this with treesitter parsing plus virtual text and window options, and it runs entirely inside Neovim with no external window.

How do I render Markdown in Neovim with render-markdown.nvim?

Install the plugin through vim.pack, lazy.nvim, rocks.nvim or packer.nvim, and make sure nvim-treesitter is present with the markdown and markdown_inline parsers. Once loaded, the :RenderMarkdown command family controls it, with :RenderMarkdown toggle switching rendering on and off and :RenderMarkdown buf_toggle doing the same for the current buffer only.

Can render-markdown.nvim convert Markdown to PDF?

No. The plugin renders Markdown inside the Neovim buffer and the README documents no export path to PDF or any other format. If you need a PDF, you need a separate tool.

What is the purpose of a Markdown file, and does render-markdown.nvim change it?

A Markdown file stores structured text in a plain-text format. render-markdown.nvim does not change the file or its purpose; it only changes how that file is displayed inside Neovim, drawing headings, tables, callouts and other components as formatted text.

Official sources

  1. Issues
  2. License: MIT
  3. MeanderingProgrammer/render-markdown.nvim on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/meanderingprogrammer-render-markdown-nvim.svg)](https://hysenlabs.com/projects/meanderingprogrammer-render-markdown-nvim)