Evolving Code: From the Crust to the Core
At Shopify, as our team scales, we’ve been trying to figure out how to manage the influx of new design and new components into the codebase. On one hand, we want all code to meet our coding standards, use the existing system where it can, and expand it when necessary.
As new functionality and new experiments get introduced, we are finding ourselves unsure how best to manage this.
Quick and dirty and refactor later? Problem is, people are lazy. Things might not get revisited and we’ll be left trying with the less-than-desirable code for some time.
Spend the time up front to “do it right”? It might limit our ability to iterate quickly if we fuss too much on doing it right. With experiments, much if not all of the code might just be thrown away anyways or changed with the knowledge gained from the experiment.
From the Crust
We’re approaching this now by placing code in the crust and then moving it to the core as it is refined and needed.
What does the crust look like from a code perspective? We have different files that we’ve been using:
Often times, the designs are specific to a section of the app. They haven’t yet been abstracted out to apply elsewhere.
While not specific to one area, we know that this is code that we don’t want. We know that this is code that desperately needs to be refactored and will be tackled sooner rather than later.
This is relatively new. At the ruby level, we’ve done beta flags for years but hadn’t considered what this meant from a CSS perspective until recently. We’re trying an experiments prefix to identify stuff that will be tested and then decide what to do with it when the experiment is done.
To the Core
I have a motto as of late: “Make the right things easy and the wrong things hard.” I fear that these approaches make it easier for code to live at the fringe and that people won’t take the time to refactor the code, pushing it closer to the core.
However, I have been thinking about component systems — especially ones that live outside of the core product. In such a situation, having components developed on the crust that then ‘graduate’ to the core sounds like a good approach.
In this way, there’s a higher bar that would need to be met, due to the longevity of these core pieces.
In the world of Object-Oriented Programming, there is a saying: “Make it work, make it small, make it fast.” This is an approach that we’re trying on for size and will hopefully create the right balance of code quality.