A Better Blog Blueprint: Balancing Both Basic and Bespoke

A new coat of paint, a blog custom-made.

I recently moved my blog from a Notion-hosted website to a self-developed solution. Although Notion allows users to easily create advanced (and very pretty) page layouts, the customization features are a bit lacking for my tastes; there are only 3 font-options; the line-height cannot be changed; and the properties of database entries (which I was using for my posts) cannot be hidden. Additionally, certain features like iframe embedding and custom domain names are locked behind a subscription service, which I wasn’t willing to pay for.

Of course, moving away from Notion comes with its trade-offs. The UX of writing blog posts in a text editor just doesn’t quite compare to that of using a word-class note-taking app. However, I was able to come up with a solution that offers a good balance between customizability and ease-of-use. I’ll tell you how it works — maybe it’ll be useful to you someday.


A Replacement Text Editor

What is a blog without any posts? A dead blog. My highest priority was to keep the creation process of posts easy — a difficult writing process would discourage me from writing new posts, defeating the purpose of my blog altogether. I thought about the different writing ecosystems that I’ve substantially used, including Notion, $\LaTeX$, Google Docs, and Microsoft Word. Eventually I decided on using Markdown, a lightweight markup language used for software documentation and on Social Media platforms such as Slack, Discord, and Reddit.

Markdown is just about perfect for my needs. It’s quick and easy to use, and it offers native support for images, hyperlinks, lists, tables, code blocks, font settings (e.g. bold, underline, italics, etc.), and more. It also supports HTML and CSS, expanding its capabilities to allow for any layout that my blog would ever need. Not only is Markdown convenient and powerful, it’s also easy to implement — there already exists reliable Markdown renderers that can easily be integrated into websites.

For this blog, I decided to use marked.js, a Markdown-to-HTML converter that doubles as both a JavaScript library and a CLI. I decided on compiling my blog with the CLI, since it results in faster-loading pages and I don’t need any real-time markdown rendering features. I created a template HTML file alongside Python scripts to automatically generate HTML pages from Markdown for the blog posts.

The Metadata for Posts

What data format to use? JSON, of course. All changes to posts are done by hand, so I don’t need a proper database, and JSON data is easily readable by both humans and computers. Additionally, the JSON format is nearly identical to that of Python dictionaries, which helps reduce coding confusion, and JSON data can easily be visualized using tools such as jq.

As for the metadata structure, each post is represented by an array element containing information including the markdown file path, the post title, and the post date. It is all read and processed by Python scripts that automatically generate both the home page and the pages for individual blog posts.

The Outsourced Parts

There were 3 main aspects of the blog that I was afraid of dealing with:

  1. $\LaTeX$ rendering;
  2. code syntax highlighting; and
  3. consistent emojis across all platforms.

Luckily, I was able to easily handle these parts using external libraries.

To handle $\LaTeX$ rendering, I used KaTeX, a JavaScript $\LaTeX$ renderer for the Web. The integration process with my blog was straightforward — all I had to do was add the sample code to my template HTML files.

The 2nd library I used is highlight.js, a code syntax highlighter for the Web. Luckily for me, marked.js automatically generates HTML code compatible with hightlight.js, eliminating all text processing required on my end. As a result, the sample code worked perfectly without any changes.

As for the emojis, I used Twemoji Amazing. I wouldn’t consider handling emojis to be technically challenging, but it requires a lot of manual work that I wasn’t willing to do. Twemoji Amazing provides a huge list of HTML classes that can be used to render Twitter’s emoji catalog. Combining this with some RegEx, I was able to integrate consistent-looking emojis into my Markdown rendering pipeline.

The Editing Process

To make a change to my blog, I follow these steps:

  1. Create/edit the associated Markdown file.
  2. Edit the post metadata file.
  3. Run ./scripts/make.sh to rebuild the website.

It’s quick and easy to use — perfect for my needs.

The Downsides

No Comment System (Yet)

Notion has an amazing comment system that lets users select any part of a post to make a comment on. My comment system, on the other hand… doesn’t exist. It’ll be coming soon though; it just won’t be as good as that of Notion’s.

10 ⁄ 09 ⁄ 22: Comments are here !

Suboptimal Writing Feedback

In Notion, you can immediately see the final result of any changes made. I use VS Code’s Markdown Preview to edit my blog, which can instantly show formatted Markdown, but it doesn’t display any HTML or CSS. This works okay in my experience, although I sometimes miss Notion’s simplicity in this regard.


What does the new blog look like? You’re on it right now . It loads fast, and I think it’s aesthetically pleasing too. Maybe I’ll publish a template for this blog in the future. Here’s the codebase by the way.


Comments