Why I forked instead of taking the easy way out

I wanted to add a small real-time visitor counter to my website. In other words, to openly display how many people are viewing my site at the exact moment you're on it. If you're alone: 1. If you and someone else on the other side of the world: 2. etc.

Presence counter in action

My website uses a WebSocket server, Django Channels (since all the dynamic parts are rendered using Django LiveView). With this, I thought, why not? It would be fun. I have all the necessary tools to calculate the number and notify visitors instantly.

If you're not familiar with some of these technologies, here's a quick overview:

  • Django: Web framework in Python
  • Django Channels: Django extension for handling asynchronous connections, like WebSockets. Think of things like chats, push notifications, etc.
  • Django LiveView: Inspired by Phoenix LiveView, it allows rendering HTML on the server and sending it to the client in real-time using WebSockets. Ideal for creating reactive interfaces without needing to write JavaScript

In the past, I had already built a similar feature for a chat that indicated whether a user was connected or not. You can figure it out by keeping track of how many users connect to the WebSocket server and how many disconnect, and asking from time to time if they're still there. So, I knew the logic behind it. However, this time I wanted some easy-to-integrate extension. The minimum possible complexity.

I found a repository with just what I needed django-channels-presence. Unfortunately, it had been abandoned for 5 years, with Pull requests begging for some attention.

Instead of getting discouraged, or forcing myself to build it manually, I decided to fork it. I set out to update it to modern Django versions. It wasn't as complex a job as I imagined. With a small investment of time I created django-channels-more-than-present.

You can currently install it with:

pip install django-channels-more-than-present

I updated dependencies, replaced deprecated functions (like unique_together with UniqueConstraint or removed the old Signal parameter providing_args), did a migration, tested everything, published it on pypi and... little else. It took me longer to understand how it worked than to change the code (spoiler: it's well designed!).

The question you'll ask yourself is: Why did I bother making the fork?:

  • I would use it again in the future, and a Django app is an excellent way to integrate it quickly
  • It's code with potential
  • It improves the Django ecosystem

And because that's how Open Source works. Developing it for myself would have been faster, yes, but it would only contribute to my project. Now anyone can benefit.

With the new package ready, and Django LiveView rendering HTML in real-time... et voilà! With a feline theme, my visitors can know if they're alone or if there's someone else exploring the website at that precise moment.

Presence indicator

Django Channels Presence

Fork updates

Presence counter in action

Now all that's left is to play with the design.

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Will you buy me a coffee?

Written by Andros Fenollosa

December 7, 2025

3 min of reading

You may also like

Visitors in real time

You are alone: 🐱