---
title: "Building with Sky UI"
canonical: https://sky-ui.cf.sky.com/intro-to-sky-ui/building-with-sky-ui
apiPackages: [{"name":"@sky-uk/ui-core","representedVersion":"14.0.0"}]
---

# Building with Sky UI

Learn to compose and customise Sky UI components with code examples and selected live previews.

Learn to use and customise Sky UI components. Start with the
[Developer Quickstart](/intro-to-sky-ui/developer-quickstart/) for installation, then explore the
code examples below. Examples with a live preview can be edited to see your changes.

## Set up global styles

Add `GlobalReset` once at the top of your app, before the page content:

```jsx
import { GlobalReset } from "@sky-uk/ui-core";

export default function App({ children }) {
  return (
    <>
      <GlobalReset />
      {children}
    </>
  );
}
```

It provides consistent browser styles and Sky fonts. See
[GlobalReset](/components/global-reset/) for details and the
[React Server Components guide](/guides/react-server-components/) for Next.js App Router usage.

## Use a component

Import the components you need from `@sky-uk/ui-core`:

```js
import { Box, Button, Text } from "@sky-uk/ui-core";
```

Try changing the Button's `$variant` from `primary` to `secondary`:

```tsx
<Button type="button" $variant="primary" $marginTop={4}>
  Button
</Button>
```

Styling props start with `$`. HTML attributes and event handlers keep their usual names, such as
`type`, `aria-label`, and `onClick`. Check each component's React API for supported props.

## Use theme values

Use theme helpers for Sky UI colours and spacing. Here, `color('primary')` sets the blue
background and `spacing(4)` sets the padding:

```jsx
import styled from "styled-components";
import { color, spacing } from "@sky-uk/ui-core";

const MyComponent = styled.div`
  background-color: ${color("primary")};
  color: ${color("white")};
  padding: ${spacing(4)};
`;

export const Example = () => <MyComponent>Hello world!</MyComponent>;
```

Define styled components outside the React component function.
See [Foundations](/foundations/) for available values.

## Use a basic modifier

Use a prop to switch styles. Here, `$color="blue"` selects blue; other values select red:

```jsx
import styled from "styled-components";
import { color, spacing } from "@sky-uk/ui-core";

const MyComponent = styled.div`
  background-color: ${({ $color }) =>
    color($color === "blue" ? "primary" : "negative")};
  color: ${color("white")};
  padding: ${spacing(4)};
`;

export const Example = () => (
  <MyComponent $color="blue">Hello world!</MyComponent>
);
```

## Make styles responsive

Set different values at each [breakpoint](/foundations/breakpoints/). Here, padding increases at
`lg`. Open the fullscreen preview and resize the window to see the change:

```tsx
<Box $border={true} $borderColor="black" $padding={{ xs: 4, lg: 6 }}>
  <Text>Compact spacing on small screens, more room on larger screens.</Text>
</Box>
```

## Use system modifiers

Use `applyModifierProps()` to add styling props to your own component. This example adds colour
and margin props, including responsive values:

```jsx
import styled from "styled-components";
import { applyModifierProps, color, spacing } from "@sky-uk/ui-core";

const MyComponent = styled.div`
  background-color: ${color("grey5")};
  padding: ${spacing(4)};

  ${applyModifierProps({ system: ["color", "margin"] })}
`;

export const Example = () => (
  <MyComponent $color="primary" $marginBottom={{ xs: 4, md: 6 }}>
    Hello world!
  </MyComponent>
);
```

### Modifiers or CSS?

Use modifiers when someone using your component needs to change its styles. For fixed internal
styles, use CSS. For example, these values are always set inside `MyComponent`:

```jsx
import styled from "styled-components";
import { applyModifierProps } from "@sky-uk/ui-core";

const Wrapper = styled.div`
  ${applyModifierProps({ system: ["padding", "width"] })}
`;

export const MyComponent = () => (
  <Wrapper $padding={{ xs: 4, lg: 5 }} $width="100%">
    Hello world!
  </Wrapper>
);
```

Write them directly in CSS instead:

```jsx
import styled from "styled-components";
import { breakpoint, spacing } from "@sky-uk/ui-core";

export const Wrapper = styled.div`
  padding: ${spacing(4)};
  width: 100%;

  @media (min-width: ${breakpoint("lg")}) {
    padding: ${spacing(5)};
  }
`;

export const MyComponent = () => <Wrapper>Hello world!</Wrapper>;
```

## Add a custom modifier

Add your own styling choices with `applyModifierProps()`. Here, `$appearance` switches from red
to blue at the `lg` breakpoint:

```js
import styled, { css } from "styled-components";
import { applyModifierProps, color, spacing } from "@sky-uk/ui-core";
```

These imports are already available in the live editor. The outer function keeps the preview
self-contained; in your app, define the styled component outside the React component function.

```tsx
(() => {
  const $appearance = {
    red: css`background-color: ${color('negative')};`,
    blue: css`background-color: ${color('primary')};`
  };

  const MyComponent = styled.div`
    color: ${color('white')};
    padding: ${spacing(4)};

    ${applyModifierProps({
      modifiers: { $appearance }
    })}
  `;

  return (
    <MyComponent $appearance={{ xs: 'red', lg: 'blue' }}>
      Hello world!
    </MyComponent>
  );
})()
```

## Composition

A custom `Hero` could take all its content through props:

```jsx
<Hero
  heading="Hero heading"
  bgAsset="image-url"
  cta={{
    text: "click me",
    href: "link-url",
  }}
/>
```

Composition lets you arrange the content and add components without adding more props:

```jsx
<Hero>
  <Hero.Asset>{image ? <Image src={src} /> : <Video src={src} />}</Hero.Asset>
  <Hero.Content>
    <Text as="h2">Hero heading</Text>
    <CustomComponent />
  </Hero.Content>
  <Hero.Actions>
    <Button href="link-url">click me</Button>
  </Hero.Actions>
</Hero>
```

This illustrates a custom `Hero`, rather than a component exported by Sky UI. See
[Hero Sections](/sections/hero/react/) for the package APIs.

Keep heading levels and interactions appropriate to the page, and follow each component's
documented child structure.
