Utrecht Design System

April 30, 2026 ยท View on GitHub

Applying design elements from this project is strictly prohibited for organisations that are not part of the Municipality of Utrecht.

This project is part of a community iniative to use NL Design System components for projects that need to adhere to the Utrecht Design System. Teams from the central Municipality of Utrecht, as well as those who are contracted by them to develop websites and apps, are able to collaborate via this project.

Getting started

Include the Design Token CSS variables:

<link rel="stylesheet" type="text/css" href="https://unpkg.com/@utrecht/design-tokens/dist/index.css" />

Combine it with the latest Web Components from the NL Design System community, for example:

<script
  src="https://unpkg.com/@utrecht/web-component-library-stencil/dist/utrecht/utrecht.esm.js"
  type="module"
></script>

Then you can go ahead and see the result:

<utrecht-html-content class="utrecht-theme">
  <h1>Page styled with NL Design System</h1>
</utrecht-html-content>

Avoid automatic upgrades to a new version with breaking changes

For all dependencies, see what the version is you use while developing and update the URL without version to include a version number, and ensure your page keeps working even when new versions are released:

For alpha, beta and rc versions:

https://unpkg.com/@utrecht/design-tokens/dist/index.css

Above should become:

https://unpkg.com/@utrecht/design-tokens@1.0.0-alpha.10/dist/index.css

For stable versions it would become:

https://unpkg.com/@utrecht/design-tokens@^1.0.0/dist/index.css

npm packages

nameversion
@utrecht/component-library-angularNPM version
@utrecht/component-library-cssNPM version
@utrecht/component-library-reactNPM version
@utrecht/component-library-vueNPM version
@utrecht/design-tokensNPM version
@utrecht/iconNPM version
@utrecht/web-component-library-angularNPM version
@utrecht/web-component-library-reactNPM version
@utrecht/web-component-library-stencilNPM version
@utrecht/web-component-library-vueNPM version

In addition to these npm packages, there are separate packages for each components.

These follow the following naming conventions, for example: @utrecht/{component}-css, where you can replace {component} with the name of the component, resulting in @utrecht/button-css.

naming conventionversion
@utrecht/{component}-cssAll components available
@utrecht/{component}-reactHandpicked components available

Contributing

Install prerequisites

You need to have the following tools installed to run Storybook locally:

  • Git
  • Node.js and npm
  • pnpm. After installing Node.js with npm, you can install pnpm by running: npm install -g pnpm

Open a terminal and run the following commands to check:

  • git --version: a relatively recent version should be installed (Git 2.28 or later).
  • node -v: should be at least the version defined in the engines section of package.json.
  • npm -v: should be at least the version defined in the engines section of package.json.
  • pnpm -v: should be at least version 7.

Install code editor

You can use any editor you'd like, but in case you use Visual Studio Code we recommend the following extensions that are useful for this project:

Developing locally

  1. Open Terminal
  2. Select the directory this repository should be cloned into with cd <name-of-directory>
  3. Clone this Git repository
  4. cd utrecht
  5. git checkout main to switch to the main branch, if you previously worked in this repository.
  6. git pull to get to the latest version of the main branch
  7. pnpm install to download and install all the dependencies

Run Docusaurus on your computer

  1. Open Terminal
  2. Ensure your current directory is utrecht
  3. Run pnpm install to ensure the latest and greatest of all dependencies
  4. Run pnpm run docs
  5. The local version of docusaurus will be running on localhost:3000/utrecht
  6. Press Control+C in your terminal to stop Docusaurus

Read the packages/docusaurus/README.md for docusaurus details

Run Storybook on your computer

  1. Open Terminal.
  2. Ensure your current directory is utrecht
  3. Run pnpm install to ensure the latest and greatest of all dependencies
  4. Run pnpm build to build everything that is needed to run Storybook.
  5. Run pnpm run storybook to start Storybook
  6. Your main browser opens automatically with your local storybook.
  7. Press Control+C in your terminal to stop Storybook.

Debugging Storybook

First check the logs in the terminal if any error is displayed, if something doesn't work as expected.

Secondly check the JavaScript logs in your browsers developer tools if there are errors or warnings.

You can run the code checks with pnpm run lint to see if any code errors can be detected.

You can also check the build logs of the design tokens for errors, if you have changed Style Dictionary JSON files, by building those separately:

  1. cd proprietary/design-tokens/
  2. pnpm run build

npm scripts for development web servers

scriptdescription
pnpm run docusaurusStart development docusaurus at localhost:3000 (without access to Storybook, start pnpm run nx-storybook in parallel if you need that)
pnpm run storybookStart HTML/CSS Components Storybook localhost:6006
pnpm run storybook-allStart development Storybook with composition for each framework at localhost:6006
pnpm run serve-docusaurusStart production Docusaurus website (without access to Storybook) at localhost:8080
pnpm run serve-storybook-angularStart production Storybook for Angular Components at localhost:7009
pnpm run serve-storybook-reactStart production Storybook for React Components at localhost:7008
pnpm run serve-storybook-vueStart production Storybook for Vue.js Components at localhost:7007
pnpm run serveStart production Docusaurus website with access to each Storybook at localhost:8080
pnpm run storybook-angularStart development Storybook for Angular Components at localhost:6009
pnpm run storybook-cssStart development Storybook for CSS Components, HTML Components and Web Components at localhost:6006
pnpm run storybook-reactStart development Storybook for React Components at localhost:6008
pnpm run storybook-vueStart development Storybook for Vue.js Components at localhost:6007

The scripts above use nx to automatically run all scripts that are a prerequisite for that particular script. Unfortunately nx often hides the error message when something is wrong. In case nx doesn't work, use follow these simple steps instead to better see the error message in the terminal.

ProjectSteps
Design tokenscd proprietary/design-tokens, npm run build
Storybook for HTML/CSScd packages/storybook, npm run storybook. Depends on design tokens.
Storybook for Reactcd packages/storybook-react, npm run storybook. Depends on design tokens and React components.
Storybook for Vue.jscd packages/storybook-vue, npm run storybook. Depends on design tokens and Vue.js components.
Storybook for Angularcd packages/storybook-angular, npm run storybook. Depends on design tokens and Angular components.
Build Angular componentscd packages/component-library-angular, npm run build
Build Vue.js componentscd packages/component-library-vue, npm run build
Build React componentscd packages/component-library-react, npm run build
Build Web componentscd packages/web-component-library-stencil, npm run build. Depends on icons.
Build Iconscd components/icon, npm run build
Build Docusauruscd packages/docusaurus, npm run build
Build CSS for all componentscd components, npm run build

npm scripts for quality assurance

scriptdescription
pnpm run lint-fixCheck code formatting and automatically fix some types of issues
pnpm run lintCheck code formatting et cetera
pnpm run nx-lint-fixCheck code formatting and automatically fix some types of issues (but faster, using cache)
pnpm run nx-lintCheck code formatting et cetera (but faster, using cache)
pnpm run nx-testRun unit test for each package (but faster, using cache)
pnpm run testRun unit test for each package

npm scripts for the release process

scriptdescription
pnpm run buildBuild each package
pnpm run nx-buildBuild each package (but faster, using cache)
pnpm run publishPublish each package to the npm registry
pnpm run releaseDetermine new version number automatically and update each package.json

MCP server

The Storybook for React components provides an MCP server, when running it locally:

pnpm run storybook-react

The information needed to connect to the MCP server is specified in .mcp.json. You can also try your luck with configuring it using this tool:

pnpm run mcp-add

Once the MCP server is available, instruct the LLM to use it, for example like so:

Use the MCP server local-utrecht-storybook-react for all knowledge of existing design system components.

With the MCP server an LLM can use the information about the components to generate code, for example:

Create a form that asks for a persons name and address, using design system components.

Other scripts

pnpm run build-vercel

Run the build processes, but excluding the following builds that do not currently work on Vercel:

  • The build for storybook-angular crashes randomly.

Code of Conduct

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. Read our Code of Conduct if you haven't already.

License

This project is free and open-source software licensed under the European Union Public License (EUPL) v1.2. The documentation is licensed as Creative Commons Zero 1.0 Universal (CC0-1.0).

For information about proprietary assets in this repository, please carefully read the NOTICE file.

Special thanks

Chromatic supports us with a free starter plan for open source.