A CMS-of-sorts built on open standards (Micropub & IndieAuth). Bring your own IndieWeb micro-blog and enjoy this lucid publishing interface.

Please note that this project is no longer being developed at all. For posterity, the code will soon be available on my GitHub.


Primary Author


June 2020 – February 2021

Tools Used/Explored

  • Express.js: to serve as the HTTP server.
  • TypeScript: to statically type parts of the code.
  • Jest: to unit test the application for easier upgrades and spec-compliance checks.
  • Docker: to publish community usable images and have reproducible builds along with a production environment.
  • Svelte: to progressively enhance the app.
  • Redis: to store IndieAuth logins and ephemeral user preferences.
  • Verdaccio: to self-host public & private modules.

A foray into back-end web development.

Since modern front-end web development — ReactJS, Angular, & other frameworks, serverless architecture, and JAMStack — have ushered in a whole array of backend concepts to the frontend, I finally scratched my itch to get started on gaining some familiarity with the backend itself — potentially to open up an avenue to become a full-stack developer.

I envisioned the backend to be a very complex monolith, and decided to have strongly typed code with TypeScript. Why? So this could help me and my IDE make sense of everything in the long run. Even though I had little idea of TypeScript at the on-set, this has given me a well-rounded overview of its basic usage already.

Becoming familiar with advanced JavaScript concepts.

Once a post is published, Celestial knows where the post will eventually show up. Static sites like mine, however, take time to build; this could range from a few seconds to a few minutes. This caused me unnecessary headache as I kept refreshing the post link to check if the post has been published and if everything looks OK.

I decided to implement some sort of automated check in the user’s browser. My project mentor then hopped on to a coding session with me, and we figured out together how to implement this.

Ultimately, I implemented a repetitive check in the browser itself using Svelte, which exposed me to closures and the factory design pattern. Every few seconds, we make a call to the post link to see if it has been published yet. When the post is published and verified through our checks, we automatically play an audio sound using the Web Audio API.

Problem solved! 🥳

Understanding and implementing standards/specifications.

This project implements two specifications so far: Micropub and IndieAuth.

I implemented IndieAuth in about a week, ensuring a high degree of compliance with the original specification. My work still continues as far as Micropub compliance is concerned.

Still, this gives me yet another insight into working with documentation written by someone else, and hopefully some idea on how to write one of my own!

What’s IndieAuth?

Imagine you discover a new site that does something cool, but you need to sign up to access their services. Pretty normal stuff on the modern web, right? You are also super likely to see options like, Sign in with Facebook, Sign in with Google, and so on – because they really want you to sign in effortlessly and perhaps even leverage more accurate data from your Facebook and Google profiles.

Now imagine if there was another method to let you sign up and in: Sign in with your website. Sounds strange? It did to me too!

My website is hosted on https://rusingh.com/, so I type it in and hit sign in. My identity is then verified perhaps by an email code, or my GitHub profile in this case, and the website now has some basic details about me based on my h-card, as can be seen below:

IndieAuth is a protocol built on top of OAuth 2.0. The specification is a Living Standard and can be viewed on IndieWeb’s website. This project implements IndieAuth with changes up to 25 January 2020.

Planning front to back.

While the project started with just a plan in my head and a rough roadmap to v1 in the README file, I kept growing it to include v2 and v3 features as well as refining the v1 roadmap.

Ultimately, I now have a whole bunch of issues, projects, and milestones ready to guide me. Given that I have consciously slowed down the development, this is immensely helpful to guide me in picking up new features. Another benefit is it gives folks an idea of where the project is and how things are going at any given point.

For example, here’s a look at the v1 milestone page:

And, here’s a look at just one of the projects, UI & UX:

Building reliable software with unit-testing.

Unit testing had eluded me for so long it wasn’t cool anymore. I have always looked at projects with tests as “well-done” projects. It only made sense that at this stage in my career, I better get down to business on this front. Jest was my choice of unit-testing suite as it advertised out-of-the-box support for TypeScript.

I already have gathered a bit of idea around what not to test, how to mock an API call, and how to take snapshots. Armed with this knowledge, I expect using Jest to test ReactJS code might not be so different.

Building and using private, independent & reusable modules.

When Celestial’s development went private, one of the first issue I faced was the inability to distribute my newly-crafted IndieAuth module to the core application. Well, not without spending USD 7/month on npmjs.com to gain the ability to publish and fetch a private package.

Between git submodules and lerna-based monorepo, I finally settled on self-hosting an instance of Verdaccio, which would give me the same publishing and installation flow as npm, but without the hefty monthly fees.

Verdaccio also acts as a proxy to npmjs.com for packages not available on our self-hosted registry. It has experimental support for npm tokens, which had to be enabled for programmatic node modules installation. Docker required additional configuration to play well, but it was worth the effort.

Collaboration with the FOSS Community.

Even though the project is in its infancy, I’ve already worked with several people, and it has been a very interesting and validating experience.


When starting out with the project, one of the first things I did was toot for a project mentor. I was going to go in unknown waters and if there’s one thing I’ve learned, it helps to have someone to bounce ideas from and ask questions about things they understand better. Tyler Childs volunteered and has been a great help not just from a technical point of view, but also from a more philosophical perspective. Most recently, he had asked me, “Do you think the reason you don’t feel like returning to the project is that you’re fatigued by TypeScript?” That was a light-bulb moment. In fact, we have found ourselves talking about companies we’d like to work for or even the state of the world; we even found out we have the exact same laptop!


I also sent out a request for a logo and if someone would be willing to volunteer with full attribution to their work on the GitHub project as well as the actual site. Andy stepped up and through the course of over a month, we finally settled on the current logo. It’s so creative, and I love it – couldn’t have asked for a better one!


That’s not it, either. When I reached out for help on an accessibility issue around a smart input field for categories, Mehdi M. volunteered, and we had a conversation around the issue on a GitHub gist. I am impressed with how he went above and beyond in helping me with my issue.

While all the suggestions have not yet made it into Celestial, it’s on the roadmap for v1.0.