A design system is a collection of reusable components, code snippets, assets, and any other detail
that will allow teams to design consistent user experiences.
Learn how to create one »
A design system is comprised of anything that will help teams efficiently develop consistent interfaces that scale. For example:
- A components library, snippets, templates or starter projects
- A style guide
- Design patterns for colors, typography, iconography or animation
- Assets like icons, images or fonts
- Rules for branding voice and tone
- Design usage documentation and guidelines
As you can see, it covers a broad spectrum of concepts. A specification to describe all that can help us by:
- Letting design tools know how to use components, snippets, assets, or tokens
- Having a centralized source of truth for our design system
- Auto-generating documentation and showcase pages
- Tracking and versioning changes to the design system
Hadron is a design tool where code is the source of truth. It can read design systems described in this way to allow users to design with them.
This repo contains all the information needed to create design systems to be used at Hadron. You can create your own, publish it to NPM, and add it to your project's package.json
file without our intervention 1
It also contains all design systems listed there for public usage.
Design systems dialog at hadron.app
All DS from this repo will be displayed there
If you want to list your design system too for the public, fork this repo, add it, and then open a pull request. You can get inspiration from existing ones. But remember, this is a prerelease, and the specs might change.
A design system it's just a folder with a design-system.json
file plus any asset, dependency, or code that it requires. This file have the goal of describing what's available and how to use it.
Your design system will be a dependency of any project using it. Therefore, if it has any external dependencies, you should put them on the package.json
file.
Take the Bulma design system in this repo for example. It has a package.json
with the "bulma" dependency:
{
"name": "@hadronapp/bulma-ds",
"version": "0.1.0",
"dependencies": {
"bulma": "^0.8.2"
}
}
And it only has snippets. But you could build your entire design system without external dependencies, of course. Or have your components together with your design system definitions, which will make it easier to maintain.
This is the entry point for describing your design system. Place it at the root of your project.
Full example:
{
"name": "@hadronapp/bulma-ds",
"displayName": "Bulma",
"homepage": "https://bulma.io",
"description": "Bulma is a free, open source CSS framework based on Flexbox.",
"dependencies": [
"node_modules/bulma/css/bulma.min.css"
],
"components": [
"./components/*.ds.js"
],
"tokens": [
"./tokens/*.json"
]
}
- name { String } - Unique name
- displayName { String } Optional
Readable name. - homepage { String } Optional
- description { String } Optional
- dependencies { Dependency.<> } Optional
Dependencies that you want to include in every document of a project using anything from your design system. - components { String.<> } Optional
Paths to your components definitions. You can use glob patterns, like in the example above. - tokens { String.<> } Optional
Paths to your tokens definitions. You can use glob patterns too.
Component's definitions are js modules. The default
export is the metadata for the component. And the variants
named export must be an array with each variant definition for this component.
Take a look a this simple button component with 2 variants. From Bulma design system.
export default {
displayName: 'Button',
name: 'button',
category: 'Elements',
description: 'The classic button, in different colors, sizes, and states.',
homepage: 'https://bulma.io/documentation/elements/button'
};
export const variants = [
{
displayName: 'Normal',
picture: {
src: './pictures/button/normal.webp'
},
snippet: {
html: `<button class="button">Button</button>`
}
},
{
displayName: 'Primary',
picture: {
src: './pictures/button/primary.webp'
},
snippet: {
html: `<button class="button is-primary">Primary</button>`,
}
}
];
Button component with 2 variants. Extracted from Bulma design system
Tokens can be used to define class names that are styled on your stylesheets, attributes that are styled in some way for certain -or all- elements, CSS variables or even raw values.
They are defined in JSON files and, like with components, you should refer to them in the design-system.json
file.
{
"category": "icons-styles",
"type": "class",
"values": [
{
"value": "fa-xs",
"description": "Icon size: xs"
},
{
"value": "fa-sm",
"description": "Icon size: sm"
},
{
"value": "fa-2x",
"description": "Icon size: 2x"
},
{
"value": "fa-3x",
"description": "Icon size: 3x"
},
{
"value": "fa-rotate-90",
"description": "Rotate icon 90°"
}
]
}
Example extracted from the Font-awesome design system:
Design systems must be NPM packages. You must add that dependency to your project.
At the moment, there are 2 ways to do that:
- Automatically, by pressing install on the public design system list
- Manually, by creating a package.json file and add it to "dependencies" on your project (there is no UI-form to do that more nicely at this moment)
Location from the main document to all dependencies that are needed in every document using the design system.
- It can be a string, which is the path to the dependency.
"node_modules/bootstrap/dist/css/bootstrap.css"
- Or an object
- src { String }
- priority { Number } Optional
If defined, this dependency should load before any other that doesn't have "priority" or it's lower. Your won't normally need this. But on some occasions, dependencies must be loaded in order. - snippets { String.<> } Optional If provided, it means that this dependency only matters for the specified snippets. Otherwise it'll be considered for all snippets.
- type { String } Optional
- Any other attribute Optional
They will only be added when importing with HTML elements. Like script tags or link tags
{
"src": "node_modules/@github/time-elements/dist/time-elements.js",
"priority": 0,
"type": "module",
"snippets": ["html", "vue"],
...
}
- name { String }
- displayName { String } Optional
- homepage { String } Optional
- dependencies { Dependency.<> } Optional
If there is a dependency that isn't global to all components, you can place it on the components that use it themselves.
- displayName { String }
- picture { String | Object }
- src { String }
- width { Number } Optional
- height { Number } Optional
- snippets { Object }
- category { String }
- type { "class" | "attribute" | "css-property" | "css-variable" }
- values { Object.<> }
- value { string }
- description { String }
- cssProperties { String.<> } Optional
Only for "css-property" type. When present, this token is meant to be used for this properties.cssProperties: ["border*", "background"]
- propertyType { String } Optional
Only for "css-property" and "css-variable" types. It can be any string that explains the actual type of the value. Like "color", "background-color", "shadow", "length", ..
For any ideas or discussion about the design systems API, please open an issue in this repo.
We're also on @hadronapp and spectrum.chat/hadron
1 On hadronapp, installing private npm packages is not currently supported. If you need them, please get in touch and tell us what you're planning to do, as we might accelerate its development.