├── README.md ├── package.json ├── utils ├── checkExisting.js ├── installDeps.js └── modifyFiles.js └── index.js /README.md: -------------------------------------------------------------------------------- 1 | # nuxt-tailwind 2 | 3 | Automates Tailwind CSS v4 setup in Nuxt projects. 4 | 5 | Note: Intended be used with freshly created Nuxt projects, even thought it can be used with existing projects. 6 | 7 | ## Usage 8 | 9 | ```bash 10 | npx nuxt-tailwind 11 | ``` 12 | 13 | ## Working 14 | 15 | - Installs Tailwind CSS v4 dependencies. 16 | - Modifies `nuxt.config.ts` to include Tailwind CSS v4 configuration. 17 | - Creates a `main.css` file in the `assets/css` directory with proper imports. 18 | - Avoid conflicts with existing Tailwind CSS configurations if found in `package.json`. 19 | 20 | > After running the command, start or restart your Nuxt development server. 21 | 22 | Made with ❤️ by [Sumir Seth](https://github.com/sumirseth). 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-tailwind", 3 | "version": "1.3.0", 4 | "description": "A package manager agnostic tool to set up Tailwind CSS v4 for Nuxt. Supports npm, pnpm, and yarn.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "nuxt", 11 | "tailwind", 12 | "setup", 13 | "pnpm", 14 | "npm", 15 | "yarn" 16 | ], 17 | "author": "Sumir Seth", 18 | "url": "https://github.com/sumirseth/nuxt-tailwind", 19 | "license": "ISC", 20 | "type": "module", 21 | "dependencies": { 22 | "execa": "^9.5.2", 23 | "fs-extra": "^11.3.0", 24 | "path": "^0.12.7", 25 | "picocolors": "^1.1.1" 26 | }, 27 | "bin": { 28 | "nuxt-tailwind": "index.js" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /utils/checkExisting.js: -------------------------------------------------------------------------------- 1 | import pkg from 'fs-extra'; 2 | const { readJson } = pkg; 3 | import { resolve } from 'path'; 4 | import pc from 'picocolors'; 5 | 6 | async function checkExistingTailwind() { 7 | console.log(pc.cyan("Checking the package.json file...")); 8 | const packageJsonPath = resolve(process.cwd(), 'package.json'); 9 | try{ 10 | 11 | const packageJsonContent = await readJson(packageJsonPath); 12 | 13 | return ( 14 | packageJsonContent.dependencies && 15 | (packageJsonContent.dependencies.tailwindcss || packageJsonContent.dependencies['@tailwindcss/vite']) 16 | ); 17 | }catch(error){ 18 | console.log(pc.red("No package.json file detected, please run this command inside your nuxt project.")) 19 | console.error(error); 20 | throw error 21 | } 22 | } 23 | 24 | 25 | 26 | export { checkExistingTailwind }; -------------------------------------------------------------------------------- /utils/installDeps.js: -------------------------------------------------------------------------------- 1 | import { execa } from 'execa'; 2 | import { existsSync } from 'fs'; 3 | import pc from 'picocolors'; 4 | import { resolve } from 'path'; 5 | 6 | async function detectPackageManager() { 7 | const cwd = process.cwd(); 8 | if (existsSync(resolve(cwd, 'pnpm-lock.yaml'))) return 'pnpm'; 9 | if (existsSync(resolve(cwd, 'yarn.lock'))) return 'yarn'; 10 | return 'npm'; 11 | } 12 | 13 | async function installDependencies() { 14 | const packageManager = await detectPackageManager(); 15 | console.log(pc.cyan('Installing dependencies...')); 16 | try { 17 | await execa(packageManager, ['install', 'tailwindcss', '@tailwindcss/vite'], { stdio: 'inherit' }); 18 | console.log(pc.greenBright('✅ Dependencies installed successfully.')); 19 | } catch (error) { 20 | console.error(pc.redBright('❌ An error occurred while installing dependencies.')); 21 | console.error(error); 22 | throw error; 23 | } 24 | } 25 | 26 | export { installDependencies }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { installDependencies } from './utils/installDeps.js'; 3 | import { modifyNuxtConfig, createCSSFile } from './utils/modifyFiles.js'; 4 | import { checkExistingTailwind } from './utils/checkExisting.js'; 5 | import pc from 'picocolors'; 6 | 7 | 8 | async function main() { 9 | console.log(pc.blueBright('🚀Setting Up Tailwind CSS v4 for Nuxt...')); 10 | 11 | try { 12 | // check for existing configs. 13 | const hasExistingTailwind = await checkExistingTailwind(); 14 | if (hasExistingTailwind) { 15 | console.log(pc.redBright('❌ Tailwind configuration already exists.')); 16 | process.exit(1); 17 | } 18 | 19 | // install Dependencies 20 | await installDependencies(); 21 | 22 | // modify nuxt.config.ts 23 | await modifyNuxtConfig(); 24 | 25 | // create CSS File 26 | await createCSSFile(); 27 | 28 | console.log(pc.greenBright('✅ Tailwind CSS v4 has been set up for Nuxt.')); 29 | console.log(pc.greenBright('🎉 Start or restart your Nuxt Development Server to use Tailwind CSS v4.')); 30 | 31 | 32 | } catch (error) { 33 | console.error(pc.redBright('❌ An error occurred while setting up Tailwind CSS v4 for Nuxt.')); 34 | console.error(error); 35 | process.exit(1); 36 | } 37 | 38 | 39 | } 40 | console.log(pc.italic("Greeting from Sumir! 👋 Appreciate your support!")); 41 | main(); -------------------------------------------------------------------------------- /utils/modifyFiles.js: -------------------------------------------------------------------------------- 1 | import pkg from 'fs-extra'; 2 | const { readFile, writeFile, ensureDir } = pkg; 3 | import { resolve, dirname } from 'path'; 4 | import pc from 'picocolors'; 5 | 6 | 7 | async function modifyNuxtConfig() { 8 | const nuxtConfigPath = resolve(process.cwd(), 'nuxt.config.ts'); 9 | try { 10 | let configContent = await readFile(nuxtConfigPath, 'utf-8'); 11 | if (!configContent.includes("import tailwindcss from \"@tailwindcss/vite\";")) { 12 | configContent = "import tailwindcss from \"@tailwindcss/vite\";\n" + configContent; 13 | } 14 | const pluginsRegex = /plugins:\s*\[/; 15 | if (pluginsRegex.test(configContent)) { 16 | configContent = configContent.replace(pluginsRegex, 'plugins: [\n tailwindcss(),'); 17 | } else { 18 | // Handle cases where 'plugins' array doesn't exist. Add it within 'vite'. 19 | const viteRegex = /vite:\s*\{/; 20 | if (viteRegex.test(configContent)) { 21 | configContent = configContent.replace(viteRegex, 'vite: {\n plugins: [\n tailwindcss(),\n ],'); 22 | } else { 23 | //handle cases where even vite does not exits. 24 | const defineNuxtConfigRegex = /export default defineNuxtConfig\(\{/; 25 | if(defineNuxtConfigRegex.test(configContent)){ 26 | configContent = configContent.replace(defineNuxtConfigRegex, 27 | `export default defineNuxtConfig({ 28 | vite: { 29 | plugins: [ 30 | tailwindcss(), 31 | ], 32 | },`); 33 | } 34 | else{ 35 | throw new Error("Could not find defineNuxtConfig in nuxt.config.ts"); 36 | } 37 | } 38 | } 39 | const cssRegex = /css:\s*\[/; 40 | if(cssRegex.test(configContent)){ 41 | configContent = configContent.replace(cssRegex, 'css: [\n \'~/assets/css/main.css\',') 42 | }else{ 43 | const defineNuxtConfigRegex = /export default defineNuxtConfig\(\{/; 44 | if(defineNuxtConfigRegex.test(configContent)){ 45 | configContent = configContent.replace(defineNuxtConfigRegex, `export default defineNuxtConfig({\n css: ['~/assets/css/main.css'],`) 46 | }else{ 47 | throw new Error("Could not find defineNuxtConfig in nuxt.config.ts"); 48 | } 49 | } 50 | const compatibilityDateRegex = /compatibilityDate:\s*["']\d{4}-\d{2}-\d{2}["']/; 51 | if(compatibilityDateRegex.test(configContent)){ 52 | const currentDate = new Date().toISOString().split('T')[0]; 53 | configContent = configContent.replace(compatibilityDateRegex, `compatibilityDate: "${currentDate}"`); 54 | } 55 | 56 | 57 | await writeFile(nuxtConfigPath, configContent, 'utf-8'); 58 | console.log(pc.green("nuxt.config.ts modified successfully.")); 59 | } catch (error) { 60 | console.error(pc.red("An error occurred while modifying nuxt.config.ts.")); 61 | console.error(error); 62 | throw error; 63 | } 64 | } 65 | 66 | async function createCSSFile() { 67 | console.log(pc.cyan('Creating tailwind.css file...')); 68 | const cssFilePath = resolve(process.cwd(), 'assets/css/main.css'); 69 | try { 70 | await ensureDir(dirname(cssFilePath)); 71 | await writeFile(cssFilePath, '@import "tailwindcss";\n', 'utf-8'); 72 | console.log(pc.greenBright('✅ tailwind.css file created successfully.')); 73 | } catch (error) { 74 | console.error(pc.redBright('❌ An error occurred while creating tailwind.css file.')); 75 | console.error(error); 76 | throw error; 77 | } 78 | } 79 | 80 | export { modifyNuxtConfig, createCSSFile }; --------------------------------------------------------------------------------