The component library & design system for Skillsoft and Codecademy. ✨
This repository is a monorepo that we manage using NX. That means that we publish several packages to npm from the same codebase, including:
gamut: Our React UI component library
gamut-styles: Utility styles for Gamut components and codecademy apps
gamut-icons: SVG Icons for Gamut components and codecademy apps
variance: TypeScript CSS in JS utility library
styleguide: Styleguide Documentation & storybook development sandbox
- Run
yarnin the root directory - Run
yarn buildto build all of the packages (certain packages likegamut-iconsneed to be built to function in storybook).
- Run
yarn nx storybook styleguideto start the storybook server - Add new stories to
packages/styleguide/src - Stories are written using storybook's Component Story Format and MDX. Check out our comprehensive guide on writing stories here.
Versioning and publishing run on Changesets.
A pull request that changes a versionable package needs a changeset.
Merging to main opens a "Version Packages" pull request that publishes when merged.
See CONTRIBUTING.md for how to add one and which packages release together. Coordinate breaking changes with maintainers first.
Every pull request publishes installable preview packages through pkg.pr.new. A bot comments with the install commands:
yarn add https://pkg.pr.new/@skillsoft/gamut@<pr-number>Previews never reach npm and they expire, so don't commit one to a lockfile on a long-lived branch.
NOTE: Due to the inconsistencies of symlinks in a monorepo, instead of using
yarn link, we recommend using thenpm-link-betterpackage with the--copyflag to copy packages into your local repo'snode_modulesdirectory.
Initial Setup:
- Ensure you have npm-link-better installed:
npm install -g npm-link-better - Ensure you've built the entire
gamutrepo since you last synced:yarn build
Instructions:
For each of your local gamut packages (e.g. gamut), you'll need to do 2 things to get it working in your project:
-
Make sure your package changes have been built into the
gamut/packages/[package]/distfolder.yarn build
or
yarn build:watch(not all packages support this yet)
-
Copy that built
/distfolder to your project'snode_modules/@codecademy/[package]folder.cd myProjectRepo npm-link-better --copy --watch path/to/gamut/packages/[package]NOTE: The
--watchflag will automatically copy your package intonode_moduleseverytime it is built.
Example Workflow
Let's say we are making changes to the gamut package, and our app that uses the gamut package uses yarn start to build, serve, and watch our app for changes.
Let's also assume these two repos are sibling directories inside of a folder called repos
repos
|- gamut
|- my-app
We would run the following commands in 3 separate shells
# Shell 1: Auto-build Gamut changes
cd repos/gamut/packages/gamut
yarn build:watch
# Shell 2: Auto-copy built Gamut changes to my-app.
cd repos/my-app
npm-link-better --copy --watch ../gamut/packages/gamut
# Shell 3: Auto-update app when anything changes.
cd repos/my-app
yarn startThis would allow us to make a change in our gamut package, and see that change automatically reflected in our local app in the browser.
Troubleshooting
-
If you see compilation issues in your project's dev server after running
npm-link-better, you may have to restart your app's dev server. -
If you are seeing compilation issues in a
gamutpackage, you may need to rebuild the whole repository viayarn build
Instructions for using `yarn link` instead (not recommended)
For quicker development cycles, it's possible to run a pre-published version of Gamut in another project. We do that using symlinks (the following instructions assume you have set up and built Gamut):
cd /path/to/gamut/packages/gamutyarn linkcd path/to/other/repoyarn link @skillsoft/gamutyarn install
If your other project uses React, you must link that copy of React in Gamut:
cd path/to/other/repocd node_modules/reactyarn linkcd /path/to/gamut/packages/gamutyarn link reactyarn build
See the docs for more information for why you have to do this.
NX
This monorepo uses NX to cache previous builds locally and in CI.
The config for NX is located at /nx.json, along with project.json files for each package.
Breaking changes must be coordinated with the maintainers ahead of time.
While packages are on 0.x.x, select minor when yarn changeset asks for the bump type.
After 1.0.0, select major.
---
'@skillsoft/gamut': minor
---
Remove the deprecated `primary-blue` and `secondary-red` Button variants.See CONTRIBUTING.md for the complete versioning and prerelease policy.
Because Gamut is a separate repository from its consumers, it can be tricky to coordinate technically breaking changes. If your changes will require changes in any downstream repositories:
- Open a PR in Gamut, which publishes preview packages
- Open PRs in the consuming repositories against those previews
- Update each downstream PR description to link to the Gamut PR, and vice versa
- Once all PRs have been approved, merge your Gamut PR first
- Update your repository PRs to use the published version once the release PR merges
- Merge your repository PRs
This process minimizes the likelihood of accidental breaking changes in Gamut negatively affecting development on our other repositories.
Changelog content comes from the changeset summary, not the PR title or PR description.
Gamut ships an agent-tools plugin with skills, rules, and agents for Claude Code and Cursor. The gamut CLI is included in @skillsoft/gamut, so run it via npx from any project that has the package installed. The plugin content itself lives in the separate, optional @skillsoft/gamut-agent-tools package; the CLI installs it automatically the first time you run gamut plugin install if it isn't already a dependency.
Claude Code
npx gamut plugin install claudeRegisters the plugin at user scope via claude plugin marketplace add, then installs it. Skills become available as slash commands (e.g. /gamut-buttons, /gamut-review). If they don't appear immediately, run /reload-plugins inside Claude Code.
Cursor
npx gamut plugin install cursorCopies skills, rules, and agents into your project's .cursor/ directory.
Add --theme to also write a DESIGN.md into the current directory with theme-specific design tokens and component guidance:
npx gamut plugin install cursor --theme core # Codecademy Core
npx gamut plugin install cursor --theme percipio # Percipio / LX Studio
npx gamut plugin install cursor --theme admin # Admin / PlatformUse --force to overwrite an existing DESIGN.md.
Install only a subset of the plugin content with --scope:
npx gamut plugin install cursor --scope skills # skills only
npx gamut plugin install cursor --scope rules # rules only
npx gamut plugin install cursor --scope agents # agents onlynpx gamut plugin install # re-run to update to the latest version
npx gamut plugin remove cursor # remove the Cursor plugin
npx gamut plugin remove claude # remove the Claude Code plugin
npx gamut plugin list # list installed pluginsRun Claude Code with the plugin loaded for a single session without registering it:
claude --plugin-dir ./node_modules/@skillsoft/gamut-agent-toolsStorybook is built and published automatically when there are merges into the main branch.