@@ -22,7 +22,12 @@ const run = (cmd, cwd = process.cwd()) => {
2222 type : "list" ,
2323 name : "cssFramework" ,
2424 message : "Choose a CSS framework:" ,
25- choices : [ "Tailwind" , "Bootstrap" , "MUI" ]
25+ choices : [
26+ "Tailwind" ,
27+ "Bootstrap (CDN)" ,
28+ "React Bootstrap" ,
29+ "MUI"
30+ ]
2631 }
2732 ] ) ;
2833
@@ -64,23 +69,34 @@ const run = (cmd, cwd = process.cwd()) => {
6469 : "src/main.tsx" ;
6570 const mainPath = path . join ( projectPath , mainFile ) ;
6671 let mainContent = fs . readFileSync ( mainPath , "utf-8" ) ;
67- mainContent = mainContent . replace ( / i m p o r t \s + [ ' " ] \. \/ i n d e x \. c s s [ ' " ] ; ? / g, "" ) ; // remove default CSS import
72+ mainContent = mainContent . replace ( / i m p o r t \s + [ ' " ] \. \/ i n d e x \. c s s [ ' " ] ; ? / g, "" ) ;
6873 if ( ! mainContent . includes ( `import './index.css'` ) ) {
6974 mainContent = `import './index.css';\n` + mainContent ;
7075 }
7176 fs . writeFileSync ( mainPath , mainContent ) ;
72- } else if ( cssFramework === "Bootstrap" ) {
73- run ( `npm install bootstrap` , projectPath ) ;
77+
78+ } else if ( cssFramework === "Bootstrap (CDN)" ) {
79+ const indexHtmlPath = path . join ( projectPath , "index.html" ) ;
80+ let indexHtml = fs . readFileSync ( indexHtmlPath , "utf-8" ) ;
81+ indexHtml = indexHtml . replace (
82+ / < h e a d > / ,
83+ `<head>\n <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">\n <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>`
84+ ) ;
85+ fs . writeFileSync ( indexHtmlPath , indexHtml ) ;
86+
87+ } else if ( cssFramework === "React Bootstrap" ) {
88+ run ( `npm install react-bootstrap bootstrap` , projectPath ) ;
7489 const mainFile = fs . existsSync ( path . join ( projectPath , "src/main.jsx" ) )
7590 ? "src/main.jsx"
7691 : "src/main.tsx" ;
7792 const mainPath = path . join ( projectPath , mainFile ) ;
7893 let mainContent = fs . readFileSync ( mainPath , "utf-8" ) ;
7994 mainContent = mainContent
80- . replace ( / i m p o r t \s + [ ' " ] \. \/ i n d e x \. c s s [ ' " ] ; ? / g, "" ) // remove vite css import
81- . replace ( / i m p o r t \s + [ ' " ] \. \/ A p p \. c s s [ ' " ] ; ? / g, "" ) ; // remove App.css import
95+ . replace ( / i m p o r t \s + [ ' " ] \. \/ i n d e x \. c s s [ ' " ] ; ? / g, "" )
96+ . replace ( / i m p o r t \s + [ ' " ] \. \/ A p p \. c s s [ ' " ] ; ? / g, "" ) ;
8297 mainContent = `import 'bootstrap/dist/css/bootstrap.min.css';\n` + mainContent ;
8398 fs . writeFileSync ( mainPath , mainContent ) ;
99+
84100 } else if ( cssFramework === "MUI" ) {
85101 run ( `npm install @mui/material @emotion/react @emotion/styled` , projectPath ) ;
86102 const mainFile = fs . existsSync ( path . join ( projectPath , "src/main.jsx" ) )
@@ -158,17 +174,21 @@ api.interceptors.response.use(
158174 fs . writeFileSync ( path . join ( projectPath , "src" , "utils" , "axiosInstance.js" ) , axiosContent ) ;
159175 }
160176
161- // 9. Clean up default CSS files from Vite
177+ // 9. Clean up default CSS files (centralized)
162178 const appCssPath = path . join ( projectPath , "src" , "App.css" ) ;
163179 if ( fs . existsSync ( appCssPath ) ) fs . unlinkSync ( appCssPath ) ;
164180
181+ const indexCssPath = path . join ( projectPath , "src" , "index.css" ) ;
182+ if ( cssFramework !== "Tailwind" && fs . existsSync ( indexCssPath ) ) {
183+ fs . unlinkSync ( indexCssPath ) ;
184+ }
185+
186+ // 10. Replace App.jsx content
165187 const appFile = fs . existsSync ( path . join ( projectPath , "src/App.jsx" ) )
166188 ? path . join ( projectPath , "src/App.jsx" )
167189 : path . join ( projectPath , "src/App.tsx" ) ;
168190
169- let appContent = fs . readFileSync ( appFile , "utf-8" ) ;
170- appContent = appContent . replace ( / i m p o r t \s + [ ' " ] \. \/ A p p \. c s s [ ' " ] ; ? / g, "" ) ; // remove App.css import
171- appContent = `export default function App() {
191+ let appContent = `export default function App() {
172192 return (
173193 <div
174194 style={{
@@ -201,13 +221,24 @@ api.interceptors.response.use(
201221}` ;
202222 fs . writeFileSync ( appFile , appContent ) ;
203223
204- // 10 . Default Router setup in main.jsx
224+ // 11 . Default Router setup in main.jsx
205225 const mainFile = fs . existsSync ( path . join ( projectPath , "src/main.jsx" ) )
206226 ? "src/main.jsx"
207227 : "src/main.tsx" ;
208228 const mainPath = path . join ( projectPath , mainFile ) ;
209229
210- const routerSetup = `import React from 'react';
230+ let cssImports = "" ;
231+ if ( cssFramework === "React Bootstrap" ) {
232+ cssImports = `import 'bootstrap/dist/css/bootstrap.min.css';\n` ;
233+ } else if ( cssFramework === "Tailwind" ) {
234+ cssImports = `import './index.css';\n` ;
235+ } else if ( cssFramework === "Bootstrap (CDN)" ) {
236+ cssImports = "" ; // CDN already added in index.html
237+ } else if ( cssFramework === "MUI" ) {
238+ cssImports = "" ; // no CSS import needed
239+ }
240+
241+ const routerSetup = `${ cssImports } import React from 'react';
211242import ReactDOM from 'react-dom/client';
212243import { BrowserRouter, Routes, Route } from 'react-router-dom';
213244import App from './App';
@@ -224,6 +255,7 @@ ReactDOM.createRoot(document.getElementById('root')).render(
224255
225256 fs . writeFileSync ( mainPath , routerSetup ) ;
226257
258+
227259 console . log ( "\n✅ Setup complete!" ) ;
228260 console . log ( `\nNext steps:\n cd ${ projectName } \n npm run dev` ) ;
229261} ) ( ) ;
0 commit comments