Skip to content

Getting Started

Installation

To get started using Primer React, install the package and its peer dependencies with your package manager of choice:

# with npm
npm install @primer/components react react-dom styled-components
# with yarn
yarn add @primer/components react react-dom styled-components

You can now import Primer React from the main package module:

// using import syntax
import {Box, Flex} from '@primer/components'
// using require syntax
const {Box, Flex} = require('@primer/components')

Minimizing bundle size

Module bundlers that use ECMAScript modules (ESM) will automatically tree-shake Primer React, ensuring that no unused code is included in your final bundle. However, if you're not using ESM, you may be able to drastically reduce the size of your final bundle by importing components individually from the lib subfolder:

// using import syntax
import Box from '@primer/components/lib/Box'
import Flex from '@primer/components/lib/Flex'
// using require syntax
const Box = require('@primer/components/lib/Box')
const Flex = require('@primer/components/lib/Flex')

Note that the modules in the lib folder are CommonJS-style modules; if you're using ESM and a compatible module bundler, importing files individually from lib provides no benefit.

Peer dependencies

Primer React ships with a few libraries labeled as peer dependencies. These libraries are separated because they are commonly already installed in the host project and having multiple versions can introduce errors.

Primer React requires the following libraries to be installed along with it:

  • styled-components at version 4.0.0 or higher
  • react at versions 16.8.0 or higher
  • react-dom at versions 16.8.0 or higher

BaseStyles

In order to set baseline color, font-family, and line-heights across your project, you will need to establish base Primer styles for your app by wrapping all of your Primer components in <BaseStyles> at the root of your app:

import {BaseStyles, Box, Heading} from '@primer/components'
export default const MyApp = () => (
<BaseStyles>
<Box m={4}>
<Heading mb={2}>Hello, world!</Heading>
<p>This will get Primer text styles.</p>
</Box>
</BaseStyles>
)

This will apply the same color, font-family, and line-height styles to the <body> as Primer CSS's base styles.

Theming

Components are styled using Primer's theme by default, but you can provide your own theme by using styled-component's <ThemeProvider>. If you'd like to fully replace the Primer theme with your custom theme, pass your theme to the <ThemeProvider> in the root of your application like so:

import {ThemeProvider} from 'styled-components'
const theme = { ... }
const App = (props) => {
return (
<div>
<ThemeProvider theme={theme}>
<div>your app here</div>
</ThemeProvider>
</div>
)
}

If you'd like to merge the Primer theme with your theme, you can do so by importing the Primer theme and then merging the themes using a library like deepmerge:

import {ThemeProvider} from 'styled-components'
import {theme} from '@primer/components'
import deepmerge from 'deepmerge'
const customTheme = { ... }
const newTheme = deepmerge(theme, customTheme, {
// overwrite arrays instead of concatenating
arrayMerge: (_dest, source) => source
})
const App = (props) => {
return (
<div>
<ThemeProvider theme={deepmerge(theme, )}>
<div>your app here</div>
</ThemeProvider>
</div>
)
}

Note that using Object.assign to merge themes will only create a shallow merge. This means that if both themes have a color object, the entire color object will be replaced with the new color object, instead of only replacing duplicate values from the original theme's color object. If you want to merge sub-values, be sure to use a deep-merging strategy.

Static CSS rendering

If you're rendering React components both server- and client-side, we suggest following styled-component's server-side rendering instructions to avoid the flash of unstyled content for server-rendered components.

TypeScript

Primer React includes TypeScript support and ships with its own typings. You will need still need to to install type typings for the peer dependencies if you import those in your own application code.

Once installed, you can import components and their prop type interfaces from the @primer/components package:

import {BorderBox, BorderBoxProps} from '@primer/components'

Fixing "Duplicate identifier 'FormData'"

Ever since @types/styled-components version 14.1.19, it has had a dependency on both @types/react and @types/react-native. Unfortunately, those declarations clash; for more information, see issue 33311 and issue 33015 in the DefinitelyTyped repo.

You may run into this conflict even if you're not importing anything from react-native or don't have it installed. This is because some package managers hoist packages to the top-level node_modules folder, and the TypeScript compiler automatically includes types from all folders in node_modules/@types by default.

The TypeScript compiler allows you to opt-out of this behavior using the typeRoots and types configuration options, and the best solution for this error — for now — seems to be to opt out the automatic inclusion of node_modules/@types and instead list the types you want to be included individually.

In your tsconfig.json, set the types array under the compilerOptions like so:

{
"compilerOptions": {
"types": ["node", "react", "styled-components", "jest"]
}
}

Of course, customize the array based on the @types/ packages you have installed for your project.

Silencing warnings

Like React, Primer React emits warnings to the JavaScript console under certain conditions, like using deprecated components or props. Similar to React, you can silence these warnings by setting the NODE_ENV environment variable to production during bundling.

Edit this page on GitHub
4 contributorsemplumsBinaryMusealbingroensamrose3
Last edited by emplums on August 26, 2020