published on 30.11.2020

I’ve been searching for a good workflow for publishing Jupyter or RMarkdown Notebooks as static blog posts. I think I’ve found the optimal solution for my use case. In this post, I’ll explain my workflow and why chose this way with examples.

In reality my main purpose to migrate from Jekyll to Hugo was blogdown, thus R notebooks. Still, I have no regret even if I had not published any notebook yet.

Why Jupyter Notebooks Suck

Currently, I work with Python and usually with Jupyterlab Notebooks. I can’t say that I like jupyter notebooks. Still, they work fine for small projects and the notebook concept is good if you are taking notes or plotting graphs besides the code. What I don’t like about jupyter notebooks, is that they are JSON files. You may ask “what’s wrong with that?”. Well, let me tell you:

  • You can’t just open jupyter notebooks in any code editor and edit them.
  • Jupyter notebooks feel slower than normal code editors.
  • I don’t like the extensions and the dependencies. Why would I install npm?
  • It’s not as powerful as an IDE.

Most importantly, you can’t get clear diffs because notebooks are JSON files. I’ve tried an extension called jupyterlab-git but the results weren’t satisfying for me.

So, I want:

  • Normal diffs
  • Ordinary text document
  • Notebook logic

This is where Rmarkdown shines. Did you know that we can run Python code in Rmarkdown? R has a library called reticulate which allows us to run Python via R. As a bonus, we have a fully-featured IDE RStudio.

Reticulate also allows us to combine R and Python code. Even though it’s an exciting feature, I don’t think most of us will need it. It might be useful for teams working on a big project.

Convert Notebooks

Now, let’s take a step back and remember the main objective: Notebooks to Hugo. To be honest, I tried to convert jupyter notebooks to markdown using jupyter nbconvert. It wasn’t successful. I’ve also tried a couple of scripts created by the community but the results weren’t good. You can try in your environment if you are already using jupyter notebooks.

jupyter nbconvert .\foo.ipynb --to markdown --NbConvertApp.output_files_dir=.

This is a Rmarkdown document by the way and below is a Python code chunk. Let’s try it out.

import as px
iris =
##        sepal_length  sepal_width  petal_length  petal_width  species_id
## count    150.000000   150.000000    150.000000   150.000000  150.000000
## mean       5.843333     3.054000      3.758667     1.198667    2.000000
## std        0.828066     0.433594      1.764420     0.763161    0.819232
## min        4.300000     2.000000      1.000000     0.100000    1.000000
## 25%        5.100000     2.800000      1.600000     0.300000    1.000000
## 50%        5.800000     3.000000      4.350000     1.300000    2.000000
## 75%        6.400000     3.300000      5.100000     1.800000    3.000000
## max        7.900000     4.400000      6.900000     2.500000    3.000000

Of course, my blog is already generated by Hugo and compatible with R blogdown library. So, I just simply did the following:

  1. open up RStudio
  2. open my existing website as a new R project.
  3. serve site using the add-ins or by running blogdown::serve_site()
  4. add post using the add-ins or create an Rmarkdown document or with blogdown:::new_post_addin()

And it’s rendered auto-magically, I can now focus on the notebook. I suggest you use blogdown & hugo for ease of use but you can still use blogdown with other static site generators. Even more, you can write your notebook using Rmarkdown then convert it into the format you want using knitr but that also requires learning about the knitr package.


In summary, we write in Rmarkdown. Blogdown converts it into markdown and then, Hugo processes the markdown file, generates an HTML file for publishing to the web.


Here are the most important benefits of using Rmarkdown for me:

  • We are not dependent on Hugo or RStudio. You can work on VSCode if you want to.
  • We can open the Rmarkdown document anywhere and read what’s inside.
  • Most importantly, we have standard diffs with git.

As a side note, if you are using built-in syntax highlighters you should use .Rmarkdown extension, not .Rmd. Otherwise, you’ll need a syntax highlighter library like highlight.js. If you are already using client-side syntax highlighting then it shouldn’t matter which extension you choose.

In the next post, I’ll share examples of adding plots generated by Python code in the Rmarkdown document.

You are reading the 1st of 2 episodes in Rmarkdown.
Published on 30.11.2020 by Mert Bakır with commit 4fa6ba7.
#hugo #rmarkdown #rstudio #workflow
Next episode:
HTML Widgets with R Markdown Documents & Blogdown
published on 31.12.2020
edited on 26.06.2021

I’ve, recently, published a blog post called Perfect Workflow for Publishing Python Notebooks. I talked about some of the benefits of using Rmarkdown and reticulate. In this post, I’ll try HTML widgets and explain how we can embed those in our blog post using nothing but R. […] 1 …

published on 03.08.2020

In this post, I aim to explain this website. Template by template… The main purpose here is to create a document to myself for future reference. Templates are complicated and not easy to read. That’s why I’ll probably forget what I did and why I coded this way. […] We are …

published on 24.01.2021
edited on 11.06.2021

Some time ago, I wanted to display image galleries on my Hugo website and searched for Hugo themes for photography and gallery. I can’t say I find much. Then, I met with a javascript library called nanogallery2 which is using another javascript library as an image viewer lightbox2. In this …

published on 23.01.2021
edited on 11.06.2021

Image processing may seem complicated at first but it’s actually easy and definitely worth implementing since it’ll help you decrease page load times. As you probably know, we don’t want to load raw images with huge sizes for small thumbnails or blog-posts. We want to load a small …

published on 05.12.2020

Resume A4 is a side project of mine. It’s one page Hugo Theme that allows you to write your resume in YAML format and keep track of it using git. Also, you can publish it online as a static site using GitLab, GitHub Pages, Netlify, or some other service you are familiar with. A few months …

published on 29.11.2020
edited on 05.12.2020

Plotly is a visualization library that allows us to write code in Python, R, or Julia and generates interactive graphs using Javascript. So, we don’t have to deal with Javascript. You can checkout Plotly gallery, there are interesting works. Anyway, last week, I’ve started learning …