Saying goodbye to emotion

Recipe is the ezCater design system in production since 2018, which we've recently open sourced. Check out the documentation site for examples and a catalog of React components we use to build amazing experiences for our customers.

First things first. I’m not going to be talking about a 2002 science fiction movie about a future in which feelings and artistic expression are outlawed.

Christian Bale from the movie "Equilibrium"

Instead, I’ll be talking about the emotion 👩‍🎤  CSS-in-JS library we’ve been using since early 2018 for authoring and distributing styles for our React applications, and more specifically, why the Recipe team decided to wave a fond farewell to the library, what we’re doing instead, and why we’re excited about it!

Prologue

(The context here is an extract from our v12 migration docs, so skip ahead to the next heading if you’d like)

When the Recipe project was created, we had to decide how we would package styles alongside React components for distribution within our applications. Ideally styles would be co-located and packaged with components, such that applications could use Recipe components without having to "remember" to manually include a separate stylesheet-per-component, or maintain a large global stylesheet.

The Recipe team made the choice to utilize the emotion CSS-in-JS library, as it had already been well established as a tooling choice in ezcater's core web sites and web applications. Using emotion within Recipe solved the packaging and distribution problem, without requiring any additional configuration overhead for our existing applications.

In 2019, the Emotion maintainers shipped a major release of the emotion libraries (v10), adding some very useful new features and updating the internals for compatibility with React (by removing usage of deprecated APIs). Unfortunately for us as consumers of Emotion, this change required a significant update to Recipe that needed tight coordination with downstream applications.

Updating any major peer-dependency is somewhat challenging, and this situation was no different; applications could not upgrade Emotion without a corresponding Recipe release, but Recipe couldn't be upgraded without either cutting off support for applications that were not yet using the latest version of Emotion. 🐔 🥚

Once again, we find ourselves in a similar situation - the Emotion team have shipped a major release with breaking changes (v11), and progress in the react tooling ecosystem (supporting webpack 5) necessitates that we discontinue use of the prior version for compatibility.

This leaves us two options, upgrade emotion in Recipe (and all downstream applications), or remove Recipe's dependency on Emotion to unblock downstream applications from their own upgrades.

The Recipe team have chosen to do the latter. We've chosen a strategy that creates with some new opportunities:

  • Solving the "Recipe theming" story for supporting multiple applications with different branding/marketing focuses

  • Enabling a solid story for creating new "branded" components outside of Recipe by utilizing Recipe's theming engine

  • Reducing runtime overhead by leveraging static CSS, instead of CSS generated at runtime

  • Providing a path to optimizing performance by leveraging the extraction of CSS at build-time

  • Creating a developer-friendly experience by leveraging TypeScript at the core our our styling engine.

I’ll be needing stitches

There we go again. Despite what Google search may lead you to believe, I’m not going to be talking about the 2015 Shawn Mendes top 10 hit.

Shawn Mendes is singing and dancing!

No, in this case I’m referring to the stitches 🪡 🧵 CSS-in-JS library. I’m not actually going to do a deep dive on this library though, as the Recipe team are intentionally keeping this dependency internalized (more on this shortly).

Instead, let’s have a very quick look at some of stitches' killer features:

  • First-class variant API. Seriously, this is a huge winner for the Recipe team. A before/after comparison of Recipe’s layout component shows how powerful this abstraction can be. In addition to reducing the layout component footprint from 254 loc to 123 loc, the declarative variant API is much easier to understand (both by devs and static extraction tooling).

  • Fully-typed API. This is both great for the devs maintaining Recipe, who can now see a typed list of CSS-variable available to any given component, but also to application developers who are provided with rich type definitions for component responsive props.

  • Custom utilities for authoring CSS with property shorthands (like tailwind pt, pr, pb, pl), property bundles (like tailwind px, py, inset etc), CSS polyfills and more.

  • Best-in-class debugging experience. Stitches generates styles for component variants with BEM-like syntax, for example, if you take a peek at accented cards in Recipe’s doc-site, you’ll see class names suffixed --imagePosition-top and --accent-info.

We’ve paired stitches with our very own snitches library, allowing us to use stitches' fantastic core API, while eliminating the need for any additional setup to supporting server-side-rendering.

Ice Cube saying "snitches get stitches"

Shhhh, keep this to yourself!

As I mentioned, the Recipe team are intentionally keeping the stitches dependency internalized. You won’t see stitches in Recipe’s public API, nor should you have to give any consideration to stitches when installing Recipe or using Recipe components.

Internalizing this dependency is critical for us to avoid the peer-dependency challenges we had with emotion. It is also they key to the Recipe team’s plans for future performance optimizations; we want to eliminate the need for a JavaScript runtime for styling applications. While authoring styles in TypeScript gives us a fantastic developer experience, JavaScript is still the most expensive resource, and having all styles generated at build time (just like SASS, LESS etc) will allow us to minimize this cost without sacrificing the authoring experience.

Read More

Tags: javascript, react, github

Multi-armed Bandit Experimentation

What is a Multi-armed Bandit Experiment?

Problem Intuition

Let’s imagine you’ve decided to hit up the casino and try your luck at the slots. You don’t know which slots are best, but you have reason to believe that some of the slot machines are better than others. You only have a limited amount of money to play with, so you want to play each of the machines enough to learn which is going to be best (explore), and then as you learn, play the best machines most frequently to maximize your return (exploit). Choosing which machine to play is referred to as the exploration / exploitation dilemma.

Read More

Tags: experiments, ruby, engineering, kafka, dynamodb

Migrate, transform, and backfill data with zero downtime

Oftentimes database tables begin with the best of intentions. They can start out narrow and clearly named with well-defined content, but as our applications and teams grow, we may start to notice that those same tables begin to take on a different shape. It’s possible that they grow wider and are harder to work with than you remember. They could be holding data around multiple concepts, which might mean your models are breaking the single responsibility principle. Perhaps that table didn’t start out concise at all. There are many common scenarios that cause tables to exist in a cumbersome form, but it doesn’t mean they have to stay that way.

Read More

Tags: ruby, development, engineering, rails, activerecord, migrations, database

You're not in the zone!

Working with the SQL ‘time’ type in Ruby on Rails

 

Read More

Tags: ezcater, ruby, engineering, coding, rails, time zones, timeofday, activerecord, time, active record

ezCater Code Culture

A little while ago, we decided to define and document ezCater's pull request culture in an effort to streamline onboarding and facilitate collaboration as our team doubles, quadruples, and beyond in size. Clearly communicating both how we operate and also why we do things the way we do, sets people up for success from day one. We're proud that new hires are able to contribute to the codebase during their first week and are always looking for ways to simplify onboarding.

Read More

Tags: ezcater, culture, values, github, development, engineering, coding, creating

The Long, Long Journey of Connecting to Snowflake with Ruby

Charting a Path from Redshift to Snowflake

ezCater is a data-driven company. For a long time, the principal source for our metrics was our Redshift data warehouse. As a result, we invested heavily in building out the data systems that fed Redshift. We also staffed up a team of engineers dedicated to building, enhancing, and growing our data systems. (And yes, we're hiring!)

Read More

Tags: data warehousing, snowflake, ruby

The case against React snapshot testing

...and what you can do instead!

We've been working with React for a few years now here at ezCater, during which time our unit testing story has been steadily evolving. One of the recent strategies we've tried out is Jest snapshot testing.

Read More

Tags: unit testing, jest, snapshot testing, javascript, react

How ezCater Engineers Deploy to Kubernetes

Working at ezCater is an unbelievable opportunity to witness scaling close up. Requests, transactions, revenue, it’s hard to find something not going up and to the right. That’s great, but in each area of growth requires figuring out how to scale it.

The Hardest Thing to Scale

The particular metric that was keeping me up at night was the “number of engineers trying to work together in harmony”. Ten, twenty, forty engineers are simply different scales and they require different systems to ensure things move smoothly. But how would we even describe a “happily scaling” organization from a developer productivity standpoint?

Tom Petr addresses this in his slides on Maximizing Developer Productivity in a Microservices Environment. This presentation shows the KPIs & shape of the curves I want for our organization.

Read More

Tags: devops, kubernetes

Turning Designers Into Data Nerds

At ezCater, we believe that designers should care deeply about using data at all stages of the design process. Whether qualitative or quantitative, it helps to inform and empower our design decisions.

Data is a powerful tool that allows us to:
  1. Validate that we are solving the right problem
  2. Test small assumptions to get to the right solution with quantifiable impact
  3. Understand what the business cares - and should care - about, which influences design strategy

Product manager Lindsay Matthews and I gave a talk at the recent UXPA Boston conference about all the ways that designers can use data to be more effective. Learn more in the slides below:

Read More

Tags: experiments, women_in_tech, ezcater, design

Machine Learning LTV (Part 2)

What did we learn about machine learning?

This is part 2 in a series about Estimating the LTV of new SaaS customers. To do this we're taking all the datapoints we have about a user after X days and seeing whether we can predict how much revenue they'll spend in their first year.

In Early Prediction of Lifetime Value (LTV) we left off when we had a CSV full of features and the Year1Revenue(Y1R) that we were trying to predict. It was time to put the pedal down and see whether machine learning is all it's cracked up to be.

Read More

Tags: machine learning, ltv

About ezCater

We're the #1 online – and the only nationwide – marketplace for business catering in the United States. We make it easy to order food online for your office. From routine office lunches to offsite client meetings, from 5 to 2,000 people, we have a solution for you. ezCater connects business people with over 50,000 reliable local caterers and restaurants across the U.S.

ezCater is hiring!

We’re always looking for highly skilled full stack and iOS engineers to help execute our technology goals while riding this rocket ship of growth. Our people are terrifically talented straight-shooters who love what they do. And everyone is generous and kind, too — we have a strict no jerk policy.

View ezCater Opportunities

Recent Posts

Subscribe to Email Updates