Creating My Blog From Scratch In Python
Curious how a blog from scratch can be made using simple open-source tools and technologies? Here is how I built Pyyogi.com, a made-from-scratch blog which I can extend according to my ideas.

Process of Elimination
When I first considered publishing and setting up my own blog, a few searches suggested that WYSIWYG
editors were a pretty standard way to go. The idea is you write markdown
in an editor hosted on a website, and it automatically converts that markdown to HTML, which viewers can then see on the site.
However, setting up a WYSIWYG
editor and customizing it to do exactly what I wanted felt like a heavy lift on the JavaScript side. While I've used JavaScript before, I wasn't confident enough to really dive in and extend existing WYSIWYG
frameworks written in it to fit my specific needs.
I even tried out Lexical
and Quilljs
with React
on the backend, but the extra step of setting up server-side rendering (SSR)
in React didn't appeal to me. I also experimented with Quilljs using a Python backend, but I still felt lost in the JavaScript
ecosystem. Given my early career experience with Django, my mind kept suggesting I take a route where I could design the whole blog experience according to my own needs, primarily using Python as much as possible. It was while trying to work with React that I discovered HTMX. Eventually, I decided to build my blog using Python, HTMX
, Tailwind CSS
, Litestar
, and Nginx
. Even with my preferred stack, it didn't turn out to be a completely easy task.
Pythonic World In-Depth
I was trying to pick a backend framework for my blog, and I had a few options in mind: FastAPI
, Litestar
, Flask
, and Django
. After experimenting with them a bit, I've decided to go with Litestar. It's proven to be an easier and more extensible framework for what I need.
Markdown To HTML
I mostly take my notes in markdown and organize them in folders. I wanted to make them available on my blog, Pyyogi. At the time, I had already decided against using WYSIWYG editors because I wanted to build a solution that I could extend, and Python was my go-to language for writing custom tools. So, I came up with a few Python scripts to automate the conversion of my markdown notes to HTML. Here's a high-level overview of how I managed it:
I used the python-markdown
package to convert markdown
to html
. Later, when I felt it wasn't fulfilling all my needs, I extended it by writing several extensions to enhance the parsing and conversion process.
I also used the lxml
Python package for post-processing and annotating the html
document tree that was produced by the method I just mentioned.
Keeping Track of Posts, Categories & Users
Parsing notes written in markdown to HTML wasn't enough to manage the blog smoothly and effectively. To better organize and keep track of my posts, I started attaching properties to them using YAML. This allowed me to define metadata such as categories, tags, publication dates, and even the URL structure for accessing them on the webserver.
Similarly to how I managed posts, I also created User
and Category
classes and established relationships between them and the Post
objects. This helped in managing authors and categorizing content for better organization and navigation on the blog.
Prettifying The Content : CSS
After running the markdown notes content through several pipelines, I ended up with HTML that, while not visually beautiful, was at least semantically correct and coherent. Even though I wasn't a big fan of CSS
initially, using Tailwind completely changed my mind – I actually fell in love with it. I used Tailwind CSS to prettify the HTML content of my posts. In fact, I even designed my entire blog from scratch using Tailwind CSS.
World Outside Programming Languages : Deployment
When it comes to deploying your application, it feels like a whole unfamiliar world exists beyond the programming language itself. There's a vast array of tools and tricks, which can be combined in seemingly endless ways to configure your app. With the first prototype of my blog ready, I started exploring how to deploy it properly so it could handle real-world traffic in a standard way.
To get it running, I set up Uvicorn
with Nginx
and used Certbot
for SSL
certificates. I also wrote some bash scripts to automate tasks. Additionally, I learned about Podman
(as an alternative to Docker) and familiarized myself with Tmux
and other useful console tools.