Top 5 Ways to Style Your React Apps in 2024

Style your React apps using Stylex, Styled Components, Sass, Tailwind or Emotion in 2024!

Lakindu Hewawasam
Bits and Pieces

--

Styling React components has become easier over the years. You no longer have to build your styles but can work from boilerplate stylesheets that are generally enough for small-scale projects.

But, it’s essential to understand the correct CSS libraries to use in 2024 to style your app. Choosing the proper framework can save a lot of time from the start.

So, let’s dive in and explore the top 5 libraries you can use to style your React apps in 2024.

I’ll use Bit to showcase demos for each library, as it’s easier to build compatible apps with Bit than with a traditional React app. So, make sure you’ve installed Bit locally and initialized an empty workspace, scope to follow along!

To quickly initialize a Bit workspace, run the command:

bit new basic css-workspace --default-scope <<YOUR_BIT_USERNAME>>.<<SCOPE_NAME>> && cd css-workspace && bit start

If you wanna jump right into how each of these libraries work, check it out here.

Approach 01: StyleX

StyleX is a JavaScript syntax and compiler for styling web apps by the team at Meta. It introduces the same benefits of a standard CSS-in-JS solution (and more) without the performance overhead.

StyleX lets you remove the global boundary of CSS and create more component-bound CSS configurations that become easier to debug, scale, and maintain. Additionally, it introduces a type-safe way to write CSS in JavaScript, which gets transpiled to regular CSS at build time.

You can integrate StyleX onto your React Components using Bit in a few steps:

First, you must ensure that your workspace can create StyleX components.

Luckily for us, the Bit team has already created a StyleX + React environment that we can use to create our components from. All we have to do is rely on that!

Create a React component that uses StyleX for styling using the command:

bit create stylex stlyex/button --env learnbit-react.stylex/envs/react-stylex

After you’ve run the command, you should see the output:

Next, open the button.tsx you can work with StyleX as shown below:

import { type ReactNode, type HTMLAttributes } from 'react';
import * as stylex from '@stylexjs/stylex';
import type { StyleXStyles } from '@stylexjs/stylex';

const styles = stylex.create({
base: {
fontSize: 32,
color: '#eeeaee',
backgroundColor: {
default: '#720b72',
':hover': '#a93da9',
},
padding: 12,
borderRadius: 8,
borderColor: 'unset',
},
});

export type ButtonProps = {
children?: ReactNode;
style?: StyleXStyles;
} & Omit<HTMLAttributes<HTMLButtonElement>, 'style'>;

export function Button({ children, style }: ButtonProps) {
return (
<button type="button" {...stylex.props(styles.base, style)}>
{children}
</button>
);
}

You can update the compositions and provide a visual output for your components using the code by updating button.composition.tsx :

import React from 'react';
import { Button } from './button';

export const BasicButton = () => {
return (
<Button>Hello World!</Button>
);
}

export const StyledButton = () => {
return (
<Button
style={{
color: 'blue' as any
}}
>Blue Text Button!</Button>
);
}

This will provide a set of variations that

Next, you can open the Bit server and view the StyleX component below:

That was simple wasn’t it? You can work with StyleX with Bit in a few commands!

To find it’s full implementation, check out my React + StyleX Component.

Approach 02: Styled Components

Styled Components lets you to write CSS in JS while building custom components in React.js. This lets you maintain your CSS code right in your JavaScript file and write maintainable CSS.

To create a React component that uses Styled-Components, I’ve created an environment that you can use. Simply run the command to create a simple React component:

bit create react styled/button --env dummyorg.react-css/envs/react-styled

You should see the output:

You could directly add a custom CSS style to your component, or you could create more utility components in Bit that hold your theming configs. For a detailed explanation on this, check this out:

But, for a simple implementation to help you get started, open up your button.tsx file in your styled directory and add the code:

import React from 'react';
import type { ReactNode } from 'react';
import styled from 'styled-components';
import { css } from 'styled-components';

export type ButtonProps = {
children?: ReactNode;
isPrimary?: boolean
};

const StyledButton = styled.a<{ primary?: boolean; }>`
--accent-color: blue;

background: transparent;
border-radius: 3px;
border: 1px solid var(--accent-color);
color: var(--accent-color);
display: inline-block;
margin: 1rem;
padding: 1rem 0;
transition: all 200ms ease-in-out;
width: 11rem;

&:hover {
filter: brightness(0.85);
}

&:active {
filter: brightness(1);
}

${props => props.primary && css`
background: var(--accent-color);
color: white;
`}
`

export function Button({ children, isPrimary = false }: ButtonProps) {
return (
<StyledButton
primary={isPrimary}
>
{children}
</StyledButton>
);
}

As you can see, we’ve leveraged Styled-Components to build a StyledButton and we're wrapping its implementation with our custom Button component.

Next, you can customize your compositions to showcase the different variations we’ve created — Primary/Secondary:

import React from 'react';
import { Button } from './button';

export const BasicButton = () => {
return (
<Button>Basic Button</Button>
);
}

export const PrimaryButton = () => {
return (
<Button
isPrimary
>
Primary Button
</Button>
);
}

Afterward, you can head over to your Bit server to see the Styled-Component Button:

To checkout the full implementation, check out my demo component.

Approach 03: Sass

Sass/SCSS has been a replacement to CSS due to the advanced features that it provides. SCSS lets you nest CSS, introduce variables and work with mixins.

By leveraging these features, you can build pretty write powerful CSS code with minimal efforts.

Generally, you’d need to configure SCSS by supporting the your compiler to read the .scss files. But, with Bit, this is offered by default and is quite effortless to build with SCSS/Sass.

To do so, create a basic React component with Bit:

bit create react scss/button

You’ll see the output below:

Next, expand the directory scss/button and modify the create a file - <<component-name>>.scss. In our case, it'll be button.scss. Afterward, you'll see the output:

Next, open the button.scss file and work on your component specific SCSS configurations:

.button {
padding: 10px;
margin: 10px;
font-size: 18px;
border-color: unset;
}

.purple {
background: #8d2ee6;
}

Next, open up your button.tsx file to consume the SCSS file:

import React from 'react';
import type { ReactNode } from 'react';
import './button.scss';

export type ButtonProps = {
children?: ReactNode;
};

export function Button({ children }: ButtonProps) {
return (
<div className='button purple'>
{children}
</div>
);
}

Next, open your Bit server and you should see your SCSS stylings applied to your Button:

To see its full implementation, have a look at this Button.

Approach 04: Tailwind

Tailwind is a UI library that is purely driven by CSS. It’s similar to Bootstrap, but more advanced! It lets you build complex UI components such as tables, grids, cards, avatars with a few CSS class.

But, setting up Tailwind isn’t easy. You have to create a Tailwind compiler and update your build process to compile the Tailwind CSS. But, luckily for us. the Bit team has created a Tailwind Environment that we can leverage to build Tailwind components.

To do so, run the command:

bit create react tailwind/button --env learnbit-react.tailwind/tailwind-env

Afterward, you should see the output:

Next, open the button.tsx file and let's write some Tailwind:

import type { ButtonHTMLAttributes, ReactNode } from 'react';
import { twMerge } from 'tailwind-merge';

export type ButtonProps = {
children?: ReactNode;
} & ButtonHTMLAttributes<HTMLButtonElement>;

export function Button({ children, className, ...rest }: ButtonProps) {
const classes = twMerge(
'inline-flex items-center justify-center px-4 py-2 border border-transparent text-base font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500',
className
);

return (
<button className={classes} type="button" {...rest}>
{children}
</button>
);
}

Next, let’s add a composition to define its output.

import { Button } from './button';
import '@learnbit/styling.config.tailwind/globals.tailwind.css';

export const BasicButton = () => {
return <Button type="button">Hello World</Button>;
};

Afterward, head back to the Bit dev server and you should see the output:

To see the full implementation, check out this component on Bit Cloud.

Approach 05: Emotion

Finally, we’ve got Emotion. Emotion is quite similar to styled-components. It lets you create styled components with custom CSS or directly automatically create a className to a CSS function that you provide. This is show clearly in their documentation:

To work with Emotion is really simple. I’ve created a dev environment that you can use to directly start working with Emotion CSS. To do so, create a React component using this command:

bit create react emotion/button --env dummyorg.react-css/envs/react-emotion

You should see the output:

Next, you can open up the file emotion/button/button.tsx and start building your React component with Emotion as shown below:

import React from 'react';
import type { ReactNode } from 'react';
import { css } from '@emotion/css'

const color = 'white'
export type ButtonProps = {
children?: ReactNode;
};

export function Button({ children }: ButtonProps) {
return (
<div
className={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
` as any}
>
{children}
</div>
);
}

Next, head back to your dev server and you should see the output of the button in hotpink.

For a detailed implementation, you can check the full component out.

Wrapping Up

And it’s as simple as that! These libraries can be quite difficult to configure if you’re doing it on your own. But, if you’re building with tools like Bit, this becomes effortless as there’s plenty of reusable components and environments out there that you can leverage in your workflow.

I hope you grasped each of these libraries and are now set on selecting the right library for your next big React project in 2024!

To browse the full code, check out my Bit Scope.

Thank you for reading.

--

--