diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..b02ec43 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,39 @@ +## ❓ Frequently Asked Questions (FAQ) + +**Q1: What makes Celtrix stand out from other project scaffolding tools?** +A1: Celtrix provides ready-to-use templates, supports multiple popular stacks, and follows modern best practices, allowing you to start projects quickly without setting up everything manually. + +**Q2: How do I add a new stack or template to Celtrix?** +A2: You can create a new template in the `templates/` folder following the existing folder structure. Test it using the CLI and then submit a Pull Request to contribute. + +**Q3: Are projects created with Celtrix ready for production?** +A3: Celtrix projects give you a strong foundation for development. Some adjustments may be needed for production depending on your specific project requirements. + +**Q4: Which stacks are currently available in Celtrix?** +A4: Celtrix currently supports MERN, MEAN, T3, Angular+Tailwind, and several other popular stacks. Contributors can add more stacks. + +**Q5: Do I need to install anything globally to use Celtrix?** +A5: No, you don’t need global installations. Simply run `npx celtrix my-awesome-app` and follow the interactive prompts to start a project. + +**Q6: Can I customize the generated templates?** +A6: Absolutely! You can modify components, styles, API setups, and configurations to match your project’s requirements. + +**Q7: How can I report bugs or request new features?** +A7: Open a GitHub Issue in the Celtrix repository. Provide clear steps, screenshots, and a description to help maintainers understand and address your request. + +**Q8: Does Celtrix support TypeScript projects?** +A8: Yes, most templates offer optional TypeScript support. You can choose TypeScript when setting up a new project. + +**Q9: Can I use Celtrix for commercial projects?** +A9: Yes! Celtrix is open-source under the ISC license, so you can use it for personal or commercial projects following the license terms. + +**Q10: How can I improve or update existing templates?** +A10: Fork the repository, make your changes in a separate branch, test them, and submit a Pull Request. Ensure your updates follow the coding guidelines. + +**Q11: What prerequisites do I need to use Celtrix?** +A11: You only need Node.js and npm installed. Celtrix will handle other dependencies automatically during project setup. + +**Q12: Where can I get support or join the Celtrix community?** +A12: You can ask questions via GitHub Discussions or join the community chat if available. Always stay respectful and constructive while engaging. + +--- diff --git a/README.md b/README.md index b916f34..3237c8a 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,24 @@
- [![npm version](https://img.shields.io/npm/v/celtrix.svg)](https://www.npmjs.com/package/celtrix) - [![Downloads](https://img.shields.io/npm/dm/celtrix.svg)](https://www.npmjs.com/package/celtrix) - [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC) - +[![npm version](https://img.shields.io/npm/v/celtrix.svg)](https://www.npmjs.com/package/celtrix) +[![Downloads](https://img.shields.io/npm/dm/celtrix.svg)](https://www.npmjs.com/package/celtrix) +[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC) +
# ✨ Features ### 🎯 **Multiple Stack Options** -Choose from **7+ popular stacks** including MERN, MEAN, T3, Angular+Tailwind, and more! + +Choose from **8+ popular stacks** including MERN, MEAN, Next.js+Express+MongoDB, T3, and more!
Celtrix Stack Selection Demo
### 🌐 **Language Flexibility** + Pick your preferred programming languages and frameworks to match your workflow.
@@ -30,11 +32,12 @@ Pick your preferred programming languages and frameworks to match your workflow.
### πŸ› οΈ **Ready-to-Go Setup** -- **ESLint** configuration included -- **Sample components** and boilerplate code -- **API setup** with best practices -- **Automatic dependency installation** -- **Modern development tools** pre-configured + +- **ESLint** configuration included +- **Sample components** and boilerplate code +- **API setup** with best practices +- **Automatic dependency installation** +- **Modern development tools** pre-configured --- @@ -50,44 +53,9 @@ That's it! Follow the interactive prompts to customize your project. --- -## ❓ Frequently Asked Questions (FAQ) - -**Q1: What makes Celtrix stand out from other project scaffolding tools?** -A1: Celtrix provides ready-to-use templates, supports multiple popular stacks, and follows modern best practices, allowing you to start projects quickly without setting up everything manually. - -**Q2: How do I add a new stack or template to Celtrix?** -A2: You can create a new template in the `templates/` folder following the existing folder structure. Test it using the CLI and then submit a Pull Request to contribute. - -**Q3: Are projects created with Celtrix ready for production?** -A3: Celtrix projects give you a strong foundation for development. Some adjustments may be needed for production depending on your specific project requirements. - -**Q4: Which stacks are currently available in Celtrix?** -A4: Celtrix currently supports MERN, MEAN, T3, Angular+Tailwind, and several other popular stacks. Contributors can add more stacks. - -**Q5: Do I need to install anything globally to use Celtrix?** -A5: No, you don’t need global installations. Simply run `npx celtrix my-awesome-app` and follow the interactive prompts to start a project. - -**Q6: Can I customize the generated templates?** -A6: Absolutely! You can modify components, styles, API setups, and configurations to match your project’s requirements. - -**Q7: How can I report bugs or request new features?** -A7: Open a GitHub Issue in the Celtrix repository. Provide clear steps, screenshots, and a description to help maintainers understand and address your request. - -**Q8: Does Celtrix support TypeScript projects?** -A8: Yes, most templates offer optional TypeScript support. You can choose TypeScript when setting up a new project. - -**Q9: Can I use Celtrix for commercial projects?** -A9: Yes! Celtrix is open-source under the ISC license, so you can use it for personal or commercial projects following the license terms. - -**Q10: How can I improve or update existing templates?** -A10: Fork the repository, make your changes in a separate branch, test them, and submit a Pull Request. Ensure your updates follow the coding guidelines. - -**Q11: What prerequisites do I need to use Celtrix?** -A11: You only need Node.js and npm installed. Celtrix will handle other dependencies automatically during project setup. - -**Q12: Where can I get support or join the Celtrix community?** -A12: You can ask questions via GitHub Discussions or join the community chat if available. Always stay respectful and constructive while engaging. +## FAQ +You can now find the full list of FAQs here: [FAQ.md](./FAQ.md) --- diff --git a/index.js b/index.js index e04659a..75157f7 100755 --- a/index.js +++ b/index.js @@ -32,6 +32,7 @@ async function askStackQuestions() { { name: chalk.bold.magenta("MEAN") + " + Tailwind + Auth", value: "mean+tailwind+auth" }, { name: chalk.bold.cyan("MEVN") + " β†’ MongoDB + Express + Vue.js + Node.js", value: "mevn" }, { name: chalk.bold.yellow("MEVN") + " + Tailwind + Auth", value: "mevn+tailwind+auth" }, + { name: chalk.bold.blue("Next.js + Express + MongoDB") + " β†’ TypeScript-first full-stack", value: "next+express+mongodb" }, { name: chalk.bold.yellow("Next.js") + " + tRPC + Prisma + Tailwind + Auth", value: "t3-stack" }, { name: chalk.bold.red("Hono") + " β†’ Hono + Prisma + React", value: "hono" } @@ -85,7 +86,7 @@ async function main() { } const stackAnswers = await askStackQuestions(); config = { ...stackAnswers, projectName }; - + console.log(chalk.yellow("\nπŸš€ Creating your project...\n")); await createProject(projectName, config); diff --git a/utils/installer.js b/utils/installer.js index 2e07232..8c8d080 100644 --- a/utils/installer.js +++ b/utils/installer.js @@ -3,14 +3,14 @@ import { logger } from "./logger.js"; import path from "path"; import fs from "fs"; -export function installDependencies(projectPath, config, projectName,server=true,dependencies=[]) { +export function installDependencies(projectPath, config, projectName, server = true, dependencies = []) { logger.info("πŸ“¦ Installing dependencies..."); try { const clientDir = fs.existsSync(path.join(projectPath, "client")) ? path.join(projectPath, "client") : path.join(projectPath, "client"); - + const serverDir = fs.existsSync(path.join(projectPath, "server")) ? path.join(projectPath, "server") : path.join(projectPath, "server"); @@ -101,14 +101,14 @@ export function HonoReactSetup(projectPath, config, projectName) { try { // 1. Create React project (inside projectPath) - if(config.language==="typescript"){ + if (config.language === "typescript") { execSync(`npm create vite@latest client -- --t react-ts --no-rolldown --no-interactive `, { cwd: projectPath, stdio: "inherit", shell: true, }); - }else{ + } else { execSync(`npm create vite@latest client -- --t react --no-rolldown --no-interactive `, { cwd: projectPath, stdio: "inherit", @@ -116,7 +116,7 @@ export function HonoReactSetup(projectPath, config, projectName) { }); } - + execSync(`npm create hono@latest server -- --template cloudflare-workers --pm npm `, { cwd: projectPath, stdio: "inherit", @@ -135,14 +135,14 @@ export function mernSetup(projectPath, config, projectName) { try { // 1. Create MERN project - if(config.language==="typescript"){ + if (config.language === "typescript") { execSync(`npm create vite@latest client -- --t react-ts --no-rolldown --no-interactive `, { cwd: projectPath, stdio: "inherit", shell: true, }); - }else{ + } else { execSync(`npm create vite@latest client -- --t react --no-rolldown --no-interactive `, { cwd: projectPath, stdio: "inherit", @@ -151,15 +151,15 @@ export function mernSetup(projectPath, config, projectName) { } - if(config.language == 'javascript'){ + if (config.language == 'javascript') { + - const appJsxPath = path.join(projectPath, "client", "src", "App.jsx"); - const appCssPath = path.join(projectPath,"client", "src", "index.css"); - + const appCssPath = path.join(projectPath, "client", "src", "index.css"); + let appJsx = fs.readFileSync(appJsxPath, "utf-8"); const lines = appJsx.split("\n"); - + for (let i = 0; i < lines.length; i++) { if (lines[i].includes("")) { // inject badge right after opening fragment @@ -167,11 +167,11 @@ export function mernSetup(projectPath, config, projectName) { break; } } - + fs.writeFileSync(appJsxPath, lines.join("\n"), "utf-8"); - - // append the fu*king CSS - const badgeCSS = ` + + // append the fu*king CSS + const badgeCSS = ` .powered-badge { position: fixed; bottom: 1.5rem; @@ -196,18 +196,18 @@ export function mernSetup(projectPath, config, projectName) { color: #4ade80; } `; - - fs.appendFileSync(appCssPath, badgeCSS, "utf-8"); - + + fs.appendFileSync(appCssPath, badgeCSS, "utf-8"); + } - if(config.language=="typescript"){ + if (config.language == "typescript") { const appTsxPath = path.join(projectPath, "client", "src", "App.tsx"); - const appCssPath = path.join(projectPath,"client", "src", "index.css"); - + const appCssPath = path.join(projectPath, "client", "src", "index.css"); + let appTsx = fs.readFileSync(appTsxPath, "utf-8"); const lines = appTsx.split("\n"); - + for (let i = 0; i < lines.length; i++) { if (lines[i].includes("")) { // inject badge right after opening fragment @@ -215,11 +215,11 @@ export function mernSetup(projectPath, config, projectName) { break; } } - + fs.writeFileSync(appTsxPath, lines.join("\n"), "utf-8"); - - // append the fu*king CSS - const badgeCSS = ` + + // append the fu*king CSS + const badgeCSS = ` .powered-badge { position: fixed; bottom: 1.5rem; @@ -244,12 +244,12 @@ export function mernSetup(projectPath, config, projectName) { color: #4ade80; } `; - - fs.appendFileSync(appCssPath, badgeCSS, "utf-8"); - + + fs.appendFileSync(appCssPath, badgeCSS, "utf-8"); + } - serverSetup(projectPath,config,projectName); + serverSetup(projectPath, config, projectName); logger.info("βœ… MERN project created successfully!"); } catch (error) { logger.error("❌ Failed to set up MERN"); @@ -257,21 +257,21 @@ export function mernSetup(projectPath, config, projectName) { } } -export function serverSetup(projectPath,config,projectName){ - try{ +export function serverSetup(projectPath, config, projectName) { + try { execSync(`npm init -y`, { cwd: path.join(projectPath, "server") }); - installDependencies(projectPath,config,projectName,true,["dotenv","express","helmet","mongoose","cors","nodemon","morgan"]) + installDependencies(projectPath, config, projectName, true, ["dotenv", "express", "helmet", "mongoose", "cors", "nodemon", "morgan"]) logger.info("βœ… Server project created successfully!"); - }catch(error){ + } catch (error) { logger.error("❌ Failed to set up server"); throw error; } } -export function serverAuthSetup(projectPath,config,projectName){ +export function serverAuthSetup(projectPath, config, projectName) { try { execSync(`npm init -y`, { cwd: path.join(projectPath, "server") }); - installDependencies(projectPath,config,projectName,true,["bcrypt","jsonwebtoken","cookie-parser","dotenv","express","helmet","mongoose","cors","nodemon","morgan"]) + installDependencies(projectPath, config, projectName, true, ["bcrypt", "jsonwebtoken", "cookie-parser", "dotenv", "express", "helmet", "mongoose", "cors", "nodemon", "morgan"]) logger.info("βœ… Server Auth project created successfully!"); } catch (error) { logger.error("❌ Failed to set up server auth"); @@ -284,22 +284,22 @@ export function mernTailwindSetup(projectPath, config, projectName) { execSync(`npm install tailwindcss @tailwindcss/vite`, { cwd: path.join(projectPath, "client") }); let isJs = config.language === 'javascript'; - const viteConfigPath = isJs - ? path.join(projectPath, "client", "vite.config.js") + const viteConfigPath = isJs + ? path.join(projectPath, "client", "vite.config.js") : path.join(projectPath, "client", "vite.config.ts"); - + let viteConfigContent = fs.readFileSync(viteConfigPath, "utf-8"); - const indexCssPath = path.join(projectPath,"client","src","index.css") + const indexCssPath = path.join(projectPath, "client", "src", "index.css") let indexCssPathContent = fs.readFileSync(indexCssPath, "utf-8"); indexCssPathContent = indexCssPathContent.replace( /:root/g, "@import 'tailwindcss';\n\n:root" ); - - fs.writeFileSync(indexCssPath,indexCssPathContent) + + fs.writeFileSync(indexCssPath, indexCssPathContent) // Add tailwindcss import viteConfigContent = viteConfigContent.replace( @@ -327,23 +327,103 @@ export function mernTailwindSetup(projectPath, config, projectName) { } -export function mevnSetup(projectPath,config,projectName){ +export function nextExpressMongoSetup(projectPath, config, projectName) { + try { + logger.info("⚑ Setting up Next.js + Express + MongoDB..."); + + // Create Next.js project with appropriate template + if (config.language === 'javascript') { + execSync(`npx create-next-app@latest client --js --tailwind --eslint --app --src-dir --import-alias "@/*" --no-experimental`, { + cwd: projectPath, + stdio: "inherit", + shell: true + }); + } else { + execSync(`npx create-next-app@latest client --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --no-experimental`, { + cwd: projectPath, + stdio: "inherit", + shell: true + }); + } + + // Modify the main page to include Celtrix branding + const isTs = config.language === 'typescript'; + const pageExtension = isTs ? 'tsx' : 'jsx'; + const pagePath = path.join(projectPath, "client", "src", "app", `page.${pageExtension}`); + + let pageContent = fs.readFileSync(pagePath, "utf-8"); + + // Add Celtrix badge to the page + const celtrixBadge = `
+ Powered by Celtrix +
`; + + // Find the closing tag and add the badge before it + pageContent = pageContent.replace( + /(\s*)<\/main>/, + `$1${celtrixBadge}\n$1` + ); + + fs.writeFileSync(pagePath, pageContent, "utf-8"); + + // Add CSS for the badge to globals.css + const globalsCssPath = path.join(projectPath, "client", "src", "app", "globals.css"); + let globalsCss = fs.readFileSync(globalsCssPath, "utf-8"); + + const badgeCSS = ` +.powered-badge { + position: fixed; + bottom: 1.5rem; + left: 1.5rem; + font-size: 0.875rem; + background-color: black; + color: white; + padding: 0.5rem 1rem; + border-radius: 0.75rem; + box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), + 0 4px 6px -2px rgba(0,0,0,0.05); + opacity: 0.8; + transition: opacity 0.2s ease-in-out; + z-index: 1000; +} + +.powered-badge:hover { + opacity: 1; +} + +.powered-badge .celtrix { + font-weight: 600; + color: #4ade80; +}`; + + globalsCss += badgeCSS; + fs.writeFileSync(globalsCssPath, globalsCss, "utf-8"); + + logger.info("βœ… Next.js + Express + MongoDB project created successfully!"); + + } catch (error) { + logger.error("❌ Failed to set up Next.js + Express + MongoDB"); + throw error; + } +} + +export function mevnSetup(projectPath, config, projectName) { try { logger.info("⚑ Setting up MEVN..."); - if(config.language=='javascript'){ + if (config.language == 'javascript') { execSync(`npm create vite@latest client -- --t vue --no-rolldown --no-interactive`, { cwd: projectPath, stdio: "inherit", shell: true }); } - else{ + else { execSync(`npm create vite@latest client -- --t vue-ts --no-rolldown --no-interactive`, { cwd: projectPath, stdio: "inherit", shell: true }); } - + const vueJsPath = path.join(projectPath, "client", "src", "components", "HelloWorld.vue"); - + let vueJsPathContent = fs.readFileSync(vueJsPath, "utf-8"); - + vueJsPathContent = vueJsPathContent.replace( /

Click on the Vite and Vue logos to learn more<\/p>/, `

Click on the Vite and Vue logos to learn more

@@ -351,7 +431,7 @@ export function mevnSetup(projectPath,config,projectName){ Powered by Celtrix ` ); - + fs.writeFileSync(vueJsPath, vueJsPathContent, "utf-8"); // Replace

with new block @@ -404,7 +484,7 @@ export function mevnSetup(projectPath,config,projectName){ } fs.writeFileSync(vueJsPath, vueJsPathContent, "utf-8"); - + // serverSetup(projectPath,config,projectName); logger.info("βœ… MEVN project created successfully!"); diff --git a/utils/project.js b/utils/project.js index 58a68e3..3a7dca4 100644 --- a/utils/project.js +++ b/utils/project.js @@ -4,7 +4,7 @@ import chalk from "chalk"; import boxen from "boxen"; import { logger } from "./logger.js"; import { copyTemplates } from "./templateManager.js"; -import { HonoReactSetup,mernTailwindSetup, installDependencies, mernSetup, serverAuthSetup, serverSetup, mevnSetup } from "./installer.js"; +import { HonoReactSetup, mernTailwindSetup, installDependencies, mernSetup, serverAuthSetup, serverSetup, mevnSetup, nextExpressMongoSetup } from "./installer.js"; import { angularSetup, angularTailwindSetup } from "./installer.js"; export async function setupProject(projectName, config) { @@ -36,54 +36,60 @@ export async function setupProject(projectName, config) { ); // --- Copy & Install --- - if(config.stack !== "mean" && config.stack !== "mean+tailwind+auth" && config.stack!=="hono"){ + if (config.stack !== "mean" && config.stack !== "mean+tailwind+auth" && config.stack !== "hono" && config.stack !== "next+express+mongodb") { copyTemplates(projectPath, config); installDependencies(projectPath, config, projectName); } - if(config.stack==="mern+tailwind+auth"){ - mernSetup(projectPath,config,projectName); + if (config.stack === "mern+tailwind+auth") { + mernSetup(projectPath, config, projectName); copyTemplates(projectPath, config); mernTailwindSetup(projectPath, config, projectName); installDependencies(projectPath, config, projectName); - serverAuthSetup(projectPath,config,projectName); + serverAuthSetup(projectPath, config, projectName); } - if(config.stack === 'mevn'){ - mevnSetup(projectPath,config,projectName) - copyTemplates(projectPath,config) - installDependencies(projectPath,config,projectName) - serverSetup(projectPath,config,projectName) + if (config.stack === 'mevn') { + mevnSetup(projectPath, config, projectName) + copyTemplates(projectPath, config) + installDependencies(projectPath, config, projectName) + serverSetup(projectPath, config, projectName) } - if(config.stack === "mean"){ + if (config.stack === 'next+express+mongodb') { + nextExpressMongoSetup(projectPath, config, projectName) + copyTemplates(projectPath, config) + installDependencies(projectPath, config, projectName) + } + + if (config.stack === "mean") { angularSetup(projectPath, config); installDependencies(projectPath, config, projectName); copyTemplates(projectPath, config); - serverSetup(projectPath,config,projectName) + serverSetup(projectPath, config, projectName) } - - if(config.stack === "mean+tailwind+auth"){ + + if (config.stack === "mean+tailwind+auth") { angularTailwindSetup(projectPath, config, projectName); installDependencies(projectPath, config, projectName); copyTemplates(projectPath, config); } - - if(config.stack === "hono"){ - try{ - HonoReactSetup(projectPath,config,projectName); - installDependencies(projectPath, config, projectName,false); + if (config.stack === "hono") { + try { + + HonoReactSetup(projectPath, config, projectName); + installDependencies(projectPath, config, projectName, false); } - catch{ + catch { copyTemplates(projectPath, config); } } - if (config.stack ==="mern") { - mernSetup(projectPath,config,projectName); + if (config.stack === "mern") { + mernSetup(projectPath, config, projectName); copyTemplates(projectPath, config); - installDependencies(projectPath, config, projectName,false,[]) + installDependencies(projectPath, config, projectName, false, []) } // --- Success + Next Steps --- @@ -91,20 +97,20 @@ export async function setupProject(projectName, config) { console.log(`${chalk.greenBright(`βœ… Project ${chalk.bold.yellow(`${projectName}`)} created successfully! πŸŽ‰`)}`); console.log(chalk.gray("-------------------------------------------")) console.log(chalk.cyan("πŸ‘‰ Next Steps:\n")); - - if(config.stack === "mean" || config.stack === "mean+tailwind+auth") { + + if (config.stack === "mean" || config.stack === "mean+tailwind+auth") { console.log(` ${chalk.yellow("cd")} ${projectName}/client && ${chalk.green("npm start")}`); console.log(` ${chalk.yellow("cd")} ${projectName}/server && ${chalk.green("npm start")}`); - } else if(config.stack === "t3-stack") { + } else if (config.stack === "t3-stack") { console.log(` ${chalk.yellow("cd")} ${projectName}/t3-app && ${chalk.green("npm run dev")}`); - }else if(config.stack==="hono"){ + } else if (config.stack === "hono") { console.log(` ${chalk.yellow("cd")} ${projectName}/client && ${chalk.green("npm run dev")}`); console.log(` ${chalk.yellow("cd")} ${projectName}/server && ${chalk.green("npm run dev")}`); } else { console.log(` ${chalk.yellow("cd")} ${projectName}/client && ${chalk.green("npm run dev")}`); console.log(` ${chalk.yellow("cd")} ${projectName}/server && ${chalk.green("npm start")}`); } - + console.log(chalk.gray("-------------------------------------------")) console.log(chalk.gray("\n✨ Made with ❀️ by Celtrix ✨\n")); } \ No newline at end of file diff --git a/utils/templateManager.js b/utils/templateManager.js index ec0f56b..bdf62b8 100644 --- a/utils/templateManager.js +++ b/utils/templateManager.js @@ -10,31 +10,39 @@ const __dirname = path.dirname(__filename); export function copyTemplates(projectPath, config) { const { stack } = config; - if(stack === "mern"){ - const backendTemplate = path.join(__dirname, "..","templates","mern","server") + if (stack === "mern") { + const backendTemplate = path.join(__dirname, "..", "templates", "mern", "server") const serverPath = path.join(projectPath, "server"); - + logger.info("πŸ“‚ Copying backend template files..."); fs.copySync(backendTemplate, serverPath); } - else if(stack === 'mern+tailwind+auth'){ - const backendTemplate = path.join(__dirname,"..","templates","mern+tailwind+auth","server"); + else if (stack === 'mern+tailwind+auth') { + const backendTemplate = path.join(__dirname, "..", "templates", "mern+tailwind+auth", "server"); const serverPath = path.join(projectPath, "server"); - + logger.info("πŸ“‚ Copying backend template files..."); fs.copySync(backendTemplate, serverPath); } - else if(stack=='mevn'){ - const backendTemplate = path.join(__dirname,"..","templates","mevn","server"); + else if (stack == 'mevn') { + const backendTemplate = path.join(__dirname, "..", "templates", "mevn", "server"); const serverPath = path.join(projectPath, "server"); - + logger.info("πŸ“‚ Copying backend template files..."); fs.copySync(backendTemplate, serverPath); } - else if(stack !== "mean" && stack !== "mean+tailwind+auth" && stack !== "t3-stack"){ + else if (stack === 'next+express+mongodb') { + const backendTemplate = path.join(__dirname, "..", "templates", stack, config.language, "server"); + const serverPath = path.join(projectPath, "server"); + + logger.info("πŸ“‚ Setting up express server files..."); + fs.copySync(backendTemplate, serverPath); + } + + else if (stack !== "mean" && stack !== "mean+tailwind+auth" && stack !== "t3-stack") { const frontendTemplate = path.join(__dirname, "..", "templates", stack, config.language, "client"); const backendTemplate = path.join(__dirname, "..", "templates", stack, config.language, "server"); @@ -46,15 +54,15 @@ export function copyTemplates(projectPath, config) { fs.copySync(backendTemplate, serverPath); } - else if(stack === "mean" || stack === "mean+tailwind+auth" ){ + else if (stack === "mean" || stack === "mean+tailwind+auth") { const backendTemplate = path.join(__dirname, "..", "templates", stack, "server") const serverPath = path.join(projectPath, "server"); - + logger.info("πŸ“‚ Copying template files..."); fs.copySync(backendTemplate, serverPath); } - else if(stack === "t3-stack" ){ + else if (stack === "t3-stack") { const frontendTemplate = path.join(__dirname, "..", "templates", stack, "t3-app"); const clientPath = path.join(projectPath, "t3-app");