# Strapi Design System: the React components behind the Strapi admin panel

> Strapi Design System is a TypeScript and styled-components component library, published as a monorepo with `@strapi/design-system`, `@strapi/icons` and `@strapi/ui-primitives`, that gives plugin authors the same UI vocabulary the Strapi admin uses. It suits teams building Strapi plugins, and it ties your plugin to React and to the design decisions of one vendor.

**strapi/design-system** — Strapi.io's design system :rocket:

- Repository: https://github.com/strapi/design-system
- Website: https://design-system.strapi.io
- Stars: 541 · Forks: 206
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/strapi-design-system

## What the design system is for inside a Strapi project

Strapi Design System provides guidelines and tools to help anyone make Strapi's contributions more cohesive and to build plugins more efficiently. That is the project's own statement of purpose, and it narrows the audience in a useful way.

The problem it addresses is specific. Strapi's admin panel is a React application, and a plugin is a React application that lives inside it. A plugin that invents its own buttons, its own inputs and its own modal will look wrong next to the core interface, and the plugin author has no good way to reuse the real ones unless they are published as a package with a stable API. The design system is that package.

So the audience is plugin authors and contributors, not the general React community. The value proposition is coherence, which is a different kind of value from capability. A plugin built with these components inherits the spacing, the colour tokens, the focus behaviour and the accessibility work that the Strapi team already put into the admin panel, and it inherits them by importing a provider rather than by copying styles.

The homepage is design-system.strapi.io, the documentation site, and the topic tags are `design-system`, `hacktoberfest` and `styled-components`. The last of those three is the implementation choice, and it has consequences for anyone considering the library.

## Three packages, and the peer dependencies they impose

The recent releases show the shape of the distribution. Three packages are versioned and published together: `@strapi/design-system` at 2.3.0-alpha.0, `@strapi/icons` at 2.3.0-alpha.0, and `@strapi/ui-primitives` at 2.3.0-alpha.0, all released on 2026-09-24.

The separation makes sense. Icons are a separate concern from components, and a primitive layer underneath both is a sensible structure for a design system that wants to share spacing and colour decisions across everything it publishes.

The installation command in the README shows what a consumer is actually pulling in, and it is worth reading closely because it lists the peers rather than the internals:

```bash
$ yarn add react react-dom @strapi/design-system @strapi/icons styled-components
```

or the npm equivalent:

```bash
$ npm i react react-dom @strapi/design-system @strapi/icons styled-components
```

So React and ReactDOM are peers, styled-components is a peer, and the two Strapi packages are the ones you actually want. That is a good sign, because a component library that lists React as a peer rather than a dependency lets the host application own the React version and avoid the duplicate-React class of bug that breaks hooks.

It also means you are committing to styled-components as your styling approach in the plugin, alongside whatever the rest of your codebase uses. If your plugin already uses CSS modules or a utility framework, you now have two styling systems in one bundle.

One detail to note in the repository metadata: the root `package.json` in this repository is marked `"private": true` and is named `design-system` at version 1.0.0. That root manifest describes the monorepo workspace itself, not the published package, which is the separate `@strapi/design-system` name. The published artefact and the repository root share a name and do not share a version line.

## The provider is the entire integration surface

The README's getting started section is short, and its brevity is the design.

You wrap your application with the `DesignSystemProvider`. You can additionally pass a theme and/or a locale, and the README notes you do not have to, because there are default values for both. The example is:

```js
import { DesignSystemProvider, lightTheme } from '@strapi/design-system';

function MyApp({ children }) {
  return (
    <DesignSystemProvider locale="en-GB" theme={lightTheme}>
      {children}
    </DesignSystemProvider>
  );
}

export default App;
```

That is the whole contract. The provider takes children, so it is a context provider that supplies theme, locale and any shared state the components need, and it renders nothing itself.

The `lightTheme` export and the `locale` prop together tell you how theming is expected to work. Theming is by token and by context, not by passing a className to every component, and the locale prop suggests the components render their own translated strings, which is a meaningful feature for a system that has to live inside a CMS with a language setting.

After the provider, the README sends you to the Storybook documentation to find the components you want and how to use them. The Storybook instance is what a design system is really made of, because it is where the props, the variants and the states of every component are documented and exercised, and the `docs/` directory in the repository is where that site is built from.

## A monorepo with turbo, changesets and a strict release path

The repository layout is a Yarn workspace monorepo driven by turbo, and the scripts in the root `package.json` describe the whole lifecycle.

The `workspaces` field lists `packages/*` and `docs`, so the published libraries and the documentation site are built in one place. The turbo tasks are `build`, `clean`, `develop`, `format`, `lint`, `test:unit`, `test:ts` and `watch`, each one a `turbo run` invocation, which means turbo's caching and task graph decide what actually needs rebuilding.

The release path is the part worth studying. There are separate scripts for `prerelease:enter` and `prerelease:exit`, which map to `changeset pre enter` and `changeset pre exit`, plus `release:add` for `changeset add` and `release:version` for `changeset version && yarn install`. The publish script is the strictest one: `release:publish` runs `turbo run build lint test:ts test:unit && changeset publish`.

That single line is the project's quality gate. A release does not happen until every package has built, linted, type-checked and unit-tested. There is no way to publish a broken package because a test failed, unless someone bypasses the script.

The changesets setup also explains the alpha versions. Changesets supports pre-release modes across a monorepo, and the recent 2.3.0-alpha.0 tags across all three packages are the visible result of the `prerelease:enter` flow, where a group of packages moves into a pre-release train together. The `.changeset/` directory at the top level holds the pending changesets.

Around that, the repository has the usual guardrails: `husky` for git hooks, with `prepare` running `husky install`, commitlint with a conventional config, ESLint with the Strapi shared config plus a set of plugins, Prettier with its own ignore file, an `.oxfmtrc.jsonc` and `.oxlintrc.jsonc`, and a `jest.config.js` with `__mocks__/` and `test/` directories.

## Where the design system is the wrong choice

The clearest wrong-tool case is a product that is not a Strapi plugin. This is a component library for one CMS admin panel. Its components are sized, worded and coloured for that context, and a generic React application that adopts it inherits Strapi's design decisions without Strapi's user base to justify them.

The second case is a plugin that must look like the host but is built in a different framework. The provider wraps React children, and the whole component set is React. There is no Vue or Angular path, and given that Strapi's own admin is React, that is not a gap anyone is going to fill.

The third case is a team that wants only the icons. `@strapi/icons` is published separately, which is convenient, but pulling a whole package for one glyph is worth thinking about, since the package is versioned in lockstep with the design system and with the primitives layer.

The fourth is anyone who needs a stable, documented API today. The most recent releases are all `2.3.0-alpha.0` versions, and pre-releases are explicitly a phase where the API can still change. For a plugin shipped to customers, pinning an alpha is a decision with consequences, and the changesets flow means the alpha train is where new work lands first.

The alternative worth naming is a general purpose React component library. The difference in approach is that such a library assumes nothing about where it will be mounted and offers a wide, general surface, while this one assumes a Strapi admin and offers a surface that is coherent with it. The trade is breadth for consistency, and for a plugin the consistency is the whole benefit.

## Maintenance, versioning and the MIT licence

The repository is not archived and the last push was on 2026-10-19. The recent releases, all 2.3.0-alpha.0 across the three packages, are dated 2026-09-24, and the README badges point at npm for the latest published version and at the Strapi Discord for support.

The versioning deserves a note. Three packages share a version number, which is a deliberate choice in a monorepo with changesets: it makes it possible to require one version of the design system, the icons and the primitives without the mismatch problems that arise when components and their icons drift apart. A plugin that depends on `@strapi/design-system` and `@strapi/icons` can rely on them being released together.

The licence is MIT, with the copyright held by Strapi Solutions SAS, and the README points at a `LICENSE` file in the repository. MIT is permissive: you can use, modify and redistribute the components, including in a commercial plugin, as long as the notice travels with the code. For a commercial plugin author that is the outcome you want, and it is a clearly different position from a design system published under a copyleft or source-available licence. This is a description of the terms as published, not legal advice.

There is also a `CHANGELOG.md` in the tree and a `CODE_OF_CONDUCT.md`, and the contributing guidelines live in `CONTRIBUTING.md`. The `hacktoberfest` topic tag suggests the project takes outside contributions, which is normal for a design system and adds a review burden that a closed internal system would not have.

The final practical point is about the Storybook. The README calls it the complete documentation, and that is where you should verify the components before committing, because the provider example shows the integration and the Storybook shows what you can actually build with it.

## Conclusion

Adopt Strapi Design System when you are building plugins for Strapi and want your admin UI to look and behave like the core product instead of like a separate application, since the provider, the theme and the icon set are the whole point. Do not adopt it for a general React product, because it is built for one CMS and will drag React, styled-components and a Strapi-shaped set of components into an unrelated codebase. Before you start, check the version you pin, since the recent releases are 2.3.0 alpha builds, and note that the package is currently marked private in the repository metadata even though the design system and icons are published to npm.

## FAQ

### What is Strapi Design System and who is it for?

It is a TypeScript component library built with styled-components that provides guidelines and tools to make Strapi contributions more cohesive and to build plugins more efficiently. The audience is plugin authors and contributors working inside the Strapi admin panel.

### How do I install Strapi Design System?

Install it with its peer dependencies using `yarn add react react-dom @strapi/design-system @strapi/icons styled-components`, or the npm equivalent `npm i react react-dom @strapi/design-system @strapi/icons styled-components`. React, ReactDOM and styled-components are peers rather than bundled dependencies.

### How do I use the DesignSystemProvider?

Wrap your application with `DesignSystemProvider` imported from `@strapi/design-system`. You can pass a `theme` such as `lightTheme` and a `locale` such as `en-GB`, but both are optional because the library ships default values for them.

### Which packages does the Strapi Design System monorepo publish?

Three, versioned together: `@strapi/design-system`, `@strapi/icons` and `@strapi/ui-primitives`. The recent releases are all 2.3.0-alpha.0, dated 2026-09-24, and the repository uses Yarn workspaces with turbo and changesets to build and release them as a group.

### What licence is Strapi Design System released under?

It is licensed under the MIT License with copyright Strapi Solutions SAS, and the repository carries a `LICENSE` file. The MIT terms allow use, modification and redistribution in commercial plugins provided the notice is retained.

## Sources

- [License: MIT](https://github.com/strapi/design-system/blob/main/LICENSE)
- [Project website](https://design-system.strapi.io)
- [README](https://github.com/strapi/design-system/blob/main/README.md)
- [Releases](https://github.com/strapi/design-system/releases)
- [strapi/design-system on GitHub](https://github.com/strapi/design-system)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/strapi-design-system
