Hot Reloading with Pandoc (Part 1)

2025-09-07

I like using a word processor like Pages to write blog posts, but I enjoy using Vim and markdown too much. So I write blogposts in my terminal using Vim, and use Pandoc to render the markdown into html.

This is nice, but I can’t see any formatting changes while I’m writing in my terminal, and I do really love to see how a post is coming together as I’m writing it. It’d be nice if I could see what the html looks like as I’m writing my blog post in markdown. Basically something like Merlot except I can use my terminal for writing the markdown.

Desired flow: type into vim -> render markdown into html -> see results on browser immediately.

Initial Attempt

I render a markdown file into html with pandoc like this:

$ pandoc -s --template=template.html -i <file.md> -o <file.html>

Using fswatch I can monitor a file and do something every time it changes:

if [ $# -eq 0 ]; then
    echo "Provide a .md file"
    exit 1
fi

file=$1

# make sure the provided file ends in '.md'
if [[ "$file" != *.md ]]; then
    echo "Provide a .md file"
    exit 1
fi

file=$1
filename="${file%.md}"
output="$filename.html"

if [[ ! -e "$file" ]]; then
    touch $file
fi

fswatch -o $1 | while read num ;
do
    pandoc -s --template=template.html -i $file -o $output
    open $output
done

The open $output opens the .html file in whatever way the OS is configured to, which in this case is to open it with Firefox.

If you save this as watch.sh, you can run it like this:

$ ./watch.sh <file.md>

This is a good start, but it has a few issues:

  1. I have to save every time I want to see a change
  2. It takes a noticeable half second or second for the changes to render
  3. It opens a new tab in Firefox every time I save, so my browser is quickly flooded with open tabs of my blog post.
  4. Using open changes the focus from my terminal to Firefox, so I have to cmd+tab back to the terminal each time I save.

I’ll tackle these issues in part 2.