Skip to content

Commit e9c1c97

Browse files
committed
Initialize quick-react CLI tool with interactive setup, project structure, and CSS framework integration
0 parents  commit e9c1c97

File tree

4 files changed

+303
-0
lines changed

4 files changed

+303
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
package-lock.json

index.js

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env node
2+
3+
4+
import inquirer from "inquirer";
5+
import { execSync } from "child_process";
6+
import path from "path";
7+
import fs from "fs";
8+
// const { execSync } = require("child_process");
9+
// const path = require("path");
10+
// const fs = require("fs");
11+
// const inquirer = require("inquirer");
12+
13+
14+
const run = (cmd, cwd = process.cwd()) => {
15+
console.log(`\n📦 Running: ${cmd}`);
16+
execSync(cmd, { stdio: "inherit", cwd });
17+
};
18+
19+
(async () => {
20+
// 1. Ask project name
21+
const { projectName } = await inquirer.prompt([
22+
{ type: "input", name: "projectName", message: "Enter project name:" }
23+
]);
24+
25+
// 2. Ask for CSS framework
26+
const { cssFramework } = await inquirer.prompt([
27+
{
28+
type: "list",
29+
name: "cssFramework",
30+
message: "Choose a CSS framework:",
31+
choices: ["Tailwind", "Bootstrap", "MUI"]
32+
}
33+
]);
34+
35+
// 3. Ask optional packages
36+
const { packages } = await inquirer.prompt([
37+
{
38+
type: "checkbox",
39+
name: "packages",
40+
message: "Select optional packages:",
41+
choices: [
42+
{ name: "Axios", value: "axios" },
43+
{ name: "React Icons", value: "react-icons" },
44+
{ name: "React Hook Form", value: "react-hook-form" },
45+
{ name: "Yup", value: "yup" },
46+
{ name: "Formik", value: "formik" },
47+
{ name: "Moment.js", value: "moment" }
48+
]
49+
}
50+
]);
51+
52+
// 4. Create Vite + React project
53+
run(`npm create vite@latest ${projectName} -- --template react`);
54+
const projectPath = path.join(process.cwd(), projectName);
55+
56+
// 5. Install chosen CSS framework
57+
if (cssFramework === "Tailwind") {
58+
run(`npm install tailwindcss @tailwindcss/vite`, projectPath);
59+
60+
const viteConfigPath = path.join(projectPath, "vite.config.js");
61+
let viteConfig = fs.readFileSync(viteConfigPath, "utf-8");
62+
viteConfig = `import tailwindcss from '@tailwindcss/vite'\n` + viteConfig;
63+
viteConfig = viteConfig.replace(/plugins:\s*\[/, "plugins: [\n tailwindcss(),");
64+
fs.writeFileSync(viteConfigPath, viteConfig);
65+
66+
fs.writeFileSync(path.join(projectPath, "src", "index.css"), `@import "tailwindcss";\n`);
67+
68+
const mainFile = fs.existsSync(path.join(projectPath, "src/main.jsx"))
69+
? "src/main.jsx"
70+
: "src/main.tsx";
71+
const mainPath = path.join(projectPath, mainFile);
72+
let mainContent = fs.readFileSync(mainPath, "utf-8");
73+
mainContent = mainContent.replace(/import\s+['"]\.\/index\.css['"];?/g, ""); // remove default CSS import
74+
if (!mainContent.includes(`import './index.css'`)) {
75+
mainContent = `import './index.css';\n` + mainContent;
76+
}
77+
fs.writeFileSync(mainPath, mainContent);
78+
} else if (cssFramework === "Bootstrap") {
79+
run(`npm install bootstrap`, projectPath);
80+
const mainFile = fs.existsSync(path.join(projectPath, "src/main.jsx"))
81+
? "src/main.jsx"
82+
: "src/main.tsx";
83+
const mainPath = path.join(projectPath, mainFile);
84+
let mainContent = fs.readFileSync(mainPath, "utf-8");
85+
mainContent = mainContent
86+
.replace(/import\s+['"]\.\/index\.css['"];?/g, "") // remove vite css import
87+
.replace(/import\s+['"]\.\/App\.css['"];?/g, ""); // remove App.css import
88+
mainContent = `import 'bootstrap/dist/css/bootstrap.min.css';\n` + mainContent;
89+
fs.writeFileSync(mainPath, mainContent);
90+
} else if (cssFramework === "MUI") {
91+
run(`npm install @mui/material @emotion/react @emotion/styled`, projectPath);
92+
const mainFile = fs.existsSync(path.join(projectPath, "src/main.jsx"))
93+
? "src/main.jsx"
94+
: "src/main.tsx";
95+
const mainPath = path.join(projectPath, mainFile);
96+
let mainContent = fs.readFileSync(mainPath, "utf-8");
97+
mainContent = mainContent
98+
.replace(/import\s+['"]\.\/index\.css['"];?/g, "")
99+
.replace(/import\s+['"]\.\/App\.css['"];?/g, "");
100+
fs.writeFileSync(mainPath, mainContent);
101+
}
102+
103+
// 6. Install optional packages
104+
if (packages.length > 0) {
105+
run(`npm install ${packages.join(" ")}`, projectPath);
106+
}
107+
108+
// 7. Create folder structure
109+
const folders = ["components", "pages", "hooks", "store", "utils", "assets"];
110+
folders.forEach((folder) => {
111+
fs.mkdirSync(path.join(projectPath, "src", folder), { recursive: true });
112+
});
113+
114+
// 8. Axios setup if chosen
115+
if (packages.includes("axios")) {
116+
const axiosContent = `import axios from "axios";
117+
118+
export const api = axios.create({
119+
baseURL: import.meta.env.VITE_API_URL || "http://localhost:5000",
120+
headers: { "Content-Type": "application/json" }
121+
});
122+
`;
123+
fs.writeFileSync(path.join(projectPath, "src", "utils", "axiosInstance.js"), axiosContent);
124+
}
125+
126+
// 9. Clean up default CSS files from Vite
127+
const appCssPath = path.join(projectPath, "src", "App.css");
128+
if (fs.existsSync(appCssPath)) fs.unlinkSync(appCssPath);
129+
130+
const appFile = fs.existsSync(path.join(projectPath, "src/App.jsx"))
131+
? path.join(projectPath, "src/App.jsx")
132+
: path.join(projectPath, "src/App.tsx");
133+
134+
let appContent = fs.readFileSync(appFile, "utf-8");
135+
appContent = appContent.replace(/import\s+['"]\.\/App\.css['"];?/g, ""); // remove App.css import
136+
appContent = `export default function App() {
137+
return (
138+
<div
139+
style={{
140+
display: "flex",
141+
flexDirection: "column",
142+
justifyContent: "center",
143+
alignItems: "center",
144+
height: "100vh",
145+
fontFamily: "sans-serif",
146+
background: "#f9fafb",
147+
color: "#111",
148+
textAlign: "center",
149+
}}
150+
>
151+
<h1
152+
style={{
153+
fontSize: "2.5rem",
154+
marginBottom: "0.5rem",
155+
fontWeight: 600,
156+
}}
157+
>
158+
Welcome to{" "}
159+
<span style={{ color: "#2563eb" }}>${projectName}</span> 🚀
160+
</h1>
161+
<p style={{ fontSize: "1.1rem", color: "#555" }}>
162+
Your project is ready. Start building amazing things!
163+
</p>
164+
</div>
165+
);
166+
}
167+
`;
168+
fs.writeFileSync(appFile, appContent);
169+
170+
console.log("\n✅ Setup complete!");
171+
console.log(`\nNext steps:\n cd ${projectName}\n npm run dev`);
172+
})();

package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "quick-react",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"type": "module",
7+
"scripts": {
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"bin": {
11+
"quick-react": "index.js"
12+
},
13+
"keywords": [],
14+
"author": "",
15+
"license": "ISC",
16+
"dependencies": {
17+
"inquirer": "^9.2.7"
18+
}
19+
}

readme.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# quick-react (React Package Solution)
2+
3+
🚀 **quick-react** is an open-source CLI tool that lets you instantly create a Vite + React app with your choice of CSS framework, optional packages, and pre-configured project structure — all in one command.
4+
5+
## ✨ Features
6+
- **Interactive Setup** — prompts you for project name, CSS framework, and optional packages
7+
- **CSS Framework Support** — Tailwind CSS, Bootstrap, or MUI (Material UI)
8+
- **Optional Packages** — easily add Axios, React Icons, React Hook Form, Yup, Formik, and Moment.js
9+
- **Automatic Folder Structure** — creates `components`, `pages`, `hooks`, `store`, `utils`, `assets` folders
10+
- **Boilerplate Ready** — replaces default Vite boilerplate with a clean welcome page
11+
- **Axios Setup** — pre-configured Axios instance if selected
12+
- **CSS Integration** — automatically configures your chosen CSS framework with Vite
13+
14+
## 📦 Installation
15+
You don’t need to install it globally — run it instantly with `npx`:
16+
```bash
17+
npx quick-react
18+
```
19+
20+
## 🛠 Usage
21+
When you run `npx quick-react`, you will be prompted to:
22+
1. **Enter Project Name** — e.g., `my-app`
23+
2. **Choose CSS Framework** — Tailwind, Bootstrap, or MUI
24+
3. **Select Optional Packages** — choose from a list of commonly used React libraries
25+
26+
Example run:
27+
```bash
28+
npx quick-react
29+
```
30+
31+
### Example Walkthrough
32+
```
33+
? Enter project name: my-portfolio
34+
? Choose a CSS framework: Tailwind
35+
? Select optional packages: Axios, React Icons
36+
```
37+
38+
This will:
39+
- Create a new Vite + React project in `my-portfolio/`
40+
- Install Tailwind CSS and configure it with Vite
41+
- Install Axios and React Icons
42+
- Create standard project folders
43+
- Add a clean welcome screen
44+
- Set up an Axios instance at `src/utils/axiosInstance.js`
45+
46+
## 📂 Folder Structure
47+
After running, your project will look like this:
48+
```
49+
my-app/
50+
├── src/
51+
│ ├── components/
52+
│ ├── pages/
53+
│ ├── hooks/
54+
│ ├── store/
55+
│ ├── utils/
56+
│ │ └── axiosInstance.js (if Axios selected)
57+
│ ├── assets/
58+
│ ├── App.jsx
59+
│ ├── index.css
60+
│ └── main.jsx
61+
├── vite.config.js
62+
├── package.json
63+
└── README.md
64+
```
65+
66+
## ⚡ CSS Framework Integration
67+
### Tailwind CSS
68+
- Installs `tailwindcss` & `@tailwindcss/vite`
69+
- Updates `vite.config.js` to use Tailwind plugin
70+
- Sets up `index.css` with Tailwind directives
71+
- Removes unused default CSS files
72+
73+
### Bootstrap
74+
- Installs `bootstrap`
75+
- Imports Bootstrap CSS in `main.jsx`
76+
- Removes unused default CSS files
77+
78+
### MUI (Material UI)
79+
- Installs `@mui/material`, `@emotion/react`, `@emotion/styled`
80+
- Removes unused default CSS files
81+
82+
## 🧩 Optional Packages
83+
You can add these during setup:
84+
- **Axios** — with a ready-to-use `axiosInstance.js`
85+
- **React Icons** — icon library
86+
- **React Hook Form** — form management
87+
- **Yup** — schema validation
88+
- **Formik** — form management
89+
- **Moment.js** — date/time utilities
90+
91+
## 🚀 Quick Start
92+
```bash
93+
npx quick-react my-dashboard
94+
```
95+
Select Tailwind, Bootstrap, or MUI, add any packages, and start coding immediately.
96+
97+
## 👐 Contributing
98+
We welcome contributions! Follow these steps:
99+
1. Fork the repository
100+
2. Create a new branch: `git checkout -b feature-name`
101+
3. Commit your changes: `git commit -m "Added new feature"`
102+
4. Push to your branch: `git push origin feature-name`
103+
5. Open a Pull Request
104+
105+
Before submitting, please ensure:
106+
- Your code follows project style guidelines
107+
- You have tested your changes locally
108+
109+
110+
#### Happy Hacking 🐱‍🏍

0 commit comments

Comments
 (0)