Create CLI for your React project in 5 minutes with Pli
Tags: react, typescript, webdev, tooling
Published: 2023-04-06 13:44:07

If you have ever worked with Nest.js (which is a backend framework for Node.js) you may know that they have a nice terminal CLI which allows creating common application components like models, controllers or decorators. I really enjoyed working with it and missed the experience later in many projects. I think especially in frontend projects with React. I love React but one of it’s downsides (and biggest advantages at the same time) is that React is a library and by itself it does not provide any tooling which for bigger projects would be very useful.

So, how can we create the nice experience of having CLI for our project while staying away from React principle of being a library? [Pli](https://github.com/dawiidio/pli) can answer this question. [Pli](https://github.com/dawiidio/pli) is a small library which will turn your files into nice terminal CLI for project in just minutes.

## How to start with Pli?


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwjvqy1s0cl40hfzqtff.jpeg)

Pli is an NPM package, so you can easily install it by typing `npm install -g @dawiidio/pli` or `yarn global add @dawiidio/pli` in your terminal. Later create directory where you want to experiment with Pli, or choose one existing one and checkout there.

When we have Pli installed and we are in our directory run `pli init` . It will create a `templates` directory in current location with example template inside. The example template is `hello.ts` the below code inside it:

```ts
export function hello(): string {
    return 'Hello $NAME$';
}
```

As you can see it’s just a normal TypeScript function. One unusual thing about it, is `$NAME$` inside of string. This is a Pli variable. Pli will extract this variable from our example file and later it will prompt for it’s value in cli to replace `$NAME$` with provided value at the end. Want try it? Run

```sh
pli
# it will ask you which template you want to use
# ? Select template (Use arrow keys)
# ❯ hello.ts
```

For now we have just one template - `hello.js` so let’s go with it.

```txt
# next question is about the directory where you want to save the output file
# you can leave it empty, so the output will be saved in current directory
? Output directory

# and the las question is about our variable $NAME$!
? Insert value for NAME :
```

After providing values for variables Pli will replace all variables in template file and save the output in directory provided in the second question. Final message from pli is paths tree of generated result files and directories, like the below:

```txt
Following structure was created inside directory /path/to/directory
├─ hello.ts
```

I entered the value “Dawid” for variable `$NAME$` so If I will open hello.ts it will contain the following text:

```ts
export function hello(): string {
    return 'Hello Dawid';
}
```

That’s it! Our most basic Pli template is ready to use 🔥

## More complex example

As you saw in previous example, creating templates with Pli is fast and simple since they are just files and variables inside them. Nevertheless simplicity of Pli does not imply that it can’t deal with more complex tasks. Now I want to show you how to create template for React component with css modules styles.

In my application I keep components in directory `src/components` , each component has it’s own directory inside and in this directory I have component and it’s CSS file. What I want to do, is to create Pli template which will generate this component for me.

First, let’s create following structure in `templates` directory:

```sh
# ├─ $COMPONENT_NAME$/
# │  ├─ $COMPONENT_NAME$.module.css
# │  ├─ $COMPONENT_NAME$.tsx

mkdir templates/$COMPONENT_NAME$
touch templates/$COMPONENT_NAME$/$COMPONENT_NAME$.module.css
touch templates/$COMPONENT_NAME$/$COMPONENT_NAME$.tsx
```

Now, we can fill the files with content, in my case it looks like this:

```css
/* templates/$COMPONENT_NAME$/$COMPONENT_NAME$.module.css */

.$NAME$Root {

}
```

```ts
// templates/$COMPONENT_NAME$/$COMPONENT_NAME$.tsx

import React, { FunctionComponent } from "react";
import styles from './$NAME$.module.css';

interface $NAME$Props {

}

export const $NAME$:FunctionComponent<$NAME$Props> = ({  }) => {

    return (
        <div className={styles.$NAME$Root}>
            Component $NAME$
        </>
    )
};
```

You can now run this template and it will create nice react component with it’s styles. One more thing we can improve is to add default output directory, so we won’t have to type `src/components` each time. To do it we need to add pli config file, you can do it easily by running `pli init -c` . File `pli.config.ts` will appear in current directory, to improve our template we will add to it following content:

```ts
import { Template, IConfig } from '@dawiidio/pli';

const config: IConfig = {
    templates: [
        new Template({
            // readable name, instead of "$COMPONENT_NAME$" you will see "React Component" in cli
            name: 'React Component',
            // if you want to extend from existing template in templates directory you need to provide its name
            id: '$COMPONENT_NAME$',
            // all will be generated relative to src/components directory
            defaultOutputDirectoryPath: 'src/components',
        })
    ]
}

export default config;
```

And that’s it! Our template for React component with css modules file in `src/componentsis` ready to run. After running it you should see the message like the below one, but with your component name (in my case is was `TestFilter`)

```txt
Following structure was created inside directory /myProject/src/components
├─ TestFilters/
│  ├─ TestFilters.module.css
│  ├─ TestFilters.tsx
```

Of course you may want to add some validation for variables, introduce new ones, create dynamic templates etc. If you want to learn more see the examples in repo https://github.com/dawiidio/pli/tree/main/examples

## Summary

Pli is a very simple but powerful tool, I hope it will help you maintaining your projects on daily basis. Also, as you may already noticed, Pli is language agnostic, so if you want to you can use it with any other language than just TS or JS. If you liked it or want to know more please visit the repo https://github.com/dawiidio/pli since Pli does not have the webpage as it’s own yet. Have a nice day ❤️