On moving forward

The last 2 years have been overwhelming, in every imaginable way. Moving on means first reflecting on what I'm moving on from though.

I joined Quandoo after some missteps in my career. I had left a job I was very happy with for practical considerations, and my 2 next (both very shortlived) positions didn't pan out for various reasons. I had several offers, and was most excited to join Quandoo, so I accepted theirs.

There were several reasons for this. A CTO whose vision and attitude actively excited me. A set of engineering challenges I felt particularly strongly positioned to help them tackle. Friends I had worked with before. I was brimming with excitement, so I jumped right in.

When the state of the codebase I was tasked to work on started bothering me, I thought about making some changes. Looking back at my experience at ResearchGate, and lessons I had learned on my own time, I decided to do something else instead: propose and implement an RFC process; a way for anybody involved in writing code to propose changes, discuss their impact, reach consensus and execute successfully.

Looking back through the repository now, in about a year's time, 9 proposals were drafted. From changing our branching strategy to finding a single carousel package to accomodate all of our swipey needs. Some were good, some (primarily one of mine) were misguided, or just never reached consensus. Regardless of the outcome of individual proposals, I'm incredibly proud to have worked with engineers from junior through senior, to champion changes proposed by them, and get them excited about making improvements that don't directly translate to more revenue.

It was incredibly difficult to hear that, despite working hard to involve everyone, and make these improvements not about me, I was still perceived as arrogant by some; that I felt I was better than other developers. Particularly so because it's the exact opposite of what I feel.

One of the things to come out of the process though, lovingly called (RFC-002), was Quandoo's design system.

A trojan horse

The RFC that led to the initial version of Cookbook, Quandoo's design system, was a bit of a trojan horse. I understood it would be a hard sell to implement something like this from scratch if I was unable to show its benefits. So, when @jxnblk released styled-system, I jumped on the opportunity of an exciting new way to style components to take it a step further.

Some designers and I sat down, and came up with a very barebones set of design tokens. Spacing, elevation, borders and some colors. Based on those, I asked them to provide me the specs for a Card component they'd been designing, and we sat down together as I live coded the implementation for them. They were impressed, but that didn't mean we were there yet.

We demoed the proposal to the development team and tried the individual parts out in planned stories. We sat down with relevant stakeholders, moved diligently, and a couple of months later we had published a first version of the design system.

Although Quandoo's primary b2c property still doesn't use it as much as I'd have liked, a couple of months later when we were asked to build an MVP it really showed its values. Conversations with developers that contributed to the MVP led us to estimate it shaved a good 1-2 sprints off of development time. That may not sound like much, but it's 2-4 weeks that 3 developers can spend on something else that could bring value to your company.

A couple of decisions in particular worked out very well:

  • We set up a strong process that included designers, developers and led to contributions by everyone involved.
  • Documentation came first, and we agreed that a UI library is only a small part of a design system.
  • We tested the right things: visual regression tests through Percy, accessibility tests through axe, and behavior tests through react-testing-library.
  • We stored design tokens in YAML files, which we parsed with Handlebars, mixing in polished as well. So tokens could refer to other tokens, and we were free to output them to other targets as well.
  • We used Typescript Unions to help developers make their components accessible.
  • We strictly followed Semantic Versioning and Conventional Commits, and used semantic-release to make that simple. This later led to standardization across the company.

It wasn't all sunshine and rainbows though. Some mistakes we made:

  • Some "semantic" colors weren't named semantically at all, and changing color names means incurring a breaking change, so a major version increment.
  • We wrote components that didn't have clear use-cases, but only existed in Figma or in 1 place in 1 product.
  • I wrote the token parser myself in Folktale, a library with a collection of ADTs and utilities for working with them. I went completely overboard, and made it unusable for other developers.

Sharing knowledge

Together with other leads we rekindled the Front-end Guild (later renamed to Web Guild as its scope expanded). We talked about functional programming, css grid, writing reviewable code and much more. In its final incarnation before I handed in my resignation, we got green light to give every web developer half a day a week to learn about specific topics (that we all voted on). The last one I attended, after gauging interest, I live-coded pagination into an initial implementation proposal for GraphQL. To the best of my knowledge, none of the other guilds work to get better at their craft as involved as the Web Guild does. I hope they'll continue these sessions, and keep learning & teaching.

Moving targets

Shortly after bringing a trusted friend on board to Quandoo and the Web Platform team, we were asked to build an MVP to validate part of a new direction, one piece of a larger puzzle. This new product was planned during a transition phase; we had just started the journey to a distributed, Kafka driven microservices architecture. With that change came a lot of uncertainty, and we were at the forefront of figuring out how to work in this new reality. We had to balance delivering in a reasonable timeframe, using as little of the old systems as possible (also due to a lack of capacity in Java-based developers), being the first consumers of new tech (for example, Keycloak), while making sure what we're building is actually something Quandoo's customer base wants to use. Most of the credit here goes to the rest of the team. What I am proud of however, is unleashing my friend (and the rest of the team of course) on these challenges, and giving them space to do things right. They were fantastic, and built up an impressive amount of infrastructure, knowledge and tools that will hopefully help Quandoo long after our departure. They spent hours pair programming with recently joined developers, with folks who had never worked with Docker, Kafka, Kubernetes et al, and hadn't used Node for anything other than rendering React.

In my humble opinion, we picked the right tools for the job, and I'd like to think this product is set up as well as can be for future success. I'm glad we spent time upfront getting the tooling right (for example, writing a small Node CLI tool that produces schema-compliant Kafka messages, a custom integration layer to be able to develop against Keycloak without having to restart the Java server whenever you changed a template), and that we managed to stay away from our old systems as much as we did. Not because of any (whether perceived or real) code quality issues, but because they're hard to run locally and deterministically and would've slowed down local development.

When we were ready to launch, the preparation showed. The roll-out was measured, and went through in 1-2 days without any real issues, leaving us to celebrate what felt at times like a Herculean task. I couldn't be happier about the involvement of all team members at every step of the way; from ideation & design to deployment & monitoring.

On Failure

It'd be disingenuous if I didn't speak about my failures as well. We. All. Fail. Talking openly about failure can be scary, but has such pronounced positive effects on an entire organisation, that not doing so borders on reckless and makes getting over your fear worth the effort.

I've been overly critical, contributing to a good junior developer leaving the company. My "loose" management style cost time and caused frustration with the product manager I was working with. I caved on architectural decisions that led to more delay, when I knew I should've stood my ground. I made off-hand critical remarks about colleagues in informal settings, that in retrospect were more about my frustration with myself or the company than about them.

There's one decision above all, however, that is not a failure, and that I'm proudest of: to stand by someone who trusted me when it mattered most to them. It came at personal cost. I knew this upfront. I would do it all over again.

So, forward

I'm not sure what's next. I've started interviewing, and am talking to companies whose mission & values excite me tremendously. I think I'd prefer to work for a company that has strong guarantees around remote work, work-life balance and ethics, both in their product and in their culture. I'm not sure if want to be an engineer, a manager or somewhere in between, but I'm sure that'll work itself out. For now I'm going to learn some new things, read, and enjoy my time abroad. I'll reflect more on my career so far, and probably write more about it.

Lastly

To any Quandoorians reading this; it's been a blast. I loved working with the designers, product managers, agile coaches, the ops teams, engineers, recruiters and sales staff alike. I'm sure my departure won't deter you from making awesome stuff, and that you'll all be fine (maybe even better). I love you all and hope to work with you again in the future. ❤️

StevenLangbroek