Building a readme service that makes your documentation look beautiful — fastdocs.io

Anirudh Emmadi
6 min readAug 25, 2020

--

It’s really important to have a README for any project. But why stick to the plain old markdown renders? You spent countless hours working on your project, typing up the documentation for people to view your work, so why not show-off your docs in style!

FastDocs project logo
Project Logo

Introducing fastdocs.io, a passion project built to serve your README files with a beautiful UI and features like: adding plugins (search bar, copy-code, etc) for completely free!

Inspirations:

A big shout out to existing tools like documentup.com and nicedoc.io that renders README markdown files into a full fledged website with a neat UI. I personally have used both of these before and they have shown me the need for a readme service to exist.

Although these services provided users with a neat UI for their READMEs, they still looked “out-of-place”, and have the same common theme throughout all their renders, allowing for embedded images (sometimes) to stand out of the color scheme. This was when I found docsify.js.org, a quite spectacular piece of tool that in-fact delivers the beautiful renders it promises for your documentation. However, there was a problem. There is a setup process users had to go through to get their docs up and running. That’s when it clicked in my head.

What if there was a service that renders docs with docsify on-the-fly?

I set out to merge the best of both worlds. The ease-of-use offered by services like documentup & nicedoc with the customization and beautiful UI provided by Docsify.

Execution:

The first step was research. Fortunately, documentup & nicedoc were both open source, so I was able to take a look into their source code and see how they have architected their code. It didn’t take me long to realize most of their code was how they parsed the markdown files and generated HTML and CSS. Since I was using Docsify, I was able to speed up the development process.

The “architecture” started to formulate in my brain.

Early architecture of the project, before development
Early architecture of the project, before development

I then mapped out the tech stack I was going to use to achieve this. I wanted to learn ExpressJS for a while now, I figured I could do a two-birds-one-stone type thing so I picked that for the back-end route handling, which meant using NodeJS as my back-end server language. The scope of this project really didn’t require me to use a database as I wasn’t dealing with much data other than just the README file and a config file that was optional for the user. So, I went ahead with the mindset of adding a database when I really need it, to not complicate my development phase. I chose to deploy the application using Heroku since it was really quick and intuitive to use (I’ve also had prior experience).

Setting up the routes. ExpressJS made it incredibly easy for me to set up routes right-off-the-bat. All I had to do was import Express, and I was good to go and setup routes (Really simple). I setup the/:user/:repo route which gets triggered anytime a user navigates to matching links like fastdocs.io/aemmadi/coursebook-api where aemmadi is the user and coursebook-api is the name of the repo.

Getting the data. I was only focusing on GitHub repo’s for the time-being so the app searches only GitHub for user and repo . I utilize the GitHub Rest API v3 to achieve this. I scan the repo for a README.md file and a .fastdocs.json optional config file for users to have the ability to customize their renders with plugins, and more.

Hashing and generating HTML. I decided to hash the README files and compare them with the one in GitHub every time someone visits the same repo more than once. This allowed me to not have duplicate renders which saved write operations and storage space. Once it’s hashed, I pass the data to a Docsify imported HTML file, the config file is also passed into Docsify if it exists. At this point it is just fill in the blanks. If the config has a plugin in it, add that plugin, and so on.

Serving to users. Once everything is rendered, I use express.static() to serve the docs at /docs/:user/:repo . I wasn’t allowed to serve the docs at the same endpoint as it was already being used from earlier to trigger the GitHub function, so I had to improvise. I made it so that once everything is ready and good to serve I use res.redirect() to automatically redirect the user to the the endpoint where the docs are being served.

This is a very high level overview of the project and how it works. If you are interested in learning more on how it works exactly, feel free to check out our GitHub repo!

Challenges:

During my research and pre-development phase I always assumed this was going to be a straight forward project. I mean, how hard could it have been? I just call the GitHub API to get the README from the repository, and I pass that to a Docsify enabled HTML file to render the webpage right?

Turns out, I had to do something called static-serving to actually render and display the webpage. I couldn’t simply use res.sendFile() to just send the HTML file to the user. Given my limited knowledge with ExpressJS, I was quite confused as to why the app wasn’t working. It took me more than a day to realize that I had to use express.static() instead 😅.

Another big issue I faced was storage. I was using the fs module in NodeJS to read and write all data to the local disk. But when the time came for me to deploy the application, I thought I couldn’t rely on disk operations as they were “expensive” (or so I learnt). So I started looking into AWS S3 storage and spent a lot of time configuring that.

However, thankfully the way I built the application allowed me to safely deploy onto Heroku without having to worry about going over the storage limit. (I hash the README so I don’t make a duplicate copy of the documentation every time someone calls the same repo 😄!)

Branding:

I wanted this project to look professional. A project that could become something in the future and not just die in the list of repositories on my GitHub account. So, I went on a really insightful journey to brand my project so it can be marketable and used by people other than just my friends.

Think about it, when was the last time you used an open-source product (Or any product really) that didn’t have a logo, tagline, and stars (Star my project please!). Almost anything I use personally is really professionally branded, and I wanted other people to have the same sense of professionalism when they visited my project.

Since I didn’t have any prior graphic design skills, I used the plain old Microsoft Paint for my editing (Still the best minimalist editor imo).

Fun Fact: The project was called docsify-up before getting re-branded to fastdocs.io

The Future:

With everything said, there is still a long way to go. There is still so much that could be done to further improve this project and make it really useful. Some things that I can think of on the top of my head are:

  • AWS S3 Integration (I made so much progress configuring this, might as well)
  • Docsify theme support (Add docsify supported themes)
  • Custom path to get documentation from (Ex: docs/ , for people that have documentation not in their README)
  • Multi-file support (For people who’s documentation is split into multiple .md files instead of one big README)

If anyone is interested in contributing to this project and want to be a part of this passion project, feel free to go over the GitHub repo or just contact me!

Credits:

This entire project would obviously not have been possible without Docsify! It’s plays the most important role of parsing and rendering the README data really quickly.

I want to give a huge shout-out to Major League Hacking (and my mentor Ian Jennings, literally the best! 💯) for giving me the opportunity to be a part of their Fellowship program, from where this project was born!

Reach Me:

--

--

Anirudh Emmadi
Anirudh Emmadi

Written by Anirudh Emmadi

Building the future, one commit at a time | Software Engineer | Tech Enthusiast

No responses yet