Top Related Projects
A gulp.js generator for modern webapps
The streaming scaffolding system - Gulp as a replacement for Yeoman
Consistency Made Simple
:zap: RAN! React . GraphQL . Next.js Toolkit :zap: - SEO-Ready, Production-Ready, SSR, Hot-Reload, CSS-in-JS, Caching, CLI commands and more...
node.js command-line interfaces made easy
Quick Overview
Hygen is a code generator that helps developers create new files and directories based on predefined templates. It is a powerful tool that can streamline the process of creating boilerplate code, ensuring consistency and reducing the time spent on repetitive tasks.
Pros
- Customizable Templates: Hygen allows developers to create their own templates, enabling them to generate code that aligns with their project's specific needs and coding conventions.
- Flexibility: The tool is language-agnostic, making it suitable for a wide range of projects, from web applications to mobile apps and beyond.
- Productivity Boost: By automating the creation of new files and directories, Hygen helps developers save time and focus on more important aspects of their work.
- Collaboration-Friendly: The template-based approach makes it easier for teams to maintain consistency and share best practices across the codebase.
Cons
- Learning Curve: While Hygen is relatively straightforward to use, the process of creating custom templates may require some initial effort and understanding of the tool's syntax and features.
- Potential Complexity: As the project grows and the number of templates increases, managing and maintaining the template library can become more challenging.
- Limited Ecosystem: Compared to some other code generation tools, Hygen may have a smaller ecosystem of pre-built templates and plugins, requiring more custom development.
- Dependency on Hygen: Projects that heavily rely on Hygen-generated code may become more tightly coupled to the tool, potentially making it more difficult to migrate to alternative solutions in the future.
Code Examples
Hygen is a code generation tool, so it does not have any runtime code examples. However, here are a few examples of Hygen templates and commands:
Creating a new React component
# _templates/component/new/index.ejs.t
---
to: src/components/<%= h.changeCase.pascal(name) %>/<%= h.changeCase.pascal(name) %>.js
---
import React from 'react';
const <%= h.changeCase.pascal(name) %> = () => {
return (
<div>
<%= h.changeCase.pascal(name) %>
</div>
);
};
export default <%= h.changeCase.pascal(name) %>;
This template generates a new React component file with the specified name.
Creating a new Mongoose model
# _templates/model/new/index.ejs.t
---
to: src/models/<%= h.changeCase.pascal(name) %>.js
---
const mongoose = require('mongoose');
const <%= h.changeCase.pascal(name) %>Schema = new mongoose.Schema({
// Add your schema fields here
});
module.exports = mongoose.model('<%= h.changeCase.pascal(name) %>', <%= h.changeCase.pascal(name) %>Schema);
This template generates a new Mongoose model file with the specified name.
Generating a new route
# _templates/route/new/index.ejs.t
---
to: src/routes/<%= h.changeCase.pascal(name) %>Route.js
---
const express = require('express');
const router = express.Router();
// Add your route handlers here
module.exports = router;
This template generates a new Express route file with the specified name.
Getting Started
To get started with Hygen, follow these steps:
-
Install Hygen globally using npm or yarn:
npm install -g hygen
or
yarn global add hygen
-
Create a new Hygen project in your working directory:
hygen init project
This will create a new
_templates
directory in your project, where you can start adding your custom templates. -
Create a new template for a specific use case, such as a React component or a Mongoose model. For example, to create a new React component template, run:
hygen component new
This will generate a new template file in the
_templates/component/new
directory. -
Customize the template to match your project's requirements. You can use Hygen's built-in helpers and variables to make the templates more dynamic and flexible.
-
To
Competitor Comparisons
A gulp.js generator for modern webapps
Pros of generator-webapp
- More comprehensive scaffolding for full web applications
- Integrates with Yeoman ecosystem for additional generators
- Includes built-in task runner (Gulp) for development workflow
Cons of generator-webapp
- Less flexible for custom code generation tasks
- Steeper learning curve due to Yeoman's complexity
- May generate unnecessary boilerplate for smaller projects
Code Comparison
generator-webapp (Yeoman):
module.exports = class extends Generator {
writing() {
this.fs.copy(
this.templatePath('index.html'),
this.destinationPath('app/index.html')
);
}
};
hygen:
---
to: app/index.html
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%= name %></title>
</head>
<body>
<!-- Content goes here -->
</body>
</html>
generator-webapp uses Yeoman's file system API to copy templates, while hygen uses a frontmatter approach with embedded templates. hygen's method is more concise and allows for easier customization of generated content.
generator-webapp is better suited for full-scale web applications with predefined structures, while hygen offers more flexibility for various code generation tasks across different project types.
The streaming scaffolding system - Gulp as a replacement for Yeoman
Pros of Slush
- More mature project with a larger community and ecosystem
- Supports multiple template engines (e.g., Swig, Handlebars, Lodash)
- Easier to integrate with existing Gulp workflows
Cons of Slush
- Less active development and maintenance
- More complex setup and configuration process
- Heavier dependency on Gulp, which may not be ideal for all projects
Code Comparison
Slush (generator creation):
var gulp = require('gulp');
var install = require('gulp-install');
var conflict = require('gulp-conflict');
var template = require('gulp-template');
gulp.task('default', function (done) {
// Slush generator logic
});
Hygen (generator creation):
module.exports = {
prompt: ({ inquirer }) => {
return inquirer.prompt([
// Hygen prompts
])
},
actions: [
// Hygen actions
]
}
Both Slush and Hygen are code generators, but they differ in their approach and implementation. Slush relies on Gulp and its ecosystem, making it more suitable for projects already using Gulp. Hygen, on the other hand, is a standalone tool with a more modern and streamlined approach to code generation. While Slush offers more flexibility in terms of template engines, Hygen provides a simpler and more intuitive way to create and manage generators. The choice between the two depends on your project's specific needs and existing tooling preferences.
Consistency Made Simple
Pros of Plop
- Simpler setup and configuration process
- Built-in prompts and inquirer integration
- Easier to use for beginners with less boilerplate code
Cons of Plop
- Less flexible templating system
- Limited support for complex file structures
- Fewer advanced features compared to Hygen
Code Comparison
Plop configuration:
module.exports = function (plop) {
plop.setGenerator('component', {
description: 'Create a new React component',
prompts: [{
type: 'input',
name: 'name',
message: 'Component name:'
}],
actions: [{
type: 'add',
path: 'src/components/{{pascalCase name}}.js',
templateFile: 'templates/component.hbs'
}]
});
};
Hygen configuration:
module.exports = {
helpers: {
capitalize: (str) => str.charAt(0).toUpperCase() + str.slice(1)
},
prompt: ({ inquirer }) => {
return inquirer.prompt([
{
type: 'input',
name: 'name',
message: 'Component name:'
}
])
},
actions: [
{
type: 'add',
path: 'src/components/{{capitalize name}}.js',
templateFile: 'templates/component.ejs'
}
]
}
Both Plop and Hygen are powerful code generators, but they cater to different needs. Plop is more straightforward and easier to set up, making it ideal for simpler projects or teams new to code generation. Hygen offers more flexibility and advanced features, suitable for complex projects with intricate file structures and custom logic requirements.
:zap: RAN! React . GraphQL . Next.js Toolkit :zap: - SEO-Ready, Production-Ready, SSR, Hot-Reload, CSS-in-JS, Caching, CLI commands and more...
Pros of ran
- Provides a complete boilerplate for React, Apollo, and Next.js applications
- Includes built-in authentication and user management features
- Offers a more opinionated and comprehensive starting point for full-stack applications
Cons of ran
- Less flexible and customizable compared to hygen's template-based approach
- May include unnecessary features or dependencies for simpler projects
- Steeper learning curve due to the complexity of the full-stack setup
Code comparison
ran (Next.js page example):
import withData from '../lib/withData'
import DefaultCon from '../containers/Default'
export default withData((props) => (
<DefaultCon title="Homepage" {...props} />
))
hygen (generator example):
---
to: app/models/<%= name %>.js
---
const <%= Name %> = {
name: '<%= Name %>',
// Add model properties here
}
module.exports = <%= Name %>
Summary
ran is a comprehensive boilerplate for full-stack React applications, offering a complete setup with authentication and user management. However, it may be less flexible for customization compared to hygen, which provides a more lightweight and adaptable code generation approach. The choice between the two depends on project requirements and developer preferences for opinionated setups versus flexible templating systems.
node.js command-line interfaces made easy
Pros of Commander.js
- More mature and widely adopted, with a larger community and ecosystem
- Focused specifically on command-line argument parsing and option handling
- Lightweight and easy to integrate into existing Node.js projects
Cons of Commander.js
- Limited to command-line interface (CLI) functionality
- Requires more manual setup for complex command structures
- Less opinionated, which may lead to inconsistent CLI designs across projects
Code Comparison
Commander.js:
const program = require('commander');
program
.option('-d, --debug', 'output extra debugging')
.option('-s, --small', 'small pizza size')
.parse(process.argv);
Hygen:
module.exports = {
prompt: ({ inquirer }) => {
return inquirer.prompt([
{
type: 'input',
name: 'name',
message: "What's your name?"
}
])
}
}
Summary
Commander.js is a popular choice for building Node.js command-line interfaces, offering robust argument parsing and option handling. It's lightweight and widely adopted but focuses solely on CLI functionality. Hygen, on the other hand, is a code generator that provides a more comprehensive approach to project scaffolding and template-based code generation. While Commander.js excels in CLI argument parsing, Hygen offers a broader set of features for generating and managing project structures.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
hygen
is the simple, fast, and scalable code generator that lives in your project.
Features
- â Build ad-hoc generators quickly and full on project scaffolds.
- â Local generators per project (and global, if you must)
- â Built-in scaffolds to quickly create generators
- â Full logic templates and rendering
- â Prompts and flows for taking in arguments
- â Automatic CLI arguments
- â Adding new files
- â Injecting into existing files
- â Running shell commands
- â Super fast, constantly optimized for speed
New in hygen v4.0.0: a positional
NAME
parameter. Now you can use$ hygen component new MyComponent
instead of$ hygen component new --name MyComponent
.
Used By
Quick Start
Hygen can be used to supercharge your workflow with Redux, React Native, Express and more, by allowing you avoid manual work and generate, add, inject and perform custom operations on your codebase.
If you're on macOS and have Homebrew:
$ brew tap jondot/tap
$ brew install hygen
If you have node.js installed, you can install globally with npm
(or Yarn):
$ npm i -g hygen
If you like a no-strings-attached approach, you can use npx
without installing globally:
$ npx hygen ...
For other platforms, see releases.
Initialize hygen
in your project (do this once per project):
$ cd your-project
$ hygen init self
Build your first generator, called mygen
:
$ hygen generator new mygen
Loaded templates: _templates
added: _templates/mygen/new/hello.ejs.t
Now you can use it:
$ hygen mygen new
Loaded templates: _templates
added: app/hello.js
You've generated content into the current working directory in app/
. To see how the generator is built, look at _templates
(which you should check-in to your project from now on, by the way).
You can build a generator that uses an interactive prompt to fill in a variable:
$ hygen generator with-prompt mygen
Loaded templates: _templates
added: _templates/mygen/with-prompt/hello.ejs.t
added: _templates/mygen/with-prompt/prompt.js
Done! Now let's use mygen
:
$ hygen mygen with-prompt
? What's your message? hello
Loaded templates: _templates
added: app/hello.js
Use a template repo
Want to start from a repo?
$ hygen init repo antfu/vitesse --to my-folder
Want to start from an existing repo on an existing project?
$ mkdir your-project && cd your-project
$ hygen init repo antfu/vitesse
What's Next?
Go to the documentation to get to know the rest of Hygen and generators.
If you're in a hurry:
- To learn how to edit generator templates, look here
- To see how to use generators look here
- Take a look at the ecosystem and tooling built around Hygen.
A Different Kind of a Generator
hygen
is a scalable generator. It has developer and team ergonomics as first priority.
It avoids "blessed" or dedicated projects that codifies code generation, which before you know it, become a product you build, needs testing, CI, separate pull request reviews, and ultimately sucks up your time and becomes this super hated thing no one likes to touch anymore.
Plus, since they are not the product you are building they become notoriously hard to reason about.
Scratch Your Own Itch
Because hygen
templates live in your project, it cuts the time from having an itch for generating code (Redux, anyone?) in your current
project to code generated with it and others benefiting from it.
Template Locality
hygen
picks up a local _templates
folder
at any folder level of your project you're working from.
This is important because:
- Templates are project-local. A git clone of the project fetches all generators as well.
- Different generators can be tucked in different parts of the project, making it contextual.
- Template locality is scalable; different teams can maintain different generators.
- When you change your code, you can make changes in the template and pack in the same commit, to be reviewed and merged in the same PR (as opposed to installing different "plugins" or different templates from out-of-repo places).
And yet, if you don't like project-local templates:
- You can have a global
_templates
folder (maybe a central git repo you maintain?) by populating an environment variableHYGEN_TMPLS
- You can build a custom generator of your own with
hygen
at its core, and pack your own templates with it.
Folder Structure is Command Structure
The templates folder structure maps directly to the command structure:
$ hygen worker new jobrunner
For this command, hygen worker new
maps to _templates/worker/new
and all files within worker/new
are rendered.
Template parameters are given with --flag VALUE
, as many as you'd like. In this example we've set a parameter named name
to the value jobrunner
.
Subcommands
A subcommand is a file inside a your folder structure. So if the structure is this:
_templates/
worker/
new/
index.html.ejs
setup.html.ejs
And you only want setup
, you can run:
$ hygen worker new:setup
You can also use the subcommand as a regular expression so, these will do the same:
$ hygen worker new:se
$ hygen worker new:se.*
Frontmatter for Decluttering
Here's how a template looks like (in our example, index.ejs.t
). Templates bodies are ejs:
---
to: app/workers/<%=name%>.js
---
class <%= h.capitalize(name) %> {
work(){
// your code here!
}
}
The first part of the template is a front matter, idea borrowed from Markdown, this is the metadata part of a hygen
template and is part of the reason of why your templates will feel more lightweight and flexible.
All frontmatter metadata are also run through the template engine so feel free to use variables in the frontmatter as you wish.
There's one required metadata variable: to
.
to
points to where this file will be placed (folders are created as needed).
Case changing
hygen
provides ability to semantic case changing with change-case
library, it's simple to use and very easy to understand.
There is a usecase for react based components generation:
---
to: components/<%= name %>/index.jsx
---
import React from 'react'
export const <%= name %> = ({ children }) => (
<div className="<%= h.changeCase.paramCase(name) %>">{children}</div>"
)
With name HelloWorld
will be compiled to:
import React from 'react'
export const HelloWorld = ({ children }) => (
<div className="hello-world">{children}</div>"
)
You can see the full list here.
Addition, Injection, and More
By default templates are 'added' to your project as a new target file, but you can also choose to inject a template into an existing target file.
For this to work, you need to use inject: true
with the accompanied inject-specific props.
---
to: package.json
inject: true
after: dependencies
skip_if: react-native-fs
---
"react-native-fs":"*",
This template will add the react-native-fs
dependency into a package.json
file, but it will not add it twice (see skip_if
).
Here are the available mutually-exclusive options for where to inject at:
before | after
- a regular expression / text to locate. The inject line will appear before or after the located line.prepend | append
- add a line to start or end of file respectively.line_at
- add a line at this exact line number.
You can guard against double injection:
skip_if
- a regular expression / text. If exists injection is skipped.
Also you can insert or remove empty line to injection body. That feature very useful if your editor or formatter automatically insert blank line at the end of file on save:
eof_last
- if falsy - trim blank line from the end of injection body, if truthy - insert it.
Build Your Own
hygen
is highly embeddable. You should be able to use it by simply listing it
as a dependency and having this kind of workflow in your binary.
const { runner } = require('hygen')
const Logger = require('hygen/dist/logger')
const path = require('path')
const defaultTemplates = path.join(__dirname, 'templates')
runner(process.argv.slice(2), {
templates: defaultTemplates,
cwd: process.cwd(),
logger: new Logger.default(console.log.bind(console)),
createPrompter: () => require('enquirer'),
exec: (action, body) => {
const opts = body && body.length > 0 ? { input: body } : {}
return require('execa').shell(action, opts)
},
debug: !!process.env.DEBUG
})
Development
The Hygen codebase has a functional style where possible. This is because naturally, it feeds parameters and spits out files. Try to keep it that way.
Running hygen
locally, rigged to your current codebase (note the additional --
to allow passing flags)
$ yarn hygen -- mailer new foobar
Running tests in watch mode:
$ yarn watch
Metaverse Testing
The easiest way to make an impact is to use the built-in metaverse
tests suite, and then add the tests here.
The idea here is to copy templates from any project that use hygen
and to test that it works at all times. This keeps tabs on the hygen universe / ecosystem (nicknamed metaverse) and makes sure this test suite breaks before hygen
clients break.
Internal Testing
Start Up Speed Testing
Many generators become painfully slow to use as the thing you want to generate grow (because, real life),
This is why hygen
takes speed as a first class citizen, and sports a dedicated start-up timing suite:
$ yarn test:require
In addition, thought is given to which dependencies to take in, how their file structure fan out and what kind of disk access (due to require
) would hygen
ultimately have when we run it. This is recorded with every test run.
Bundling a single file was evaluated (and the infrastructure is still there, using webpack
) and wasn't faster than what we have right now.
Contributing
Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).
Thanks:
To all Contributors - you make this happen, thanks!
Copyright
Copyright (c) 2018 Dotan Nahum @jondot. See LICENSE for further details.
Top Related Projects
A gulp.js generator for modern webapps
The streaming scaffolding system - Gulp as a replacement for Yeoman
Consistency Made Simple
:zap: RAN! React . GraphQL . Next.js Toolkit :zap: - SEO-Ready, Production-Ready, SSR, Hot-Reload, CSS-in-JS, Caching, CLI commands and more...
node.js command-line interfaces made easy
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot