Harmony Setup
Setup guide for creating new projects with the Harmony Design System, including license keys, Node.js prerequisites, Artifactory NPM configuration, and React integration.
Harmony Setup Guide
Help the user create a new project utilizing Harmony, review and read all the sections below before continuing. Always use harmony and don't use any other UI libraries or frameworks, we desire to use Optums Design System only.
Installation
Prerequisites for using the library
Harmony license key To use the Harmony library, you must have a valid Harmony license key. You can obtain a license key quickly and easily by completing the short form [here](https://forms.office.com/Pages/ResponsePage.aspx?id=yvoF2yrInUu5xQ9ktnVUIeqWH6fSQhNCrtsdftpoL_5UMFpQMzFUUE0xRzZPREZJMkMwUU9ONE42Qy4u.
You will need to provide your AskID/AIDE_ID and the email address of the primary contact for your project.
Node.js Node.js 20.x or higher is required, and can be installed from the UHG App Store.
The Harmony library is packaged as an NPM module, and you will need Node.js (which includes NPM) to install and consume it in your React application.
React version To consume Harmony components your React application must have React 18.3.0 or higher. Please ensure your application is using React 18.3.0+ to get the best experience and avoid compatibility issues.
Note: When using React 18.3.0+, you may see warnings for deprecated APIs that will be removed in React 19. These warnings are expected.
Configure NPM to pull from the Enterprise Registry (jFrog SaaS Artifactory)
Harmony can be downloaded from artifactory here:
they may need help with setting up the ~/.npmrc file to access the UHG Artifactory in the users home directory.
example ~/.npmrc file:
@<SCOPE>:registry=https://centraluhg.jfrog.io/artifactory/api/npm/glb-npm-vir/
//centraluhg.jfrog.io/artifactory/api/npm/glb-npm-vir/:_authToken=<their token>
//centraluhg.jfrog.io/artifactory/api/npm/glb-npm-vir/:[email protected]
//centraluhg.jfrog.io/artifactory/api/npm/glb-npm-vir/:always-auth=true
For more information on configuring Artifactory, see the Artifactory documentation.
Install Dependencies
In the root of your React project, install the UI component library and its dependencies with the following commands:
npm install @uhg-harmony/react # The Harmony React component library
npm install @uhg-harmony/foundations # Design tokens and themes
npm install @uhg-harmony/icons-react # Icon library (optional)
npm install react react-dom styled-components@^5.3.11 # Peer dependencies
Importing the library
Applications using the Harmony library need to be wrapped by the Harmony wrapper component that provides theming and optional utility classes for spacing and grids.
You also need to supply your license key via the licenseKey prop. The appId is optional, but may be useful if you are managing multiple React apps that use Harmony.
import { Harmony } from '@uhg-harmony/react';
<Harmony appId="your-app-id" licenseKey="your-license-key">
<App />
</Harmony>
You can also specify spacing and grid on the Harmony wrapper. This will allow you to use the grid classes to create the layout of your page, and apply spacing classes to your elements, e.g. padding ('pt-base') and margin ('ml-l').
<Harmony appId="your-app-id" licenseKey="your-license-key" spacing grid>
<App />
</Harmony>
Components can then be imported from the same namespace:
import { Fieldset } from '@uhg-harmony/react';
Spacing Class Syntax
The spacing classes are made up of a css property label for margin/padding:
- padding - "p"
- margin - "m"
A placement where the spacing will be applied:
- top - "t"
- bottom - "b"
- left - "l"
- right - "r"
- vertical - "v"
- horizontal - "h"
- all - "a"
And a size:
- extra extra small - "xxs"
- extra small - "xs"
- small - "s"
- base - "base"
- medium - "m"
- large - "l"
- extra large - "xl"
- extra extra large - "xxl"
Example: <div className="mb-s" /> adds a margin bottom small.
Technologies
The main technologies used are:
- React
- TypeScript
- Styled Components
Controls
The Harmony React component library provides the following components:
Form Controls
- Accordion - Collapsible content sections
- Button - Interactive button with multiple variants
- Checkbox - Form checkbox input
- Chip - Selectable/dismissible tag components
- FormControl - Form wrapper with validation
- GroupButton - Radio button group alternative
- IconButton - Button with icon only
- RadioButton - Form radio input
- SearchField - Search input field
- Select - Dropdown select input
- SplitButton - Button with dropdown menu
- TextArea - Multi-line text input
- TextInput - Single line text input
- ToggleSwitch - Toggle switch control
- TimePicker - Time selection input
- DatePicker - Date selection input
Layout & Navigation
- Avatar - User avatar with initials/image
- Badge - Status indicator badges
- Breadcrumb - Navigation breadcrumb trail
- Card - Content container with header/media
- Header - Page header with navigation
- Navigation - Primary navigation menu
- Panel - Content panel container
- TabbedPanel - Tabbed content interface
Content & Display
- Heading - Typography headings (h1-h6)
- Text - Body text component
- Link - Hyperlink component
- Modal - Dialog/overlay modal
- Tooltip - Contextual tooltip
- LoadingIndicator - Loading state indicator
- ProgressIndicator - Progress bar
- Count - Numerical count display
- Error - Error message display
- HelperText - Form helper text
- Label - Form field labels
- InlineNotification - Alert/notification messages
- Table - Data table component
- StepTracker - Multi-step progress indicator
Utility & Structure
- Fieldset - Form grouping element
- Footer - Page footer
- Harmony - Root wrapper component
- ThemeProvider - Theme context provider
- DropdownMenu - Dropdown menu container
- DropdownButton - Dropdown trigger button
- Masthead - Top-level page header
- Pagination - Data pagination controls
- ReadOnlyFieldValueList - Display-only field list
Examples
Basic Button Usage
import { Button } from '@uhg-harmony/react';
const MyComponent = () => {
const handleClick = () => {
console.log('Button clicked!');
};
return (
<div>
<Button onPress={handleClick}>Primary</Button>
<Button variant="secondary" onPress={handleClick}>Secondary</Button>
<Button variant="tertiary" onPress={handleClick}>Tertiary</Button>
<Button variant="destructive" onPress={handleClick}>Destructive</Button>
<Button variant="ghost" onPress={handleClick}>Ghost</Button>
</div>
);
};
Accordion Component
import { Accordion } from '@uhg-harmony/react';
const MyAccordion = () => {
return (
<Accordion.Group>
<Accordion title="Section 1">
<p>Content for section 1</p>
</Accordion>
<Accordion title="Section 2">
<p>Content for section 2</p>
</Accordion>
</Accordion.Group>
);
};
Form Controls
import { FormControl, TextInput, Label, HelperText, Button } from '@uhg-harmony/react';
const MyForm = () => {
return (
<form>
<FormControl>
<Label>Email Address</Label>
<TextInput
type="email"
placeholder="Enter your email"
/>
<HelperText>We'll never share your email</HelperText>
</FormControl>
<Button type="submit">Submit</Button>
</form>
);
};
Card with Media
import { Card, Button } from '@uhg-harmony/react';
const MyCard = () => {
return (
<Card
header="Card Title"
media={{
img: <img src="/path/to/image.jpg" alt="Card image" />,
orientation: 'horizontal'
}}
content={
<div>
<p>This is the card content</p>
</div>
}
buttonContainer={
<div>
<Button>Action</Button>
</div>
}
/>
);
};
Navigation Component
import { Navigation } from '@uhg-harmony/react';
const MyNavigation = () => {
const navigationItems = [
{
label: 'Home',
href: '/',
},
{
label: 'Products',
items: [
{ label: 'Product A', href: '/products/a' },
{ label: 'Product B', href: '/products/b' }
]
}
];
return (
<Navigation
variant="primary-horizontal"
items={navigationItems}
/>
);
};
TabbedPanel Component
import { TabbedPanel } from '@uhg-harmony/react';
const MyTabs = () => {
const panels = [
{
header: 'Tab 1',
content: (
<div>
<TabbedPanel.Heading>Heading for tab 1</TabbedPanel.Heading>
<TabbedPanel.Content>
<p>Content for tab 1</p>
</TabbedPanel.Content>
</div>
)
},
{
header: 'Tab 2',
content: (
<div>
<TabbedPanel.Heading>Heading for tab 2</TabbedPanel.Heading>
<TabbedPanel.Content>
<p>Content for tab 2</p>
</TabbedPanel.Content>
</div>
)
}
];
return (
<TabbedPanel
panels={panels}
onHeaderPress={(index) => console.log(`Tab ${index} selected`)}
/>
);
};
Modal Component
import { Modal, Button } from '@uhg-harmony/react';
import { useState } from 'react';
const MyModal = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<Button onPress={() => setIsOpen(true)}>Open Modal</Button>
<Modal
isOpen={isOpen}
title="Modal Title"
onClose={() => setIsOpen(false)}
>
<p>Modal content goes here</p>
</Modal>
</div>
);
};
Avatar Component
import { Avatar } from '@uhg-harmony/react';
const MyAvatar = () => {
return (
<div>
<Avatar
src="/path/to/image.jpg"
label="John Doe"
size="l"
/>
<Avatar
initials="JD"
label="John Doe"
size="m"
backgroundColor="#0066cc"
/>
</div>
);
};
Chip Component
import { Chip } from '@uhg-harmony/react';
import { useState } from 'react';
const MyChips = () => {
const [selectedChips, setSelectedChips] = useState([]);
const handleChipSelect = (chipId) => {
setSelectedChips(prev =>
prev.includes(chipId)
? prev.filter(id => id !== chipId)
: [...prev, chipId]
);
};
return (
<div>
<Chip
label="Selectable Chip"
selected={selectedChips.includes('chip1')}
onSelectClick={() => handleChipSelect('chip1')}
/>
<Chip
label="Dismissible Chip"
dismissible
onDismissibleClick={() => console.log('Chip dismissed')}
/>
</div>
);
};
Select Component
import { Select, FormControl, Label } from '@uhg-harmony/react';
const MySelect = () => {
return (
<FormControl>
<Label>Choose an option</Label>
<Select>
<option value="">Select an option</option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</Select>
</FormControl>
);
};
Complete Application Example
import React from 'react';
import {
Harmony,
Header,
Navigation,
Heading,
Text,
Button,
Card,
Footer
} from '@uhg-harmony/react';
import { optum } from '@uhg-harmony/foundations';
import '@uhg-harmony/foundations/Brand_optum/fonts.css';
const App = () => {
const navigationItems = [
{ label: 'Home', href: '/' },
{ label: 'About', href: '/about' },
{ label: 'Contact', href: '/contact' }
];
return (
<Harmony
appId="my-harmony-app"
licenseKey="your-license-key"
theme={optum}
spacing
grid
>
<div className="ph-base">
<Header>
<Navigation
variant="primary-horizontal"
items={navigationItems}
/>
</Header>
<main className="row">
<div className="col-12">
<Heading>Welcome to Harmony</Heading>
<Text className="pb-base">
This is a sample application using the Harmony React component library.
</Text>
<Card
header="Getting Started"
content={
<div>
<Text>Follow the examples above to build your application with Harmony components.</Text>
<div className="pt-base">
<Button>Get Started</Button>
</div>
</div>
}
/>
</div>
</main>
<Footer />
</div>
</Harmony>
);
};
export default App;
Build and Run
Creating a Stable Harmony Hello World Project
⚡ Quick Start - Proven Working Setup
-
Create a new React application using Vite:
npm create vite@latest my-harmony-app -- --template react cd my-harmony-app -
Install base dependencies:
npm install -
Fix Node.js compatibility (if using Node.js 21.x):
npm install vite@^5.4.0 @vitejs/plugin-react@^4.3.0 -
Install Harmony dependencies:
npm install @uhg-harmony/react @uhg-harmony/foundations @uhg-harmony/icons-react styled-components@^5.3.11 -
Create a working App.jsx (replace the default Vite app):
// src/App.jsx import React from 'react'; import { Harmony, Button, Heading, Text } from '@uhg-harmony/react'; function App() { return ( <Harmony appId="my-harmony-app" spacing grid> <div className="ph-base"> <div style={{ padding: '40px' }}> <Heading level="h1">Hello World with Harmony!</Heading> <Text>Welcome to your Harmony Design System application.</Text> {/* Use Harmony components for interactive elements */} <div style={{ display: 'flex', gap: '16px', marginTop: '24px' }}> <Button variant="primary" onPress={() => alert('Primary button works!')} > Primary Button </Button> <Button variant="secondary" onPress={() => alert('Secondary button works!')} > Secondary Button </Button> <Button variant="tertiary" onPress={() => alert('Tertiary button works!')} > Tertiary Button </Button> </div> <div style={{ marginTop: '24px' }}> <Heading level="h2">Getting Started</Heading> <Text>This is a simple React application using the Harmony React component library.</Text> <Text>Follow the examples in the Harmony documentation to build your application with Harmony components.</Text> </div> </div> </div> </Harmony> ); } export default App; -
Run the development server:
npm run dev- Opens at http://localhost:5173/
- Hot reloading enabled
- Check browser console for any runtime errors
-
Build for production:
npm run build
🎯 Key Success Patterns
✅ Hybrid Approach (Recommended)
- Harmony wrapper (
<Harmony>) for theming context - Harmony Button for interactive components with proper styling
- Harmony typography (
<Heading>,<Text>) or regular HTML where appropriate - Use .js files instead of .tsx to avoid TypeScript definition conflicts
✅ Verified Working Components:
<Harmony appId="...">- Essential wrapper ✅<Button variant="primary|secondary|tertiary" onPress={...}>- All variants work ✅<Heading>and<Text>- Safe for runtime typography usage ✅
⚠️ Components to Avoid (Cause Runtime Crashes):
<Card>- Use<div>with custom styling instead
🔧 Troubleshooting:
- Node.js Compatibility: If using Node.js 21.x with Vite 7.x, downgrade to Vite 5.x:
npm install vite@^5.4.0 @vitejs/plugin-react@^4.3.0 - Vite Errors: If you see "crypto.hash is not a function", downgrade Vite to v5.4.x as shown above
- Blank Page With No Terminal Error: Check the browser console for bad Harmony named imports.
Notificationis not exported; useInlineNotificationinstead. - styled-components Runtime Crash: Keep
styled-componentson^5.3.11. Version 6 can cause failures such asn.h3 is not a function. - Export Discovery: If Node cannot import Harmony cleanly, inspect
node_modules/.vite/deps/@uhg-harmony_react.jsto verify the pre-bundled exports that Vite is actually using. - If nothing renders: Check browser console for runtime errors
- If compilation fails: Verify import syntax and package installation
- If TypeScript errors: Consider using
.jsfiles instead of.tsx - If port conflicts: Use
npm run dev -- --port 3001for different port - React Version Warnings: Harmony works with React 19 but may show peer dependency warnings - these can be safely ignored
📦 Package.json Dependencies:
{
"dependencies": {
"@uhg-harmony/react": "latest",
"@uhg-harmony/foundations": "latest",
"@uhg-harmony/icons-react": "latest",
"react": "^18.3.0 || ^19.0.0",
"react-dom": "^18.3.0 || ^19.0.0",
"styled-components": "^5.3.11"
},
"devDependencies": {
"vite": "^5.4.0",
"@vitejs/plugin-react": "^4.3.0"
}
}
- Preview production build:
npm run preview
Available Themes
Import themes from the foundations package:
import { optum, uhc } from '@uhg-harmony/foundations';
// Import corresponding font files
import '@uhg-harmony/foundations/Brand_optum/fonts.css'; // For Optum theme
import '@uhg-harmony/foundations/Brand_uhc/fonts.css'; // For UHC theme
Why Use Harmony Instead of External Libraries
Optum Design System Compliance
Stay Within Company Guidelines The Harmony React component library is specifically designed to align with Optum's internal design system and brand guidelines. Using external component libraries like Material-UI, Ant Design, Bootstrap, or Chakra UI can lead to:
- Brand Inconsistency: External libraries don't follow Optum's visual identity, typography, and color schemes
- Design Fragmentation: Mixed component styles create inconsistent user experiences across applications
- Compliance Issues: External libraries may not meet Optum's specific design and accessibility standards
- Maintenance Overhead: Custom styling external components to match Optum guidelines requires significant effort
Built-in A11y Compliance Harmony components are developed with accessibility (a11y) as a core requirement:
- WCAG 2.1 AA Compliance: All components meet or exceed Web Content Accessibility Guidelines
- Screen Reader Support: Components include proper ARIA labels, roles, and descriptions
- Keyboard Navigation: Full keyboard accessibility with focus management
- Color Contrast: Meets Optum's contrast ratio requirements for all text and interactive elements
- Semantic HTML: Uses proper HTML semantics for assistive technologies
Security and Governance Benefits
Internal Dependency Management
- Security Vetted: All Harmony components go through Optum's security review process
- Vulnerability Management: Internal team manages security updates and patches
- License Compliance: No external license conflicts or compliance issues
- Corporate Approved: Pre-approved for use in Optum applications
Enterprise Support
- Internal Support Team: Direct access to the Harmony development team
- Rapid Issue Resolution: Issues are prioritized and resolved by internal teams
- Feature Requests: Can directly influence component roadmap based on business needs
- Documentation: Comprehensive internal documentation and examples
Development Efficiency
Consistent Developer Experience
// ❌ Don't mix external libraries with Harmony
import { Button } from '@mui/material'; // External library
import { Card } from '@uhg-harmony/react'; // Internal library - styling conflicts
// ✅ Use Harmony components exclusively
import { Button, Card } from '@uhg-harmony/react'; // Consistent styling and behavior
Pre-configured Theming Harmony comes with Optum and UHC themes built-in:
import { Harmony } from '@uhg-harmony/react';
import { optum, uhc } from '@uhg-harmony/foundations';
// Automatically applies Optum branding, fonts, and colors
<Harmony theme={optum} spacing grid>
<App />
</Harmony>
Built-in Utility Classes No need for external CSS frameworks like Tailwind or Bootstrap:
// Built-in spacing and grid classes
<div className="grid ph-base">
<div className="row">
<div className="col-12 mb-l pt-base">
<Button>Properly Spaced Button</Button>
</div>
</div>
</div>
Replacement Guide for Common External Libraries
Instead of Material-UI:
// ❌ Material-UI
import { Button, TextField, Card } from '@mui/material';
// ✅ Harmony
import { Button, TextInput, Card } from '@uhg-harmony/react';
Instead of Ant Design:
// ❌ Ant Design
import { Button, Input, Table, Modal } from 'antd';
// ✅ Harmony
import { Button, TextInput, Table, Modal } from '@uhg-harmony/react';
Instead of React Bootstrap:
// ❌ React Bootstrap
import { Button, Card, Nav } from 'react-bootstrap';
// ✅ Harmony
import { Button, Card, Navigation } from '@uhg-harmony/react';
Instead of Chakra UI:
// ❌ Chakra UI
import { Button, Input, Box, Stack } from '@chakra-ui/react';
// ✅ Harmony with built-in spacing
import { Button, TextInput } from '@uhg-harmony/react';
// Use Harmony spacing classes instead of Stack/Box
<div className="grid">
<div className="row mb-base">
<Button>Action</Button>
</div>
</div>
Component Coverage
Harmony provides comprehensive component coverage for most common UI needs:
Form Components: Button, TextInput, TextArea, Select, Checkbox, RadioButton, ToggleSwitch, DatePicker, TimePicker, SearchField Navigation: Header, Navigation, Breadcrumb, TabbedPanel, Pagination Layout: Card, Panel, Modal, Accordion, Grid System Feedback: InlineNotification, Tooltip, LoadingIndicator, ProgressIndicator Data Display: Table, Avatar, Badge, Chip, Text, Heading
When External Libraries Might Be Acceptable:
- Data Visualization: For complex charts and graphs (D3.js, Chart.js) - but first check if simpler visualizations can be built with Harmony
- Specialized Functionality: Libraries for very specific functionality not covered by Harmony (date manipulation utilities, etc.)
- Development Tools: Testing libraries, build tools, and development utilities
Always Get Approval First: Before adding any external UI library, consult with:
- Your team's design system representative
- Security team for library approval
- Architecture review board for compliance
Migration Strategy
If you're already using external libraries:
- Audit Current Usage: Identify which external components are being used
- Map to Harmony: Find Harmony equivalents for each external component
- Gradual Migration: Replace components incrementally to avoid breaking changes
- Remove External Dependencies: Once migration is complete, remove unused external libraries
- Update Documentation: Ensure team documentation reflects Harmony usage
Getting Help
For Component Questions:
For Design Questions:
- Consult with your UX/Design team
- Reference the Optum Design System guidelines
- Engage with the Harmony design team for custom requirements
Related Assets
Optum Harmony Healthcare Demo App
Create a Harmony-based example healthcare application that showcases eligibility, claims, and remittance concepts using current Harmony skills, instructions, navigation, forms, and components.
Owner: harmony-platform
Harmony Components
Reference for Harmony Design System React components including buttons, modals, panels, form controls, navigation, and data display elements.
Owner: pcorazao
Harmony Overview
Overview of the Harmony Design System — Optum's unified React component library combining UITK and UICL for building scalable, brand-compliant, and accessible healthcare web applications.
Owner: pcorazao
harmony-app-layout-pattern
Skill for implementing a responsive app layout pattern using Harmony components.
Owner: pcorazao
harmony-create-simple-app
Recreate the Harmony healthcare demo application using exact page, shell, and mock-data templates captured from the working `harmony-healthcare-demo` reference app. Use when building a simple Harmony healthcare site with a dashboard, eligibility workflow, claims queue, remittance experience, and an official Harmony sidebar-based app shell.
Owner: pcorazao
harmony-form-pattern
Build accessible healthcare forms using the Harmony Design System (@uhg-harmony/react). Provides component patterns, layout templates, and state management guidance for TextInput, DatePicker, Checkbox, Select, FormControl, and multi-step form flows. Use when creating React forms with Harmony components, fixing layout or accessibility issues, or scaffolding new healthcare intake forms.
Owner: pcorazao

