---
title: 'React Native styling: Structure for style organization'
teaser: 'Setting up a React Native project for ergonomic styling while implementing
  designs.

  '
tags: react native,design,style guides,javascript
author:
- John Schoeman
- Vendela Larsson
published_on: 2019-03-18
---

React Native projects are flexible in how they can be organized and structured,
especially when it comes to style implementations. We find a lot of variation
between applications that we work on in how they setup and organize styles.
This leads to extra overhead when developing new features for new projects and
sometimes projects land on certain patterns that make it cumbersome to iterate on
design.

We've learned a few simple strategies which have led us to a more enjoyable
experience while working on React Native projects. Here are some of these
concepts for applying styles to maximize ergonomics and readability.
These allow us to develop and iterate on designs more quickly, easily, and consistently.

If you would rather learn by directly viewing some code,
we've put together a minimal template application to demonstrate these concepts.
You can find it here:
[RNStylingTemplate]

<img
src="https://images.thoughtbot.com/vl-structure-for-styling-in-react-native/b398mNCcSyynDawnH311_vl-react-native-styling.png"
alt="React Native Template Screenshot" />

### 1: Styles are important: make them easy to find

Keep styles in the root source folder.

Styling is a first class concern, and as such, styles should be accessible from a
top-level folder in the application code.

```tree
MyReactNativeApp
  - src
    - assets
    - compontents
      - MyComponent.js
    - styles
      - colors.js
      - index.js
      - typography.js
      - ...
  ...
```

We reference styles in almost every component and making them as accessible as
possible will lead to cleaner code.

Another way to think about it is that we want to minimize the use of `../`'s
in our relative paths. This not only reduces the amount of mental overhead in
counting nested folders, but it allows for easier refactoring and understandability
as the project evolves.

```javascript
import { MyStyles } from '../styles'
```

is easier to work with than:

```javascript
import { MyStyles } from '../../../../common/utils/styles/my_styles'
```

### 2. Get atomic!

Build complicated styles from simpler styles.

By using object destructuring in style declaration, we get really concise and
readable styles which allows us to be declarative in our components.

```javascript
// buttons.js

export const small = {
  paddingHorizontal: 10,
  paddingVertical: 12,
  width: 75
};

export const rounded = {
  borderRadius: 50
};

export const smallRounded = {
  ...base,
  ...small,
  ...rounded
};
```

```javascript
// src/MyComponent/index.js

const styles = StyleSheet.create({
  button: {
    ...Buttons.smallRounded,
  },
})
```

is easier to understand the intent of and maintain than:

```javascript
// src/MyComponent/index.js

const styles = StyleSheet.create({
  button: {
    paddingHorizontal: 10,
    paddingVertical: 12,
    width: 75,
    borderRadius: 50
  },
})
```

### 3: Styles are important: make them easy to use

Group similar variables in modules and bundle them up in an `index.js` file.

Style variables are easier to find and understand when they're organized by
function. Therefore, they should live in purposeful files.

If we place an `index.js` in this folder we can take advantage of JavaScript ES6
import syntax for importing all the styles at once.

```tree
- styles
  - colors.js
  - index.js
  - spacing.js
  - typography.js
  - buttons.js
```

```javascript
// src/styles/index.js

import * as Buttons from './buttons'
import * as Colors from './colors'
import * as Spacing from './spacing'
import * as Typography from './typography'

export { Typography, Spacing, Colors, Buttons }
```

This allows us to:

- import only what we need
- import from the same file every time
- give the variables descriptive and short names, contained in a descriptive object.
- easily extend and modify the common styles
- write more concise and expressive code.

```javascript
// src/MyComponent/index.js

import { Typography, Colors, Spacing } from '../styles'

...

const styles = StyleSheet.create({
  container: {
    backgroundColor: Colors.background,
    alignItems: 'center',
    padding: Spacing.base,
  },
  header: {
    flex: 1,
    ...Typography.mainHeader,
  },
  section: {
    flex: 3,
    ...Typography.section,
  }
})
```

is better than:

```javascript
// src/MyComponent/index.js

import {
  largePadding,
  smallest,
  small,
  large,
  base,
} from '../../../common/utils/styles/spacing'
import {
  largeRadius,
  baseTextColor,
  headerFontSize,
  smallFontSize,
} from '../../../common/utils/styles/common'
import { background, shuttleGray } from '../../../common/utils/styles/colors'

...

const styles = StyleSheet.create({
  container: {
    backgroundColor: background,
    padding: largePadding,
  },
  header: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#b7bdc5',
    flexDirection: 'row',
    justifyContent: 'center',
    borderRadius: largeRadius,
    color: shuttleGray,
    fontSize: headerFontSize,
    paddingBottom: base,
  },
  section: {
    flex: 3,
    alignItems: 'center',
    backgroundColor: background,
    flexDirection: 'row',
    justifyContent: 'center',
    borderRadius: largeRadius,
    color: baseTextColor,
    fontSize: smallFontSize,
    lineHeight: 19,
  }
})
```

This conciseness and consistency of always pulling in styles from the same place
adds up to significant savings in development time over the life of a project.

### 4. Keep styles close

Keep `StyleSheets` inline with components

Defining `StyleSheets` in the same file as your component can help make sure that:

- styles for one component won't be overwritten for another component in a future
  iteration
- styles will be maintained as the component evolves
- components can be flexible during design iteration
- there is a minimum amount of mental overhead while implementing designs for
  components since there is one place to look for styles rather than many.

One reason you might want to not to use in-line stylesheets is to reduce the
amount of duplication in the code, but now that you're creating variables for
global styles in functionally-named files, you can still be mindful of practicing
D.R.Y. (Don't Repeat Yourself) coding, without reusing stylesheets themselves.

```javascript
// src/MyNewComponent/index.js

import { Typography } from '../styles'

const MyNewComponent = () => (
  <View style={styles.container}>
    <View style={styles.header}>
       <MyComponent />
    </View>
    <View style={styles.body}>
       <MyOtherComponent />
    <View>
  </View>
)

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    ...Typography.header
  },
  body: {
    ...Typography.body
  },
})
```

is more self contained than:

```javascript
// src/MyNewComponent/index.js

import { styleSheetA, styleSheetB, styleSheetC } from './stylesheets'

const MyNewComponent = () => (
  <View style={styleSheetC.container}>
    <View style={styleSheetA.header}>
       <MyComponent />
    </View>
    <View style={styleSheetB.body}>
       <MyOtherComponent />
    <View>
  </View>
)
```

The simplicity of only needing to update one file to update one stylistic change
to a component is faster and leads to fewer bugs.

### Caveats

What we've presented here works well as a starting point for us and our clients,
but JavaScript and React Native are large and quickly-evolving ecosystems. There
is no one-size-fits-all solution for all projects, so your mileage may vary.

Extra large projects with hundreds of components or projects with very specific
business needs might benefit from different patterns.
Themed components and non-inline stylesheets, for example, are other patterns
that may work better for your specific situation.

Everything is a trade-off and here we are optimizing for speed and clarity of
design implementation.

Ultimately you'll need to iterate and find what works for your specific project
and team.

### Conclusion

1. Styles are important: make them easy to find: Keep styles in the root
   application folder
2. Get atomic!: Build complicated Styles from simpler Styles
3. Styles are important: make them easy to use: Bundle like styles and expose via
   an index.js file
4. Keep Styles close: Keep styles inline with components

All together, an application of styles to a component could look like this:

```javascript
// src/MyOtherComponent/index.js

import React from 'react'
import { StyleSheet, View } from 'react-native'

import MyComponent from './MyComponent'

import { Colors } from './styles'

const MyOtherComponent = () => (
  <View style={styles.container}>
    <MyComponent />
  </View>
)

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: Colors.background,
  },
})

export default MyOtherComponent
```

By following the above conventions we can keep styles in our React Native
projects cleaner, leaner, and meaner. This allows us to iterate faster, have a more
enjoyable development experience, and ultimately build better products.

Again, here's a simple template app to help demonstrate these practices for
implementing styles in a React Native application: [RNStylingTemplate]

[RNStylingTemplate]: https://github.com/thoughtbot/RNStylingTemplate

## Want a great mobile experience?

thoughtbot uses a flexible, iterative approach in creating great mobile app experiences by incorporating designers and developers into the development process. [Learn more](https://thoughtbot.com/services/react-native-development) about thoughtbot's holistic approach to React Native projects.
