Migrating to Recipe 12

Prologue

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 (to name just a few).

The Recipe v12 release is the first step of this journey.

Breaking changes

This release is a major version release and as such, will require migration steps for applications that currently use Recipe version 11.x or below.

While we have tried to minimize the number of major API changes, the following changes are considered breaking changes:

  1. While all components that accept a className prop in v11 will continue to accept a className prop in v12, new specificity issues may occur if both the className provided is generated by emotion AND the associate styles override Recipe's component styles.
  2. The CSS variable names Recipe uses within its components have changed. While the Recipe's CSS variable names are not considered part of Recipe's stable/documented public API, as these variable are visible with devtools we feel it is important to call out that the naming convention we use internally has changed.
  3. The v1 version of the @recipe-ui/theme-marketplace package is not compatible with Recipe v12 (due to breaking change #2).

Other significant changes that are considered non-breaking include:

  1. The EzTable component no longer pins the first column on small screens.

Migration steps

Installation

You can update your Recipe installation using a package manager like npm or yarn.

npm install @ezcater/recipe@latest
---
or
---
yarn upgrade @ezcater/recipe@latest

If you're building a marketplace application, you will also need install the latest marketplace theme as follows:

npm install @recipe-ui/theme-marketplace@latest
---
or
---
yarn add @recipe-ui/theme-marketplace@latest

IE 11 support

Applications that need to support IE11 may require an updated list of polyfills to use Recipe.

The Recipe team recommend using Polyfill.io in your application. Polyfill.io will apply only the polyfills needed for the requesting browser.

We recommend using the following polyfill bundle features:

  • default
  • es2015
  • es2016
  • es2017
  • smoothscroll
  • Reflect.ownKeys
  • NodeList.prototype.forEach

If you're using the css-vars-ponyfill to provide support for CSS variables in IE, please ensure you're running an up-to-date release. Version 2.4.0 or higher is needed for compatibility with Recipe.


Build tooling

Recipe v11 internally used CSS Modules to define theme tokens, and required CSS importing support. This is no longer a requirement for Recipe v12.

If you needed to add bundler configuration to your app to transpile node_modules in order to support Recipe 11, such as was the case for next.js applications, this additional configuration is no longer needed and can be removed from apps using Recipe v12.

For example, if your application previously needed to use the next-recipe-css plugin, this plugin is no longer needed in Recipe v12.


Server rendering

In prior versions of Recipe, in order for applications to render Recipe components on the server, additional set up was required to ensure styles would be included in the initial render. This set-up typically included the use of Emotion's extractCritical API.

This setup is no longer required to support the server rendering of Recipe components, and may safely be removed from your application (if your application is not relying on emotion directly).