2018 in Review
2017 was a year of some pretty significant shifts inside Miranj. The changes were so fundamental that they affected almost everything we did. The initial results were encouraging, but only now — two years into the experiment — can we fully appreciate the impact. Our first six years were about finding our feet, about survival. We are now starting to find our voice. Here’s 2018, in review.
We worked on eight different projects of varying sizes in 2018. Each project had its own set of challenges, but there were some in particular that stood out.
We’ve always strived to build performant websites, but we’ve never really had to deal with heavy loads. Performance takes a whole new meaning when a site is accessed by 50 to 100 people every second. This is the challenge that Guiding Tech came to us with. It is amongst the top 11k websites on the entire internet, and its traffic far outpaced any other project we had worked on so far. Guiding Tech gave us the opportunity to double down on and really push the limits of server-side optimisation. We learned a lot about Nginx, caching, concurrency, and were able to make major strides in handling massive loads on low-powered hardware.
We have been able to take the optimisations from this project and apply them far and wide. We also shared some of our learnings with the community at ReactFoo Delhi 2018, and have another talk on performance coming up this September.
There had been a growing itch to work on multi-lingual and non-English projects. I found it more than a little ironical that in a country with 22 official languages and only about 10% English speakers, all websites we were building were in English. 2018, finally, brought the opportunity to break out of the English bubble. We did a Burmese edition site for Myanmar Institute of Information Technology (also our first university website, yay!), and French, Spanish, and German editions for conveyor belt manufacturers Forech. The latter even involved some fancy translations and content-sync on the backend via the Google Translate API.
Five new languages in 2018, but none native to the country we operate out of. We’re still looking for that elusive Indian language web project.
We have been believers in separation-of-concerns and anti-vendor-lock-in ever since we started Miranj. This has manifested itself in many different ways — making all content client-editable without developer intervention, sharing the source code along with instructions to host the website anywhere, maintaining full transparency about our collaborators, etc. This philosophy also made us averse to ever hosting a client’s website. We firmly believed that the website and its content were the client’s intellectual property, and should be controlled by them. We would instead always ask clients to sign up directly with a web host, and then deploy the website on those accounts.
This arrangement worked well initially but we started noticing some patterns over time.
- Deployments were getting more complex. Earlier it meant simply uploading a bunch of files to a folder on a fully-managed, shared web host. But now we were dealing with DNS management, CDNs, image processing tools, image optimisation tools, web server level configurations, automated backups, VPS management, security protocols, and more. A lot of different moving parts needed to come together to host a website.
- Software updates to the underlying CMS and plugins. We would want all our deployed sites to pull down these updates, but we were no longer actively engaged on the project, and applying minor point updates felt like too small a quantum of work to re-engage. Yet this was not a trivial task either, because sometimes a minor update could also end up breaking something major or having unintended consequences.
- Critical security fixes. This is the sort of thing we did not account for in our naivety and youth because it felt so rare, but soon realised is actually not that uncommon. Vulnerabilities such as Heartbleed and critical security updates such as Craft 2.6.2982 made us realise that we did not have a contingency plan for delivering these security updates to our clients. We took evasive action in these specific instances, but realised we need a better fundamental approach.
- We were managing a lot of servers anyway. Our clients would always trust us with access to their servers. They would rarely revoke access at the end of our engagement, and we would often find ourselves fixing things on their servers, either of our own accord, or when they would bring something to our notice. This was all done pro-bono on a goodwill basis, outside any formal engagement.
At some point of time, we realised that while we did not offer hosting as a service, we performed a lot of what it entailed anyway. We also realised that ownership of content does not have to translate into ownership of infrastructure. Or rather, that Miranj can own the infrastructure, but still ensure that clients own all content and IP.1 Once we crossed that threshold, we found that there were a lot more benefits we could offer to our clients if we formalised this engagement, such as:
- Fully managed infrastructure – SSL, CDN etc. standard and baked in
- Security best practises
- Performance best practises
- Critical updates
- Robust, regular, automated onsite and offsite backups
- Automatically propagating any fixes for issues discovered across all sites we were managing
We signed our first batch of hosting clients in 2018, and we are grateful to them for placing their trust in us.
📦 Craft 2 Packages
Sometime during early 2018 we learned about a way to use Composer to install Craft 2 plugins.2 We were already managing a bunch of different Craft 2 sites, with at least four (dev × 2, staging, production) deployments per site, and adding new ones every couple months. The tedium of manual plugin installation had slowly but surely added up. So we jumped on the opportunity to automate plugin installation and have it under version control.
We adopted Derrick Grigg’s described method for two ongoing projects. Deployments became smoother. But the manual steps involved in the initial plugin install continued to feel like a chore, more-so now that one piece of the puzzle had been solved. One thing led to another, we went down a few internet rabbit holes, conducted many failed experiments, and finally realised that we could, probably, make plugin installs slightly easier. All we had to do was:
- Create a private Packagist server
- Maintain a human-editable list of Craft plugins
- Figure out ways to make plugins with different folder structures Composer-installable by issuing the standard
composer require <vendor>/<plugin>command
- Put in a process to auto-update the Packagist server whenever the plugin list is updated
- Allow the community to contribute and grow the repository of plugins
It was slightly insane, and I’m sure we lost more time doing this than we can ever make up in gained plugin installation efficiency, but we did it anyway. We launched craft2packages.miranj.in and managed to fully automate plugin installation.
My only regret is that we didn’t learn of this possibility sooner. Everything about Craft 2 Packages – inception, experimentation, and release – happened in May. Craft 3 was already out by then (released in April 2018) and most developers were in the process of switching over. While we are committed to keeping this server running for at least the next 10 years, we realise most Craft 2 projects are probably in maintenance mode now and will not go in for major changes. I feel like the community could’ve really benefitted from this had it been around when Craft 2 usage was at its peak.
We fell in love with Craft CMS when we built our first Craft powered website in 2014. We’ve built on it extensively in the following years. Craft also has a thriving developer community, largely centred in North America, Europe and Australia. Our interactions with this community were limited to Slack messages, at best. Then in 2017 they announced their own conference, Dot All. We decided to take the plunge and meet the community. Souvik travelled all the way to Portland, USA to attend the conference and put faces to all the Slack handles, GitHub handles, Stack Overflow users, and Andrew Welches (there had to be more than one). It was a wonderful experience and he had a great time.
That was 2017. Here’s Souvik narrating what happened the following year, in 2018 —
Our Craft implementations had matured significantly, especially our homegrown template architecture and code organisation which had been evolving over the last 3 – 4 years. I felt that it would be a valuable technique for other Craft developers and went on to propose a talk for Dot All 2018. A few weeks down the line, the Craft team invited me to take the stage at Dot All in Berlin. This was my first international speaking opportunity — undoubtedly, a pretty significant milestone. I felt the pressure while preparing for the talk and encountered frequent moments of excitement and butterflies-in-stomach along the way. The entire process took about two months of exploration, iterations and internal discussions before the final slides started taking shape a few weeks before the conference.
Prateek and I flew into Berlin a day ahead of the 3-day conference. Although this was our first visit to Berlin (and Germany) we never felt lost (or alone) thanks to the constant stream of suggestions and recommendations on the Dot All Slack. We kept bumping into fellow attendees everywhere — in the hotel, at the venue, at nearby bars and eateries. It was a lot of fun.
My talk was scheduled for the third (and final) day of the conference. I kept working on my slides from the sidelines and the tweaks continued until about half hour before the presentation. I took the stage right after lunch, slightly nervous but definitely excited. The presentation went very well without any significant hiccups. It was the best version of all the rehearsals I’d done with Prateek and I was quite pleased. More importantly, it was received very well by fellow attendees. Many found it helpful, some had questions, a bunch of them gave us good feedback and asked us to share our code for reference and their understanding.
The overall experience was a growing one. We managed to shun our imposter syndrome, present in an unfamiliar culture (and geography) and hold our nerves throughout the experience. It was deeply fulfilling to engage with the Craft community and share our work and experience with everyone.
While we had a lot of highs, not everything went great, and it would be dishonest if we did not mention the lows in an annual review.
The first setback was the closing down of Design Fabric. The website had undergone a redesign earlier in the year and we took that opportunity to work on its performance as well. Using a bunch of different techniques we were able to make the media heavy Design Fabric, already one of our fastest shipping websites, even faster. We were proudly showing it off to clients and our peers. However the project was taken down shortly after the founder of the publication was accused as a part of the #MeToo movement.
The other major setback was in December. Three weeks into what was meant to be a much longer relationship, a project we were working on was brought to an abrupt halt. We had failed to resolve differences with the client or find common grounds on which to proceed. Having been in business for eight years now, we have encountered a healthy diversity of opinions and personalities. We would often take pride in our willingness and ability to use reasoning and discussion to resolve differences between teams, bridge gaps and move a project forward. This experience reminded us that we still have much to learn. This was the first time we found ourselves at a stalemate.
Running a business is no easy feat — between chasing new leads, managing ongoing projects, looking after our hosted websites, handling support for older projects, accounting and regulatory compliances, running an office, keeping up with the industry, learning new skills, and doing the actual design and development work to build websites, our team of two rarely finds time to pause and reflect. This review lets us do that; take stock of how far we’ve come, and appreciate how far we have to go.
2018 in Numbers
- Undertook 8 client projects
- Collaborated on 3 projects
- Delivered 5 talks
- Hosted 1 event
- Shipped work in 5 languages
- Plugins: 2 new releases, 1 update release, 1 new Packagist repository
- Worked with/in 3 countries
- Worked with 4 non-profit organisations
- Cups of coffee consumed: don’t know (we don’t keep track)
- 8 co-workers
- 11 new office plants
- 1 person got married
See you next year!
Each website is hosted on an isolated, dedicated VPS. There is no data sharing between different clients, and we offer clients complete access to their server via SSH, if needed. ↩︎
This might sound like a banal statement to some of you, in which case, let me remind you that while Craft 3 uses Composer natively to install itself as well as plugins, this was not the case with Craft 2. The Craft 2 plugin installation process involved manually downloading the code and placing it inside the designated plugins folder. While this was not a terrible workflow, it was far from ideal. ↩︎