Integrating the EBRAINS Design System
This guide is for teams building applications outside the EBRAINS UI Ecosystem monorepo. If your app is a standalone React, Angular, Vue, or vanilla project and you want to adopt the EBRAINS design system, follow these steps.
By the end, your app will have access to the component library, design tokens, utility classes, and SVG brand assets — all installed from npm.
What’s Available
The design system is published to the @ebrains organization on npm:
| Package | What it provides |
|---|---|
@ebrains/components | 44+ Stencil web components (framework-agnostic) |
@ebrains/assets | CSS framework, design tokens, fonts |
@ebrains/svgs | SVG logos, icons, and brand assets as inline strings |
@ebrains/react | React wrappers for all components |
@ebrains/angular | Angular wrappers for all components |
@ebrains/vue | Vue wrappers for all components |
You only install what you need. Most apps will use @ebrains/components (or a framework wrapper) plus @ebrains/assets.
Step 1: Install Packages
React App
Angular App
Vue App
Plain HTML / Vanilla JS
Step 2: Load Styles
You have two options for styling: the pre-built CSS file or a custom Tailwind build.
Option A: Pre-built CSS (simplest)
Import the full framework in your entry point:
Or via CDN in your HTML:
<link rel="stylesheet" href="https://unpkg.com/@ebrains/assets@latest/styles/output.css">This gives you all utility classes (bg-*, text-*, f-heading-*, p-*, flex, grid-layout, etc.), design tokens as CSS variables, and font-face declarations. See CSS Framework for the full reference.
Option B: Tailwind Build (tree-shaken)
If you want only the classes your app actually uses, set up a custom Tailwind build. See Tailwind Migration for the full setup guide.
Option C: Variables Only (lightweight)
If you just need CSS variables and fonts (8KB):
Step 3: Use Components
In React
Import components from @ebrains/react — they auto-register the underlying web components:
import { EdsButton, EdsAccordion, EdsAlert, EdsTable } from '@ebrains/react'
function App() {
return (
<div className="container mx-auto p-32">
<EdsButton label="Click me" intent="brand" />
<EdsAccordion title="Details" variant="inverse" icon="information">
<p>Accordion content here.</p>
</EdsAccordion>
<EdsAlert message="Success!" intent="success" icon="checkmark-filled" />
<EdsTable
tableData={JSON.stringify([
{ Name: 'Alice', Role: 'Engineer' },
{ Name: 'Bob', Role: 'Designer' },
])}
theme="brand"
sortingEnabled={true}
/>
</div>
)
}In Angular
Import standalone components from @ebrains/angular:
import { Component } from '@angular/core';
import { EdsButton, EdsAlert, EdsAccordion } from '@ebrains/angular';
@Component({
standalone: true,
imports: [EdsButton, EdsAlert, EdsAccordion],
template: `
<eds-button label="Click me" intent="brand"></eds-button>
<eds-accordion title="Details" variant="inverse" icon="information">
<p>Content here.</p>
</eds-accordion>
<eds-alert message="Done!" intent="success" icon="checkmark-filled"></eds-alert>
`
})
export class AppComponent {}In Vue
Import components from @ebrains/vue:
<template>
<EdsButton label="Click me" intent="brand" />
<EdsAccordion title="Details" variant="inverse" icon="information">
<p>Content here.</p>
</EdsAccordion>
<EdsAlert message="Done!" intent="success" icon="checkmark-filled" />
</template>
<script setup>
import { EdsButton, EdsAccordion, EdsAlert } from '@ebrains/vue'
</script>In Plain HTML
Load the Stencil loader and use native custom elements:
<script type="module">
import { defineCustomElements } from '@ebrains/components/loader';
defineCustomElements(window);
</script>
<eds-button label="Click me" intent="brand"></eds-button>
<eds-accordion title="Details" variant="inverse" icon="information">
<p>Content here.</p>
</eds-accordion>
<eds-alert message="Done!" intent="success" icon="checkmark-filled"></eds-alert>See Plain HTML Setup for the full Vite configuration.
Step 4: Use SVG Assets
The @ebrains/svgs package exports all brand SVGs as inline strings:
Available exports:
| Export | Description |
|---|---|
logoPositive | EBRAINS logo for light backgrounds |
logoNegative | EBRAINS logo for dark backgrounds |
euSvg | EU flag |
gitlabColor | GitLab logo (color) |
gitlabBlack | GitLab logo (mono) |
twitter | X/Twitter icon |
linkedin | LinkedIn icon |
facebook | Facebook icon |
youtube | YouTube icon |
mastodon | Mastodon icon |
bluesky | Bluesky icon |
In React
import { logoNegative } from '@ebrains/svgs'
function Logo() {
return (
<div
className="bg-strongest p-24 rounded-lg"
dangerouslySetInnerHTML={{ __html: logoNegative }}
/>
)
}In Vue
<template>
<div class="bg-strongest p-24 rounded-lg" v-html="logoNegative" />
</template>
<script setup>
import { logoNegative } from '@ebrains/svgs'
</script>In Angular
import { Component } from '@angular/core';
@Component({
template: '<div class="bg-strongest p-24 rounded-lg" [innerHTML]="logo"></div>'
})
export class LogoComponent {
logo = require('@ebrains/svgs').logoNegative;
}In Plain HTML
<div id="logo" class="bg-strongest p-24 rounded-lg"></div>
<script type="module">
import { logoNegative } from '@ebrains/svgs';
document.getElementById('logo').innerHTML = logoNegative;
</script>Step 5: Style with Utility Classes
Once the CSS framework is loaded, use EBRAINS utility classes throughout your templates:
<!-- Layout -->
<div class="container mx-auto p-32">
<div class="flex flex-col gap-16 md:flex-row md:gap-32">
...
</div>
</div>
<!-- Typography -->
<h1 class="f-heading-01">Page Title</h1>
<p class="f-body-02">Body text content.</p>
<span class="f-ui-02">Interface label</span>
<!-- Colors -->
<div class="bg-strongest text-inverse p-16 rounded-lg">
Dark section with light text
</div>
<div class="bg-accent text-default p-16 rounded-lg">
Brand green section
</div>
<!-- Spacing -->
<div class="p-24 mb-32 gap-12">Padded with margin and gap</div>
<!-- Shadows -->
<div class="shadow-md rounded-lg p-16">Elevated card</div>See CSS Framework for the full class reference, and Tokens for the underlying design token values.
Quick Reference
Component Naming
| Context | Convention | Example |
|---|---|---|
| React | PascalCase | <EdsButton> |
| Angular | kebab-case (in template) | <eds-button> |
| Vue | PascalCase or kebab-case | <EdsButton> or <eds-button> |
| Plain HTML | kebab-case | <eds-button> |
Prop Naming
| Context | Convention | Example |
|---|---|---|
| React | camelCase | pressableLabel="..." |
| Angular | camelCase (property binding) | [pressableLabel]="..." |
| Vue | camelCase | :pressable-label="..." |
| Plain HTML | kebab-case | pressable-label="..." |
Passing Complex Data
Objects and arrays must be passed as JSON strings in HTML attributes:
<!-- Plain HTML / Angular template -->
<eds-table
table-data='[{"Name":"Alice"},{"Name":"Bob"}]'
config='{"Name":{"format":"bold"}}'
></eds-table>
<!-- React (pass as JS objects) -->
<EdsTable
tableData={JSON.stringify(data)}
config={JSON.stringify(config)}
/>Event Handling
| Context | How |
|---|---|
| React | onEdsalert={handler} or onClick={handler} |
| Angular | (edsalert)="handler($event)" |
| Vue | @edsalert="handler" |
| Plain HTML | element.addEventListener('edsalert', handler) |
Minimal Example: New React App
Create a fresh React app and integrate the design system in minutes:
Then in src/main.tsx:
And in src/App.tsx:
import { EdsButton, EdsAlert } from '@ebrains/react'
import { logoPositive } from '@ebrains/svgs'
function App() {
return (
<div className="container mx-auto p-32">
<div dangerouslySetInnerHTML={{ __html: logoPositive }} />
<h1 className="f-heading-02 mb-16">My EBRAINS App</h1>
<EdsAlert message="Welcome!" intent="success" icon="checkmark-filled" />
<EdsButton label="Get Started" intent="brand" />
</div>
)
}That’s it — components, styles, and SVGs working in a standalone project with zero monorepo dependencies.
Reference Examples
The UI Ecosystem monorepo includes sandbox apps that demonstrate the full integration for each framework:
| App | Framework | What it tests |
|---|---|---|
apps/sandbox/test-react | React + Vite | React wrappers + Tailwind factory build |
apps/sandbox/test-web | Plain HTML + Vite | Stencil loader + native custom elements |
apps/sandbox/test-angular | Angular | Angular standalone wrappers |
apps/sandbox/test-react-native | React Native | Design tokens via StyleSheet (no web components) |