ShelfUI: Project Setup
It's been a bit since I announced that I was going to work on a design system.
The surprising non-technical task that I spent considerable time on was giving it a name.
I eventually landed on ShelfUI, as something you could take off the "shelf" and add to your project. Once it had a name, the project started to feel a little more real.
The project structure
For the project, I decided to use a monorepo structure with pnpm. This allows key parts of the system to live as separate packages with their own dependencies, while still being able to work together through pnpm workspaces.
If you haven't used pnpm before, it's worth checking out, especially if you're coming from npm.
The packages workspace contains the core parts of ShelfUI:
ui- the main component librarytokens- design tokens for the systemthemes- theming support
The apps workspace contains projects that consume those packages. For now, that means the ShelfUI Storybook.
/apps
/storybook
/packages
/ui
/tokens
/themes
The workspace configuration keeps this intentionally simple:
packages:
- 'packages/*'
- 'apps/*'
This means new packages or apps can be added to the workspace without needing to update the configuration each time.
The tokens and themes packages are placeholders for now, but I wanted to establish the structure early so they can evolve alongside the component library rather than being added later.
Separating Storybook
For this project, I'm trying something slightly different with Storybook by keeping its configuration and setup separate from the core UI package.
In previous projects, I've kept Storybook inside the component package itself. That approach works, but this time I wanted Storybook to consume the other packages in the system without making those packages responsible for the Storybook setup.
This may turn out to be overkill, but with packages like themes eventually providing functionality that Storybook can consume, keeping the application separate gives me a little more flexibility without adding that configuration and dependency overhead to the core UI package.
The UI package
The ui package will be home to the main component code for the design system.
The initial setup includes React, TypeScript, Vite, and the ShelfUI tokens package, with Vite handling the component build.
To make sure the initial setup was actually working, I created a starter component.
And rather than starting with the traditional button, I decided to start with a Card.
There isn't necessarily a grand reason for that decision. I just wanted to start with something that could exercise a few different aspects of the system without immediately getting into the complexities of something like a button.
Where things stand
So far I have:
- A project name
- An initial monorepo structure
- A GitHub repository
- A working UI package
- A starter Card component
- A public Storybook
This is a pretty small start, but the project now has enough structure to start building the actual system.