Introduction

Design systems standardize component design and code to help teams efficiently create, maintain, and update products. athenahealth has 3 design systems, each for a different use:

  • Spark is a React-based design system developed by the Patient Experience team for patient-facing apps.
  • Foundation is an iOS- and Android-based design system developed by the athenaOne Mobile team for native mobile apps.
  • Forge is a React-based design system developed by the Forge team for internal and provider-facing apps. It’s the official design system of athenahealth.

This guide helps developers who are new to Forge get set up with the tools and knowledge they need to get started with Forge. If you’ve used Forge before but need to configure it again, this guide helps with that, too. By the end, you’ll have the environment and packages you need, as well as a basic understanding of how Forge works, thanks to the creation of a simple demo app.

If you’re new to athenahealth, learn about Nimbus first. This explains athenahealth’s development environment, including how Forge fits in.

Key takeaways

  • To begin using Forge, you should be familiar with React and CSS, and you’ll have to install and access a few key utilities.
  • This guide walks you through these steps, then gets you started with a simple standalone app.
  • If you’d like to go deeper with Forge, there’s information about that, too.
  • At the end, we’ve included helpful links to our recommended resources and utilities.

About Forge

The Forge design system consists of several elements:

  • The React-based code package
  • The Figma design library
  • Typography, color, and spacing guidelines
  • 200+ custom icons
  • 50+ UI components to use as building blocks to construct apps and products
  • Rules and standards for using all these elements
About Forge

These elements work together to help developers and designers work efficiently, resulting in smoother releases, a better user experience, and easier product updates as code and design decisions change over time.

The team that builds and maintains Forge is made up of ~10 product owners, developers, and designers based mostly in Watertown. If you have any questions, comments, or just want to say hi, connect with us on Teams.

Who should use Forge

If you and your team work on new React-based web products for providers or internal users, you must use Forge.

If you’re working on existing products that are gradually transitioning to Forge, you can use it in discrete parts of your app. Check with another developer on your team for the best way to do this.

If your entire app is based on an older design system like Classic or Streamlined, your subdivision’s UX leadership may require that any new or updated features are built using Forge. Check with your team for guidance.

What you need to use Forge

Code knowledge

Forge is built in React and styled by CSS. You don’t need to be a React or CSS pro to get started with Forge, but React and CSS experience are both important to use Forge successfully. As you get more familiar with Forge, you may also want to explore BEM and Sass.

For a list of recommended courses, refreshers, and references, see Resources.

Local coding tools

Node.js is our JavaScript runtime platform. For easy installation and updates, install a Node version manager (NVM) like nvm or n; Windows users should install this one. An NVM makes it easy to switch between Node versions.

Most athenahealth teams use Node package manager (npm) to manage shared packages and test code, and your nvm download includes npm. Once you’ve installed nvm, enter these commands in your command line interface (CLI) to confirm that you have npm:

node -v
npm -v

Other package managers like Yarn or PNPM also work with Forge. Some teams may have reasons they don’t use npm, so check with another developer on your team to determine the best option.

Access to internal tools

You’ll need access to Bitbucket. athenahealth developers should have this by default. If you’re not a developer, request the “bitbucket_other” permission via IdentityIQ.

You’ll also need access to Artifactory, our local npm package repository. If you can’t see content on the Artifactory web page, request permissions via the CICD Teams channel.

The latest version of Forge

We release Forge updates regularly. To make sure you’re using the latest version, check your app’s package.json file for the version number. It should match the number in the top right corner of the Forge guide. If it doesn’t, enter this in your command line:

npm install --save-exact @athena/forge@latest

Creating your first Forge app

To start learning your way around Forge, you can create a simple “Hello, World!” app that uses Forge components. You can use this app to play around with React and Forge, but it’s just a demo and isn’t eligible for production. If you’re an athenahealth developer, follow the Nimbus-specific instructions for Create React App when you’re ready to get started with sprint work.

We strongly recommend using TypeScript. It reduces production bugs by approximately 15%, is tightly integrated with vscode (our recommended text editor), and is recommended by the Athena Reviewed Tech Board. To learn more about TypeScript, see Resources.

We also strongly recommend using the Block Element Modifier (BEM) naming convention to name your CSS classes. If you initialized your repository using the Nimbus-specific instructions for Create React App, then your project will have src/bem-helper.ts to help enforce this naming convention in your Typescript files. Using the Sass ampersand can also help enforce BEM naming in Sass files.

Create a new project

For this demo project, we recommend using Facebook's Create React App, a method for creating single-page React applications.

To initialize a project with Create React App, enter this in your command line:

npx create-react-app --template typescript my-app
cd my-app
npm start

This creates a project with the base template. For additional configuration options, see the Create React App documentation. Create React App has several built-in scripts. It also generates files that you don't need and can delete:

  • serviceWorker.js and related code in index.js
  • index.css and the corresponding import statement in index.js
  • logo.svg

Open http://localhost:3000/ to see your app.

Configure Forge

Check your home directory for a .npmrc file (in OSX or Git for Windows, this is ~, and in Windows it’s %HomeDrive%%HomePath%). Add this line to it:

registry=https://artifactory.aws.athenahealth.com:443/api/npm/npm/
@athena:registry=https://artifactory.aws.athenahealth.com:443/api/npm/npm-local/

To start using Forge components in your project, add it as a dependency. To do this, enter this in the command line from the root of your project:

npm install @athena/forge

Create a "Hello, World!" app

Include @athena/forge/dist/forge.css in your app so that Forge components render with the correct styles. This can be done the same way you include stylesheets (webpack, link tags, etc.).

Use the Root component for the root of your app’s Forge section. To use Forge for the whole app, put Root at the root of the app. To use Forge in a specific section of your app, wrap just that part of your app with Root.

Root renders a div with the fe_f_all class to ensure that all content and components under it render with correct Forge styles. Forge styles are scoped and go under fe_f_all. You can now import Forge components from @athena/forge and render them in your own React code.

To make a simple “Hello, World!” example that uses the Root and Heading components, paste this code into index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import '@athena/forge/dist/forge.css';
ReactDOM.render(<App />, document.getElementById('root'));

Paste this code into App.tsx:

import React from 'react';
import { Root } from '@athena/forge';
import { Heading } from '@athena/forge';
function App() {
return (
<Root>
<Heading text="Hello, World!" />
</Root>
);
}
export default App;

Open http://localhost:3000/ to view your app. To include additional Forge components, see the Components page. Every component is fully documented and has a demo you can edit.

Testing and debugging

To test your code, use Testing Library and jest. To debug, you can use vscode debugger.

For an athenahealth-specific approach to testing, see the Nimbus testing guidance.

Deploying Forge apps

athenahealth uses Nimbus to host and deploy Forge apps. Our Nimbus documentation covers everything you need to release your app to athenahealth users, and much more.

Working with designers

Most athenahealth designers use Figma, a cloud-based tool for designing user interfaces. It makes prototyping easy and includes git-like features suited to large design organizations like ours.

With Figma’s dev handoff tools, it’s easy to find color, font, spacing, and size information, as well as copy text into your code. See Figma for developers for more information.

Going deeper with Forge

Using TypeScript

We’re in the process of converting Forge to TypeScript. This will make it easier to see the types that component props expect when working in VSCode. As a rule, Forge components export any custom types for props. You can import these the same way you import a component. Use exported Forge types instead of writing your own. For example:

import { Multiselect, MultiselectOption } from '@athena/forge'

Customizing with CSS

Thanks to Forge’s Grid component, typography utilities, and layout utilities, you can build much of your app without writing any CSS. Consistency and easy maintenance are priorities for Forge, so localized styling is discouraged. For help finding a consistent, reusable solution, reach out to the Forge team for guidance.

There may be scenarios that truly require customizing Forge’s default visual elements. For instance, nearly all legacy integrations involve some CSS tweaks. There are a few things you need to do to make sure your CSS works with Forge’s:

  1. Use Sass constants from Forge abstracts for consistent styling.

  2. If you used Create React App to build your app, follow these steps. Otherwise, the Nimbus create-react-app template already uses dart-sass.

  3. Create a new sass file App.scss and import Forge abstracts into it. Note the BEM naming convention:

@use '@athena/forge/sass/forge-abstracts';
.hiworld_c_app__header--toggled {
color: map-get(forge-abstracts.$color-alert, critical);
}
  1. Import App.scss from App.tsx.

To target a Forge component, add a custom class to the root of the component with the className prop. Every Forge component has this prop. Use the custom class in combination with Forge BEM classes to target elements of the component. For example:

import React, { useState } from 'react';
import { Heading, Root, ToggleSwitch } from '@athena/forge';
import createBEMHelper from '../../bem-helper';
import { forgeTheme } from '../../nimbus-config';
import './App.scss';
// Use this function in your React components to establish a
// BEM class name scope for the component and its elements.
const classes = createBEMHelper({
name: 'app'
});
export interface AppProps {
// These props can be passed in to your app from athenaNet
someProp?: string;
}
export default function App({ someProp }: AppProps): JSX.Element {
const [toggled, setToggled] = useState(false);
return (
/* This must be applied for Nimbus CSS namespacing to work */
<Root {...classes()} theme={forgeTheme}>
<Heading
{...classes({
element: 'header',
modifiers: (toggled ? ['toggled'] : [])
})}
text="Hello, World!"
/>
<ToggleSwitch onChange={() => setToggled((currentToggled)
=> !currentToggled)} />
</Root>
);
}

Most Forge CSS rules have specificity of 2 classes (3 classes for states). Your CSS rules need higher precedence and specificity to override them. An easy way for athenahealth devs to achieve the correct level of specificity is to use the streamlined-forge function in clinicals-sass-utils. Note that despite having “clinicals” in the name, there’s nothing in this library that’s athenaClinicals-specific. This function provides the necessary precedence to override Forge and Nimbus styling rules.

Building on the previous example, this Sass:

@use ‘@athena/clinicals-sass-utils';
@use '@athena/forge/sass/forge-abstracts';
#{clinicals-sass-utils.streamlined-forge(2)} .hiworld_c_app {
text-align: center;
&__header {
&--toggled {
color: map-get(forge-abstracts.$color-alert, critical);
}
}
}

translates to this CSS:

:not(#not-forge-ready) .fe_f_all.fe_f_all .hiworld_c_app__header--toggled {
color: #CA0D0D;
}

Typically, this is enough specificity to beat Forge styling in athenaNet. To add more specificity, increase the number in the parentheses of streamlined-forge. This adds an additional .fe_f_all class to the selector.

We plan to add better support for the shadow DOM, removing the need for this complicated CSS precedence rule.

CSS is a complicated topic that’s explained more thoroughly here.

Contributing to Forge

Forge provides building blocks for your projects, but new features or use cases might call for a new component, an updated design, or alternative behavior. Contributing your work to Forge expands the design system, which helps the whole community work more efficiently and improves the user experience. It’s easy to contribute, and we have an active pipeline of contributions. Connect with us on Teams to join the discussion with designers, developers, and the Forge team.

Resources

Utilities

All Sass variables

  • $breakpoints
  • $color-alert
  • $color-background
  • $color-border
  • $color-brand
  • $color-dataviz
  • $color-font
  • $color-interaction
  • $color-secondary
  • $color-shadow 
  • $font-size
  • $font-weights
  • $global-border
  • $global-border-focus
  • $global-border-shadow
  • $global-cursor-disabled
  • $global-cursor-interactive
  • $global-margin
  • $global-padding
  • $global-radius
  • $global-shadow
  • $global-shadow-strong
  • $global-transitions
  • $global-transition-duration-short
  • $global-transition-duration-medium
  • $global-timing-function-in-out
  • $global-timing-function-out