Markdown previews in Finder’s Quick Look
How Quick Look extensions work on modern macOS, why pressing Space shows raw Markdown, and how to get a rendered preview that survives an OS upgrade.
Quick Look is the best thing in Finder. Select a file, press Space, see the file. No launch, no window, no waiting for an application to decide whether it trusts the folder. It works for images, PDFs, video, audio, Keynote decks, and — since about 2005 — anything an app teaches it about.
Markdown is not on the built-in list. Press Space on a README.md and macOS shows you the plain text, because as far as the system is concerned that is exactly what the file is. This guide is about how to change that, and what has changed underneath in the last few years.
Two generations of Quick Look plugin
If you search for this problem you will find advice from two different eras, and mixing them up is the main reason people end up with something that stops working.
The old way: .qlgenerator bundles. You dropped a bundle into ~/Library/QuickLook, ran qlmanage -r, and Quick Look picked it up. QLMarkdown and friends worked this way for years. Apple deprecated the mechanism with macOS Catalina and has been steadily tightening what unsandboxed plugin code may do ever since. Some of these still work. Many broke at an OS upgrade and never came back.
The current way: app extensions. A Quick Look preview is now an extension shipped inside an application bundle. You install the app; macOS finds the extension; the extension runs sandboxed in its own process. Nothing goes in ~/Library/QuickLook, and nothing needs qlmanage -r.
Everything below assumes the current way, because it is the one that survives September.
How to get a rendered Markdown preview
- Install an app that ships a Quick Look extension. Hem is one, and it is free and open source; there are others, and the comparison guide is honest about them.
- Open the app once. This is the step people skip. macOS registers an app’s extensions when the app first runs, not when it lands in the Applications folder. Copying the app across and never launching it leaves the extension invisible to the system.
- Press Space on a
.mdfile.
That is the whole procedure. If it worked, you now have rendered headings, tables, code blocks and links in the Quick Look panel, and you did not have to touch a plugin folder.
When Space still shows raw text
The app has never been launched. See step two. It accounts for most reports.
The extension is switched off. Open System Settings → General → Login Items & Extensions, find Quick Look in the list, and check that the app is enabled. This pane is also where you disable extensions you no longer want.
Another app won. More than one installed extension can claim .md, and macOS picks one. There is no user-facing priority list; the practical fix is to turn off the extensions you do not want in the pane above. If you have collected three Markdown apps over the years, this is almost certainly what is happening.
The system cache is stale. Rare on modern macOS, but qlmanage -r && qlmanage -r cache in a Terminal forces a rebuild. If a plugin only works after you run this, treat it as a warning rather than a solution.
The file is not what you think. notes.md.txt is a text file with a misleading name. ⌘I in Finder shows the real one.
What a good Markdown preview should do
Rendering the text is the easy part. The differences show up in what happens next.
Tables and task lists. GitHub Flavored Markdown is what people actually write. A preview that shows | --- | --- | as literal pipes is not finished.
Code, highlighted. A README is mostly prose and shell commands. Monospace is the minimum; syntax colouring is what makes a fenced block scannable.
Diagrams and maths. Mermaid and LaTeX are common in engineering documents now. Rendering them in the preview rather than dumping the source is the difference between a preview and a fallback.
Your appearance. If your Mac is in dark mode, a preview that flashes white is a small act of violence at eleven at night.
Local rendering. A preview extension has no business making a network request. Images referenced from the web are one thing; fetching a stylesheet or a script from a CDN to draw a local file is another. It should work on a plane.
Speed. Quick Look’s whole proposition is that it is faster than opening the app. An extension that takes a second to appear has given the proposition away.
The sandbox, and why previews sometimes look different
Quick Look extensions run sandboxed. The extension is handed the one file you selected and very little else — it cannot wander the disk, and by default it cannot read another application’s preferences.
That last part has a visible consequence: unless an app goes out of its way, its Quick Look preview will not know about the settings you chose in the app. You pick New York at a comfortable size in the main window, press Space, and get the defaults.
It is fixable — the extension can be granted a narrow, read-only exception and read the app’s preferences file directly — but it requires deliberate work, and plenty of apps do not bother. It is worth checking: set an unmistakable preference, such as the largest text size, and press Space. If the preview ignores you, now you know.
Quick Look from the command line
qlmanage is a developer tool, but two of its flags are handy:
qlmanage -p README.md # open the preview panel for one file
qlmanage -m # print which generators are loaded
qlmanage -p puts [DEBUG] in the window title and does not behave exactly like Finder’s panel, so do not use it to judge appearance. It is useful for answering “is anything handling this file type at all”.
Is it worth it?
An extension is a few megabytes and a single launch, in exchange for never opening an editor to read a file again. If you work in a repository with a dozen Markdown documents in it — and in 2026, with agent-written AGENTS.md and CLAUDE.md files in every project, most repositories do — the keystroke you save is the one you press most.
Hem ships one, weighs 5.7 MB, renders GitHub Flavored Markdown with Mermaid and LaTeX, draws everything locally, and follows the settings you chose in the app. It is free and the source is public.
