Learn to build a reusable component library for your WordPress plugin. Master design tokens, component extraction, and shared UI systems for React.
Previously in this course, we explored React Component Architecture: Scaling WordPress Plugin UIs to establish a baseline for modular functional components. Now that you have a handle on individual components, this lesson adds the structural discipline required to scale: extracting those components into a shared, private library with consistent design tokens.
As your Knowledge Base plugin grows, you’ll find yourself reimplementing the same "Search Input" or "Status Badge" across different admin pages or Gutenberg blocks. This leads to "drift"—where the padding on a button in your settings page subtly differs from the one in your block editor.
A component library isn't just a folder of files; it’s a source of truth. By centralizing these UI elements, you ensure that a change to a single design token (like a primary color or border-radius) propagates across your entire plugin interface.
Design tokens are the atomic values of your UI: colors, spacing, typography, and shadows. Instead of hardcoding 12px padding, you define a token system.
Create a tokens.js file in your core library directory:
JAVASCRIPT// src/components/tokens.js export const tokens = { spacing: { small: CE9178">'8px', medium: CE9178">'16px', large: CE9178">'24px', }, colors: { primary: CE9178">'#0073aa', surface: CE9178">'#ffffff', border: CE9178">'#dcdcde', }, borderRadius: CE9178">'2px', };
When you build your components, import these tokens instead of using magic numbers. This allows you to re-theme your plugin or align it with future WordPress Admin UI updates by modifying a single file.
Let’s extract a Button component from your existing code into a shared library. We’ll move beyond simple props and use a pattern that ensures strict type safety.
JAVASCRIPT// src/components/Button/Button.jsx import React from CE9178">'react'; import PropTypes from CE9178">'prop-types'; import { tokens } from CE9178">'../tokens'; export const Button = ({ children, variant = CE9178">'primary', onClick }) => { const style = { backgroundColor: variant === CE9178">'primary' ? tokens.colors.primary : CE9178">'transparent', padding: tokens.spacing.medium, borderRadius: tokens.borderRadius, border: CE9178">`1px solid ${tokens.colors.border}`, cursor: CE9178">'pointer', }; return ( <button style={style} onClick={onClick}> {children} </button> ); }; Button.propTypes = { children: PropTypes.node.isRequired, variant: PropTypes.oneOf([CE9178">'primary', CE9178">'secondary']), onClick: PropTypes.func.isRequired, };
By isolating this code, you’ve created a contract. Any developer working on the Knowledge Base plugin now consumes this Button rather than writing raw HTML tags, ensuring visual consistency across your SPA admin screens and Gutenberg blocks.
To maintain a clean boundary, structure your plugin repository to separate the library from the feature-specific logic.
| Directory | Purpose |
|---|---|
src/components/ | Shared UI atoms and molecules (buttons, inputs, cards). |
src/features/ | Business-logic-heavy components (specific to Knowledge Base). |
src/hooks/ | Shared custom hooks for data fetching. |
src/tokens.js | Global design variables. |
tokens.js file for your project.src/components/ directory.@wordpress/components. Always check if a native component exists before building your own. Only build custom components when you need design system consistency that the native components don't provide.Building a component library is the final step in moving from a "hacked together" plugin to a professional software product. By defining design tokens, extracting atomic components, and keeping them decoupled from business logic, you reduce technical debt and accelerate development.
Up next: We will discuss Linting and Code Quality, where we’ll configure PHPCS and ESLint to enforce these architectural standards automatically.
Learn to persist Gutenberg state using Redux middleware. We’ll show you how to sync editor data to localStorage for a seamless, high-performance experience.
Read moreMaster Gutenberg block evolution. Learn to implement block transforms and deprecation handlers to ensure seamless backward compatibility for your plugin.
Component Library Design
Custom Hooks for React