A node CLI to start new projects
Avoiding else

If you can avoid else then it can simplify indentation. For example: 


if (!fs.existsSync(name)) {
    fs.mkdirSync(name);
} else {
    throw new Error(`directory ${name} already exist`);
}



The error can be thrown the error if the name exists, but if not just go ahead with the call to fs.mkdirSync():

if (fs.existsSync(name)) {
    throw new Error(`directory ${name} already exist`);
} 
fs.mkdirSync(name);


In some cases you may have to manually return or exit if the statement inside the first conditional doesn't return early or terminate the process - e.g. inside onCopyDone().

Use const instead of let when appropriate

It is wise to get in the habit of using const for any value that doesn't get re-assigned. Then if you need to have a variable that changes, switch to using let. This affects variables like result in the callback inside replaceInFile().

Arrow functions

The parentheses are not necessary on arrow functions with only one argument. Also, a single line doesn't need to have brackets - while this would lead to the return value of the statement getting returned, it shouldn't matter in most cases - so this:


i.stdout.on('data', (data) =&gt; {
    console.log(`stdout: ${data}`);
});



can be simplified to:

i.stdout.on('data', data =&gt; console.log(`stdout: ${data}`));