Create react components at the speed of light with Plop.js
Tags: react, javascript, plopjs, typescript
Published: 2022-01-09 09:07:35

---
title: Create react components at the speed of light with Plop.js
published: true
description: Use plop.js to make the tedious task of creating new files a breeze
tags: react, javascript, plopjs, typescript
//cover_image: https://direct_url_to_image.jpg
---

So you are working in your React app, and it comes the time to create a new component, you already have your ritual down. Go to the components folder, create an index file, create another file for styles and finally one more for testing because you are cool. After all of this, you still have to connect these files and write enough code to make them run. You do this every time... every time.

![Boring task](https://media.giphy.com/media/Er3QVX48nt5ok/giphy.gif)

I am assuming a lot, but if this is actually you I have good news!
What if I told you there is way to automate this boring and tedious process?
Trust me, these next 10 minutes are going to change your life. Let me introduce you to plop.js.

## What is Plop.js?

In their own words, it's a tool that saves you time and helps you build new files with consistency.

## How does it work?
It's easier than you think, otherwise I wouldn't be writing about it lol. You create file templates and configure a very simple cli.

## Let's start

First, let's clone this simple react app, it has nothing but just a basic react setup.

```bash
git clone git@github.com:ivanms1/parcel-template.git
```

And navigate to it

```bash
cd parcel-template
```

Now let's install plop, on the terminal type:

```bash
yarn add plop
# or
npm install plop
```

## The Generator

Next, on the root folder, create a file called `plopfile.js` and add the following content inside.

```js
module.exports = function (plop) {
  plop.setGenerator("component", {
    description: "Create a component",
    prompts: [
      {
        type: "input",
        name: "name",
        message: "What is this component's name?",
      },
      {
        type: "input",
        name: "element",
        message: "HTML element (div is default)",
        default: "div",
      },
    ],
    actions: [
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/{{pascalCase name}}.tsx",
        templateFile: "templates/Component.tsx.hbs",
      },
    ],
  });
};

```

We are basically configuring a cli to generate our files. `plop.setGenerator` creates a generator, the first argument is the name of this generator and the second one is an object with some options where we can configure what to generate. Let's analyze the ones we will be using for this guide.

### `description`
Pretty self explanatory, a description of your generator, for example: Generator of react components.

### `prompts`
Series of steps, questions or instructions we give to the user in order to obtain certain information. Plop stores these in variables to use later in the template files.
In our case we are using `input` type prompts to get
- The component's name.
- The component's html tag (div, button, a, etc), it defaults to div.

`message` is text the user will see and has to interact with, generally a question or an instruction.

### `actions`
After we've gather all the information need we then proceed to the actions, represented in an array. In our case we only have one action that creates a file.

Let's go a bit into more details with the actions, since it's where things actually happen. The `add` action type creates a file, `path` is simply the file path where the file is going to be created. The `template` is sort of skeleton that will be used to create the file. Plop uses [handlebars](https://handlebarsjs.com/), a templating language that generates HTML and other text formats.

You might have noticed that we haven't created our template file, and yeah... we need to do that.

## Creating our first template

On the root folder create a folder called `templates`, and add a file named `Component.tsx.hbs` with the following content.

```hbs
import React from "react";

interface {{pascalCase name}}Props {}

const {{pascalCase name}} = () => {
  return <div>{{pascalCase name}}</div>;
};

export default {{pascalCase name}};
```

As you could probably tell, we are creating a react typescript file, in handlebars the variables are inside double brackets (`{{}}`). `pascalCase` converts the `name` variable, that we get from the prompts, to pascal case. So anywhere you see `{{pascalCase name}}`, it will be replaced with the component's name.

So although this is cool, so far we are only creating a new file with some pre-written react code. There are snippet extensions that could do almost the same thing. Let's make this a bit more complete by also adding a style file.

## Adding a style file

I am gonna be using [stitches](https://stitches.dev/), a css-in-js library similar to styled components but with near-zero runtime, but feel free to use whatever you want.

Let's install the library first, on the terminal run:

```bash
yarn add @stitches/react
# or
npm install @stitches/react
```

Since we now want to create a style file as well, we need to add another `action` to our generator. Update `plopfile.js` with the following.

```js
    actions: [
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/{{pascalCase name}}.tsx",
        templateFile: "templates/Component.tsx.hbs",
      },
      // new action here
      {
        type: "add",
        path: "src/components/{{pascalCase name}}/styles.ts",
        templateFile: "templates/styles.ts.hbs",
      },
    ],
```

Pretty similar to the first `action`, now we need to add a new template. Inside the `templates` folder create a file called `styles.ts.hbs` and add the following content.

```hbs
import { styled } from '@stitches/react';

export const Styled{{pascalCase name}} = styled('{{element}}', {});
```

Just your basic css-in-js file, we create a styled component and export it.

`Component.tsx.hbs` needs to be updated, so it imports and uses the new styled component we made. Now it should look like this:

```hbs
import React from "react";

import { Styled{{pascalCase name}} } from "./styles";

interface {{pascalCase name}}Props {}

const {{pascalCase name}} = ({} : {{pascalCase name}}Props) => {
  return <Styled{{pascalCase name}}>{{pascalCase name}}</Styled{{pascalCase name}}>;
};

export default {{pascalCase name}};
```
Now we are talking, plop is saving us some considerable time, generating not one, but two files.

The final step to see this in action is to add the following script to the `package.json`.

```json
  "scripts": {
    ..., // rest of scripts
    // add this at the end
    "generate": "plop"
  },
```

We are finally ready, sit down, relax and enjoy the show. On the terminal type

```bash
yarn generate
# or
npm run generate
```

Now let's create a `Button` component.

![Give component a name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cuvvntmqk0scu5ynf7t5.png)
 
With a `button` tag of course.

![Give component a tag](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q3wlj84hh7bdgadxi2br.png)
 
If everything went well

![Success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4w7i24jh96e4xvhl94at.png)

Let's check the components folder.

```tsx
import React from "react";

import { StyledButton } from "./styles";

interface ButtonProps {}

const Button = ({} : ButtonProps) => {
  return <StyledButton>Button</StyledButton>;
};

export default Button;
```
 
The styles file is there as well.

```ts
import { styled } from '@stitches/react';

export const StyledButton = styled('button', {});
```

![Cat surprised](https://media.giphy.com/media/PUBxelwT57jsQ/giphy.gif)

Pretty cool eh?

Ok maybe is not that cool, but hopefully by now you've realized the potential this has.

I've kept this simple and only created two files but you can keep playing with it and add as many generators and actions as you want. All people/teams are different and you can tweak plop to whatever convention/style you may have. You can even update existing files if for example you like having an index file for all your components. You can create generators for hooks, pages, helpers, etc, the sky is the limit.

I hope you liked this guide and let me know if you made any cool generators at [@ivanms1](https://twitter.com/ivanms1)

Thank you for taking the time to read this article, if you enjoyed it please like to support and follow for more.

[Source Code](https://github.com/ivanms1/react-plop)