I decided to spend the week adding a code generation tool to the Web project automating a bit of the coding work while improving the developer experience.
In this article, I'll walk through the experience and the outcome of implementing a tool to generate code 👨💻
Table of Contents
- What is a code generator?
- What's the problem?
- Why you should use them?
- Using code generators
- Automate all the things!
What is a code generator?
A code generator is a tool that given a set of rules and inputs creates code, files, and folders.
To name a few popular ones 👇
All of them will create code based on specific rules taking into account the inputs provided by the user. Here's a simple example 👇
What's the problem?
Imagine, you start the day working on a new task and you need to create a feature, before writing any code you will need to consider a few things:
- Folder structure and architecture 📂
- Naming files convention 📑
- Where to put the feature 🗂
- How you should write the tests 🧪
I'm sure the project you're working on has a list of conventions and patterns defined that explains how you should work in the codebase.
However, every time you are going through this process it requires you to think 🤔 about those conventions to make the decision.
Where is the source of truth? 🧐
- Documentation 📝
- Architecture Decision Records 🏗
- Similar files on the codebase 🕵️
- A teammate 🧑💻
As software engineers we work very hard to not repeat code building abstractions, automating manual workflows...
What about writing code? In the same way, we advocate for automating processes such as deployments, we should also make an effort to the non-creative part of coding such as scaffolding.
Why you should use them?
Generating code will save you time ⏰ and will increase the productivity of the team 📈
In a team that is constantly growing it is important to make sure that everyone is aligned and able to build things efficiently.
Having a great Developer Experience will boost the confidence a developer has with the codebase.
Trust, empowers people to be more productive and agile ⚡️, to name a few of the many benefits you'll get by using generators:
- Ensure everyone is doing things "as expected" according to the project conventions 💖
- Reduce friction when working with the codebase 🤔
- Ease the onboarding of new joiners 🆕
- Decrease the development time 🚀
The most important thing is that your teammates will not have to spend time on low-value decisions, such as deciding how a component is structured.
Turns out our decision-making process gets worse the more decisions we make.
Using code generators
Sounds good right 😍? Let's take a look at how we can implement code generators in our project 👀
Choosing the right tool
I didn't want to reinvent the wheel, my focus was set on the outcome of generating code, not building a tool that solves this problem.
There are a lot of Open Source projects that will do an awesome job generating code. Here's the list of the ones I considered:
I decided to go with Hygen at N26 because:
- Great monorepo support
- Easy to maintain. You'll only need to care about
.EJStemplate files and prompts.
- No configuration required
- High value with low effort, writing a generator is very simple.
Plop is also a great tool but creating a generator is more complex since you need to spend more time writing code and the tool demands extra time on the configuration part compared to Hygen.
Yeoman is another valid option, but maintaining generators requires you to manage and publish packages to a registry and I would say the use-case of this tool is more suited to scaffolding projects instead of smaller parts of a codebase.
It's time to create our code generator 🥳. First, install Hygen as a devDependency in your project:
Define a script inside the
package.json to use the script binary:
Now we can run Hygen through the
After running the command, you'll see that Hygen is telling us we don't have any generators.
Error: please specify a generator.
By default, hygen will read the generator files from a folder named
If you want to change this behavior, create a file named
.hygen.js at the root level of your project, like this:
Creating a generator
A generator is composed of one or more actions, every action contains two items:
Let's build a simple generator that creates a React component 🤓. At the end of the post, you'll find a GitHub repository with a lot of different examples 👏
The first thing we need to create is the generator folder that will contain the action:
|The destination of the file once compiled.
|Use an external file as template.
|Overwrite existing files
|Execute the generator unless file already exists.
|Inject the contents into an existing file instead of creating a new one.
|Inject the template after the regex
|Inject the template before the regex
|Inject the template at the start of the file
|Inject the template at the end of the file
|Inject the template at the specified line number
|Skip injection if regex matches.
|Trim the newline from the end of the injection.
|Trigger a shell command after compiling the template
Now, let's add a template file named
index.ejs inside the
react action folder we created previously:
As I mentioned before, we want to create a React component, so we need to specify the location of the file where the component is going to be created.
We can do that using the
As you can see, we're using a variable called
name on the header. This value will be provided by the prompts of the generator ⁉️
Then, we need to write the body of the template, where we define the code that will be generated once the template is compiled. I'm reusing the
name variable in the body as well to create the name and export of the component ✨
In case you need to ask for user input, optionally you can use a prompt file. This is very useful to customize the output of the generator. Prompts are defined using a library named Enquirer.
Inside of the same
react 📁, we will create a
prompt.js file to ask for the variable defined as
name in the template:
There are a ton of different input types available 🔡, take a look at this link to get the complete list.
Now it's time to finally run our generator 🥳 using the script along with the name and the action:
$ npm run generators component react
You'll be asked for the prompts and finally the magic will happen! 🦄
Take a look at carloscuesta/codegenerators-demo 🕹 if you want to play and see more complex examples!
Automate all the things!
It's time for you to find out repetitive tasks and patterns to extract them into a generator! 🚀
I'm very happy with the productivity boost and the consistency that a tool like this can bring to a team ❤️
Enjoyed the article? 😍