Using Styled components with Preact

Published on 10 September 2020 3 minute read (439 words)

Background

Preact is a really cool alternative to React. It's designed to be a fast, small (a mere 3kB) alternative to React with almost the same API. All your favorite buzz word things are there - hooks, functional components, server-side rendering out of the box, you name it. It's a great choice for more performance-oriented projects.

Styled Components are a great way of building scoped and reusable components quickly in the React world. You are essentially writing SASS-like styles in JavaScript. I know, it sounds sacrilegious, but I promise you it's actually pretty cool. Styled is a great choice for when you want a more atomic design structure to your app/component library.

You might've noticed that I said Styled is a part of the "React world", not the "Preact World". That's because it's a companion library to React, but, with a few tweaks - it'll work with our Preact app just as well.

Creating our Preact app with Preact CLI

Much like any cool framework/library worth its salt these days - Preact, too, has its own CLI package. Execute this in your terminal to install it:

npm i -g preact-cli

After installing the CLI, we can use it to create our fancy Preact app:

preact create default my-project

For a TypeScript Preact project, execute this command instead:

preact create typescript my-project

After the CLI is done creating your new app, you can navigate to it:

cd my-project

Installing Styled components

Now we need to install Styled Components, and (optionally) its helper Babel plugins:

npm i styled-components
npm i --save-dev babel-plugin-styled-components @quickbaseoss/babel-plugin-styled-components-css-namespace

or

yarn add styled-components
yarn add -D babel-plugin-styled-components @quickbaseoss/babel-plugin-styled-components-css-namespace

Aliasing React to Preact and setting up Babel

We need to do some "magic" called aliasing, so that when Styled looks for React it gets Preact compatibility instead.

Create a new file called preact.config.js in the root folder of your project (if you've used the TypeScript CLI template, it should already be created, in which case just add the code below to the pre-existing method there) and populate it with the following code:

export default {
    webpack(config) {
        config.resolve.alias['react'] = 'preact/compat';
        config.resolve.alias['react-dom/test-utils'] = 'preact/test-utils';
        config.resolve.alias['react-dom'] = 'preact/compat';
    }
};

Next, open .babelrc and add the following code to the preexisting object:

{
  "presets": [
    "preact-cli/babel"
  ],
  "plugins": [
    "@quickbaseoss/babel-plugin-styled-components-css-namespace",
    "babel-plugin-styled-components"
  ]
}

Setting up for use with TypeScript

Disregard this section if you've not used the TypeScript template.

Getting our Styled components to behave under TS is fairly easy. First, we need to install the types for Styled:

npm i --save-dev @types/styled-components

or

yarn add -D @types/styled-components

Then we need to modify our tsconfig.json and add the following to the compilerOptions object:

{
  "skipLibCheck": true,
  "allowSyntheticDefaultImports": true,
  "baseUrl": ".",
  "paths": {
      "react": ["node_modules/preact/compat/"],
      "react-dom": ["node_modules/preact/compat/"]
  } 
}

Now we can safely import/export Styled components into Preact components without getting TS errors.

Creating our first Styled component in JavaScript

Let's create a sample styled component to test with. In src/routes/home create test.component.js:

import styled from 'styled-components';

const Test = styled.div`
  background: red;
`;

export default Test;

And then import and use it in src/routes/home/index.js:

import { h } from 'preact';
import style from './style.css';
import Test from './test.component';

const Home = () => (
 <div class={style.home}>
  <Test>
   <h1>Home</h1>
   <p>This is the Home component.</p>
  </Test>
 </div>
);

export default Home;

Creating our first Styled component in TypeScript

In src/routes/home create test.component.ts:

import styled from 'styled-components';

const Test = styled.div`
  background: red;
`;

export default Test;

And then import and use it in src/routes/home/index.tsx:

import { h } from 'preact';
import style from './style.css';
import Test from './test.component';

const Home = () => (
 <div class={style.home}>
  <Test>
   <h1>Home</h1>
   <p>This is the Home component.</p>
  </Test>
 </div>
);

export default Home;

Inspecting the fruits of our labor

To check out our super-dooper Styled component, run:

npm run dev

or

yarn dev

And navigate to http://localhost:8080/:

Our Styled component live on the Preact app

That was it! You now have Styled Components inside of your Preact app.