@aivenio/design-system

Aiven design system

Usage no npm install needed!

<script type="module">
  import aivenioDesignSystem from 'https://cdn.skypack.dev/@aivenio/design-system';
</script>

README

Aiven design system

Netlify Status CI

Implementation of Aiven design system, released as an npm package. Quick tour:

  • We use Figma to design the system. The design tokens are controlled in a Figma page (see example page), which are synced automatically to tokens.json
  • Component implementation uses design tokens to define their visual look. This will make updating the visuals easier in the future by changing the tokens.
  • Design system is exposed as React components via NPM
  • Tailwind is used for styling

Installing into your app

  • npm install --save @aivenio/design-system

  • Make sure to add the correct fonts in your app. Inter for Aiven theme.

  • Import the CSS to your app

    • Aiven theme with import '@aivenio/design-system/dist/styles.css
    • If you used THEME=X npm run build for building, use import '@aivenio/design-system/dist/styles_X.css
  • Add React context component to the root of your React app

      import MyApp from './MyApp';
    + import { Context } from '@aivenio/design-system';
    
      const Root = () => (
        return (
    +    <Context>
            <MyApp />
    +    </Context>
        )
      )
    

Developing the design system

Use npm 7! With older npm versions, install peerDependencies manually. If you encounter "Cannot find module..." errors, try rm -rf node_modules && npm i. This seems to be a bug introduced in npm@7.

Environment setup

This project requires certain environment variables to be set before commands such as npm run build will work. Most can be copy/pasted with the help of your teammates, but you will need to generate a NPM token yourself in order.

  • Create an NPM account here if you don't already have one.

  • Generate a token for your account. You can read about how to do so here. For the purposes of building the project, read-only access will suffice.

  • Copy the sample environment file: cp .env.sample env

  • Add the necessary data into the newly-created .env file.

  • Source the .env file for the environment variables to be set: source .env

    Note that any time a new shell instance is created (for example, when you restart your computer), you need to run source .env again, or the variables won't be set. Consider using a solution such as autoenv to automatically apply the .env file.

  • npm ci to install dependencies

  • npm run build to build the project

  • npm start to start Storybook

After Figma has been edited, run:

  • npm run figma -- sync to fetch new tokens to ./tokens.json
  • npm run build to re-create automatically generated files

Optional DX improvements

npm link

To develop Design System components in the context of an application, it is easier to do it with npm link. It allows you to make changes to components, and instantly see the change in the context of the app (e.g. Console).

  1. In design-system directory, run npm link
  2. In design-system directory, run npm link <path to app>/node_modules/react to avoid running into conflict of having two react instances. This will otherwise break the rules of hooks and crash the app. More info on the issue here. If the command fails with errors about peer dependencies, re-run the command, adding --force at the end.
  3. In the app directory, run npm link @aivenio/design-system
  4. Now <app>/node_modules/@aivenio/design-system is a symlink to your local design system directory.
  5. In design-system directory, run npm run watch
  6. Done! Now you should be able to develop DS locally, and changes are reflected to the application which depends on @aivenio/design-system
  7. When you want to stop using the npm link, and go back to the regular imported version, in your app directory, run npm unlink --no-save @aivenio/design-system, then npm i to reinstall the dependency.

Running tests

Remember that source .env is needed before NPM commands.

  • npm test to run all tests once
  • npm test -- Button to run only tests matching Button
  • npm run test:watch to run tests in watch mode
  • npm run test:coverage to run all tests and see the coverage

Note! It's good idea to run tests in watch mode when developing. If for example snapshot tests fail due to some code changes it's easy to update those with the jest commandline tool. If you want to just update the snapshots that can be done with jest --updateSnapshot. More information here

Other useful commands

  • THEME=<brand> npm start to start local storybook with a theme
  • THEME=<brand> npm run build to build DS module with a theme
  • npm run figma -- sync -i .figma-file.json to generate ./tokens.json but using previously fetched local file instead of fetching the huge Figma file from API.
  • npm run figma -- sync --debug to enable more verbose output
  • npm run figma -- sync --foundation-page-name 'my foundations' to override options.
  • jq '.document.children[] | select(.id == "8916:120229")' .cache/figma-file.json to slice Foundations page from whole Figma file JSON.

There is more documentation for the Figma sync tool.

Build and release process

Storybook

To build storybook locally

Run npm run build:storybook.

Storybook deploy

Storybook is deployed to Netlify everytime new code is merged to master.

Design system package

How to build design system package locally

  • run npm run build:ds
  • see dist for the built code

How to create a release

  1. Run npm run release -- --bump <bump> (all the dashes are needed) where bump is one of major, minor or patch.

    This command will automatically checkout a release branch, commit the version bump, and open your browser to submit a PR.

  2. Review the PR created, and merge it to master. GH actions will handle the rest.

Any API breaking change should be a major version bump and should be mentioned in release notes!

Breaking changes

Breaking change examples:

  • Rename a prop in Button component
  • Rename Card component to Box
  • Remove a prop
  • Remove a component

These are not breaking changes:

  • Add a new prop for Button
  • Add a new component
  • Changing storybook
  • Changing tests

Background

A lot of research was done into existing design systems, and if we could reuse parts of them. The conclusion was that we take mostly inspiration of the good ideas, and maybe use individual components by copy pasting code to our system.

Evaluation of existing React libraries

Some of the projects are huge, the link most commonly points directly to the part of the code base which defines the components. For tests, I checked that tests for a few components look OK, no coverage or deeper analysis done.

Next things to consider:

  • Is treeshaking possible when using just parts of the library? Size of the dist is also important factor, but after treeshaking the footprint should be quite similar across libraries
  • Maturity and activeness (commits, recent activity, contributor distribution, closed vs open issues, PR merging activity)
  • Are they migrating to another tech ? JS -> TS, Sass -> styled-components, etc
  • Owners, is it community driven or company driven? Project with 13 stars can be super mature if it's been developed internally in a company for 20k commits for N years
  • Accessibility
  • Customizability, do you need to fork or can you customise while getting upstream updates?
Link Commits* JS/TS Styling License Tests Other
Ant Design 18.6k TS Less. example MIT ☑️
Aragon UI 0.8k JS styled-components MIT Not much
Baseweb by Uber 2.3k JS (Flow) style-tron MIT ☑️
Basis 0.3k JS emotion MIT ☑️
Blueprint 1.8k TS Sass Apache 2.0 ☑️
Carbon 6.8k JS CSS classnames linking to Sass Apache 2.0 ☑️ ☑️ Storybook
Fluent UI by Microsoft 8.6k TS CSS in JS, seems to be a custom one MIT ☑️
Grommet 5.2k JS styled-components Apache 2.0 ☑️ ☑️ Storybook
Material UI 11.9k JS CLSX, CSS in JS. Example MIT ☑️
MongoDB design 0.4k JS CSS package.json says MIT, no LICENSE file No
Pivotal UI 4.0k JS Sass MIT ☑️
Polaris by Shopify 6.1k TS Sass Modified MIT, see more ☑️
Primer by GitHub 4.5k JS styled-components MIT ☑️
React Bootstrap 3.8k JS Bootstrap CSS classes MIT (also Bootstrap is MIT) ☑️
Reactstrap 0.8k JS Bootstrap CSS classes MIT ☑️
RMWC 1.9k JS CSS classnames using material-components-web by Google (source is Sass) MIT (also material-components-web is MIT) ☑️
Salesforce Design System 9.5k JS Sass Code BSD 3-Clause, see: https://github.com/salesforce-ux/design-system#licenses ☑️
Thumbprint 0.7k TS Sass Apache 2.0 ☑️
VTEX Styleguide 4.3k JS Custom Tachyons classes + CSS. Example implementation and CSS Unlicensed Not much
Zendesk Garden 0.8k TS styled-components Apache 2.0 ☑️ ☑️ Storybook
  • Most of these repos are monorepos managed with Lerna. Commit count is just to give rough estimate of how much the code has been iterated.

For further investigation, you can find plenty of components in GitHub: https://github.com/search?l=&p=99&q=created%3A%3E2015-01-01+extension%3Ajs+extension%3Ajsx+extension%3Ats+extension%3Atsx+size%3A%3E100+filename%3AButton.js+filename%3AButton.ts+filename%3AButton.jsx+filename%3AButton.tsx+filename%3Abutton.js+filename%3Abutton.ts+filename%3Abutton.jsx+filename%3Abutton.tsx&ref=advsearch&type=Code

You can find more design systems here: https://github.com/alexpate/awesome-design-systems. Not all of them have open source code.