Have you ever wanted to create your own frontend scaffolding tool — just like create-react-app
, but tailored to your stack and preferences? In this guide, I'll show you how to build a CLI tool called create-frontend-site that prompts users, clones templates, installs dependencies, and gets projects ready to roll. Let’s dive in!
🔧 Step 1: Initialize Your Project
Start by setting up a basic Node.js project:
mkdir create-frontend-site
cd create-frontend-site
npm init -y
Install the CLI essentials:
npm install inquirer commander chalk
🧠 Step 2: Create the CLI Script
Create a file named index.js
:
#!/usr/bin/env node
const inquirer = require("inquirer");
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const chalk = require("chalk");
async function main() {
console.log(chalk.blue("🚀 Welcome to create-frontend-site!"));
const answers = await inquirer.prompt([
{
type: "input",
name: "projectName",
message: "Project name:",
},
{
type: "list",
name: "framework",
message: "Choose your framework:",
choices: ["React", "Vue", "Svelte"],
},
{
type: "confirm",
name: "typescript",
message: "Use TypeScript?",
default: true,
},
]);
const targetDir = path.join(process.cwd(), answers.projectName);
const templateDir = path.join(__dirname, "templates", answers.framework.toLowerCase(), answers.typescript ? "ts" : "js");
if (!fs.existsSync(templateDir)) {
console.error(chalk.red("❌ Template not found for that combo."));
process.exit(1);
}
fs.mkdirSync(targetDir, { recursive: true });
fs.cpSync(templateDir, targetDir, { recursive: true });
console.log(chalk.yellow("📦 Installing dependencies..."));
execSync("npm install", { cwd: targetDir, stdio: "inherit" });
console.log(chalk.green("\n✅ Project is ready!"));
console.log(\\nNext steps:\\n cd ${answers.projectName}\\n npm run dev
);
}
main();
Make the script executable:
chmod +x index.js
📁 Step 3: Add Template Projects
Inside your project folder, create a structure like this:
templates/
├── react/
│ ├── js/
│ │ └── package.json, index.html, src/
│ └── ts/
├── vue/
├── svelte/
Each subfolder should be a minimal starter template. Here’s an example for react/js/package.json
:
{
"name": "frontend-app",
"scripts": {
"dev": "vite"
},
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"vite": "^4.0.0"
}
}
📦 Step 4: Setup package.json
for CLI
Update your root package.json
:
{
"name": "create-frontend-site",
"version": "1.0.0",
"description": "Scaffold your custom frontend app",
"bin": {
"create-frontend-site": "./index.js"
},
"keywords": ["cli", "scaffold", "frontend", "template"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"chalk": "^5.0.0",
"commander": "^10.0.0",
"inquirer": "^9.0.0"
}
}
🚀 Step 5: Publish to npm
Login and publish your package:
npm login
npm publish --access public
Once published, users can run:
npx create-frontend-site
🎉 You now have your own frontend scaffolding CLI!
🔄 Optional Improvements
- Use
ejs
templates for file customization. - Add Git init and first commit.
- Support mono-repo setups.
- Add plugins or themes system.
💬 Final Thoughts
Creating a custom scaffolding tool is a game-changer for teams and personal projects. Whether you want to enforce standards or boost your speed, building your own CLI is surprisingly straightforward — and super fun.
If this post helped you, consider supporting me: buymeacoffee.com/hexshift