Generate project READMEs (or other files!) quickly from custom templates using an interactive CLI. Supports variable substitution, conditional content blocks, follow-up questions, and custom multi-select separators.
Report Bug
·
Request Feature
Table of Contents
@aditsuru/readme-gen
is a command-line tool designed to streamline the creation of README files (or any text-based boilerplate) for your projects. It works by processing a template file (.md
) and interactively asking you questions defined in a corresponding configuration file (.json
). Your answers are then injected into the template, conditional blocks are processed, follow-up questions can be asked based on previous answers, and multi-select answers can be joined with custom separators, to produce the final output file.
It supports using local template files, fetching templates from public GitHub repositories, saving configurations for quick reuse, and comes with a built-in default README template.
Get up and running with readme-gen
quickly.
Ensure you have Node.js (v16 or higher recommended) and npm installed.
node -v
npm -v
You can use the tool directly with npx
without installation, or install it globally.
- Using npx (Recommended for one-off use)
npx @aditsuru/readme-gen [base_source] [options]
- Global Installation
After global installation, you can use the
npm install -g @aditsuru/readme-gen
readme-gen
command directly.
The tool has two main functions: generating files and managing saved template configurations.
This is the primary command for creating a file from a template.
Basic Syntax:
# Using npx
npx @aditsuru/readme-gen [base_source] [options]
# Or globally installed
readme-gen [base_source] [options]
Arguments & Options:
[base_source]
(Optional Positional Argument):- Path to a local directory or a public GitHub repository URL containing the template files.
- If provided, the tool expects
readme-template.md
andreadme-config.json
inside this source.
- Source Options (Choose ONE method if not using
[base_source]
):-t, --template <source>
: Path or URL to the template file (requires-c
).-c, --config <source>
: Path or URL to the config file (requires-t
).-n, --name <name>
: Use a saved template configuration by name (see Managing Templates).
- Output Option:
-o, --output <path>
: Path to save the generated file.- Default:
./README.md
in the current working directory.
- Default:
Source Priority & Examples:
The tool determines which template/config to use based on this priority:
-
Explicit Sources (Flags):
-t
and-c
together. Highest priority.# Local files, default output path (./README.md) readme-gen -t ./path/to/template.md -c ./path/to/config.json # URLs, specific output path readme-gen -t <template_url> -c <config_url> -o docs/GENERATED.md # Mixed, specific output path readme-gen -t ./local-tmpl.md -c <config_url> -o my-output.txt
-
Saved Name (Flag):
-n
flag.# Use saved config 'my-setup', output to specific path readme-gen -n my-setup -o project/README.md # Use saved config 'my-repo', default output path readme-gen -n my-repo
-
Base Source (Argument): Positional argument.
# Local directory, default output path readme-gen ./my-template-folder # GitHub Repo URL, specific output path # (Expects https://raw.githubusercontent.com/user/repo/main/readme-template.md etc.) readme-gen https://github.com/user/repo -o README_generated.md
-
User-Set Default: If you've set a default using
template default
, and no source flags or arguments are given.# Uses your saved default template, outputs to ./README.md readme-gen # Uses your saved default template, outputs to specific path readme-gen -o ../README.md
-
Built-in Default: Lowest priority. Used if no other sources are specified and no user default is set.
# Uses the built-in template, outputs to ./README.md readme-gen # Uses the built-in template, outputs to specific path readme-gen -o my-project/README.md
Conflicting Sources: Providing more than one sourcing method (e.g., using -n
and also providing a [base_source]
) will result in an error.
Save and manage your template configurations for easy reuse.
Syntax:
readme-gen template <command> [args...]
Commands:
-
add <name> <source...>
-
Saves a template configuration with a unique name.
-
Provide one source for 'base' type (local dir path or repo URL):
# Save template from local directory readme-gen template add my-local-base ./path/to/template_dir # Save template from GitHub repo readme-gen template add my-gh-repo https://github.com/user/repo
-
Provide two sources for 'explicit' type (template source and config source):
# Save explicit local files readme-gen template add my-explicit-files ./tmpl.md ./conf.json # Save explicit remote URLs readme-gen template add my-remote-files <tmpl_url> <conf_url>
-
Note: Local paths are saved as absolute paths. The first template added automatically becomes the default.
-
-
list
(aliasls
)- Shows all saved user templates and indicates the current default.
-
readme-gen template list
-
remove <name>
(aliasrm
)- Deletes a saved template configuration.
-
readme-gen template remove my-explicit-files
-
default <name>
- Sets a previously saved template as the default to be used when no other source is specified during generation.
-
readme-gen template default my-gh-repo
To use your own templates, create two files:
-
Template File (
.md
or any text format):- This is your blueprint file (e.g.,
readme-template.md
). - It can contain standard text and Markdown.
- Use placeholders for variable substitution and conditional blocks for optional content.
-
Use the format
${variableName}
where you want values inserted. -
The
variableName
must exactly match aname
defined in your config file's prompts. -
For
multiselect
answers, the values will be joined by,
by default, or by the customseparator
if defined in the config. -
Example:
# ${projectName} Author: ${authorName} License: ${chosenLicense} Includes Tests: ${includeTests} Features: ${selectedFeatures} <!-- selectedFeatures might become "lint, format, testing" --> Tags: ${selectedTags} <!-- selectedTags might become "#tag1\n#tag2" if separator is "\n" -->
-
Use HTML-style comments to wrap content that should only be included if a specific variable (typically from a
confirm
prompt) istrue
. -
Syntax:
<!-- IF:{booleanVariableName} --> This content is only included if 'booleanVariableName' is true. You can use other variables like ${projectName} inside here too. <!-- ENDIF:{booleanVariableName} -->
-
Behavior:
- If
booleanVariableName
exists in the answers and istrue
, the<!-- IF -->
and<!-- ENDIF -->
tags are removed, and the content between them is kept. - If
booleanVariableName
isfalse
, or if it's not defined in the config, or if its value is not a boolean type, the entire block (including the tags and the content inside) is removed.
- If
-
Example:
<!-- IF:{includeLicenseSection} --> ## License This project uses the ${chosenLicense} license. <!-- ENDIF:{includeLicenseSection} -->
- This is your blueprint file (e.g.,
-
Configuration File (
.json
):- This file defines the questions the CLI will ask (e.g.,
readme-config.json
). - It MUST contain a root object with a single key:
"prompts"
. - The value of
"prompts"
MUST be an array of prompt objects.
-
You can make a prompt appear only if a previous prompt was answered with a specific value.
-
To do this, add two optional properties to the prompt object you want to make conditional:
dependsOn
(string, required ifshowIf
is used): Thename
of the prompt this one depends on. This parent prompt MUST be defined earlier in the"prompts"
array.showIf
(any, required ifdependsOn
is used): The exact value (checked using===
) that the parent prompt's answer must have for this follow-up prompt to be shown.
-
If the condition is not met (parent prompt wasn't answered or the answer doesn't match
showIf
), the follow-up prompt is skipped entirely. -
Example (
my-config.json
):{ "prompts": [ // Parent prompt { "name": "deployChoice", "type": "select", "message": "Choose deployment target:", "options": ["AWS", "GCP", "Manual"] }, // Follow-up 1: Only shown if deployChoice === "AWS" { "name": "awsRegion", "type": "select", "message": "Select AWS Region:", "options": ["us-east-1", "eu-west-2"], "dependsOn": "deployChoice", "showIf": "AWS" }, // Follow-up 2: Only shown if deployChoice === "Manual" { "name": "manualSteps", "type": "text", "message": "Describe manual steps:", "dependsOn": "deployChoice", "showIf": "Manual" }, // Standard prompt, always shown { "name": "projectName", "type": "text", "message": "Project Name:" } ] }
- This file defines the questions the CLI will ask (e.g.,
Each object inside the "prompts"
array defines one question. Besides the optional dependsOn
and showIf
, it must have name
, type
, and message
. Other properties are optional depending on the type.
-
Common Properties:
name
(string, required): The variable name used in the template (e.g.,${projectName}
or for<!-- IF:{includeLicenseSection} -->
).type
(string, required): The type of prompt. See below.message
(string, required): The question text shown to the user.initialValue
(any, optional): A default value pre-filled or pre-selected.required
(boolean, optional): Fortext
andmultiselect
, enforces input/selection.dependsOn
(string, optional): See Follow-up Questions.showIf
(any, optional): See Follow-up Questions.
-
Prompt
type
Details:-
text
: For freeform text input.-
placeholder
(string, optional): Dimmed text shown when the input is empty. -
required
(boolean, optional): If true, user cannot submit an empty value. -
Example:
{ "name": "projectName", "type": "text", "message": "Enter project name:", "placeholder": "My Cool App", "required": true }
-
-
confirm
: For Yes/No questions. Returnstrue
orfalse
. Often used as the parent prompt for follow-ups or for<!-- IF: -->
blocks.-
initialValue
(boolean, optional): Default state (true
=Yes,false
=No). Defaults tofalse
. -
Example:
{ "name": "includeLicenseSection", "type": "confirm", "message": "Include a license section in the README?", "initialValue": true }
-
-
select
: For choosing a single option from a list. Returns thevalue
of the chosen option. Can be used as a parent for follow-ups based on the selectedvalue
.-
options
(array, required): List of choices. Can be:- An array of strings:
["MIT", "Apache", "GPL"]
(value and label are the same). - An array of objects:
[{ "value": "mit", "label": "MIT License", "hint": "Permissive" }, ...]
- An array of strings:
-
initialValue
(any, optional): Thevalue
of the option to select by default. -
Example:
{ "name": "chosenLicense", "type": "select", "message": "Choose a license:", "initialValue": "mit", "options": [ { "value": "mit", "label": "MIT", "hint": "Permissive" }, { "value": "gpl", "label": "GPLv3", "hint": "Copyleft" }, "Unlicensed" ] }
-
-
multiselect
: For choosing multiple options from a list. Returns an array of thevalue
s of chosen options.-
options
(array, required): Same format asselect
. -
required
(boolean, optional): If true, user must select at least one option. -
initialValue
(array, optional): An array ofvalue
s to select by default. -
separator
(string, optional): The string used to join the selected values when replacing the corresponding${variable}
placeholder in the template. Defaults to", "
. -
Example:
{ "name": "selectedTags", "type": "multiselect", "message": "Select tags:", "options": ["#tag1", "#tag2", "#tag3"], "separator": "\n" // Join tags with newlines in the output }
{ "name": "selectedFeatures", "type": "multiselect", "message": "Select features:", "options": ["Linting", "Formatting", "Testing"] // No separator: defaults to ", " => "Linting, Formatting, Testing" }
-
-
Contributions are welcome! Please fork the repository and create a pull request or open an issue.
- Fork the Project (
https://github.com/aditsuru-git/readme-gen/fork
) - Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
file for more information.
- @clack/prompts
- Commander.js
- Conf
- Picocolors
- node-fetch
- latest-version
- semver
- README Template inspired by Best-README-Template