├── .gitattributes ├── src ├── assets │ ├── main.css │ ├── logo.svg │ └── base.css ├── main.ts ├── components │ ├── icons │ │ ├── IconSupport.vue │ │ ├── IconTooling.vue │ │ ├── IconCommunity.vue │ │ ├── IconDocumentation.vue │ │ └── IconEcosystem.vue │ └── __tests__ │ │ └── HelloWorld.spec.ts └── App.vue ├── env.d.ts ├── public └── favicon.ico ├── postcss.config.js ├── .prettierrc.json ├── tailwind.config.js ├── .vscode └── extensions.json ├── .editorconfig ├── tsconfig.json ├── tsconfig.vitest.json ├── tsconfig.app.json ├── index.html ├── vitest.config.ts ├── .gitignore ├── vite.config.ts ├── tsconfig.node.json ├── eslint.config.ts ├── README.md ├── package.json └── AGENTS.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | @import './base.css'; 2 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BuilderIO/fusion-vue-tailwind-starter/main/public/favicon.ico -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import './assets/main.css' 2 | 3 | import { createApp } from 'vue' 4 | import App from './App.vue' 5 | 6 | createApp(App).mount('#app') 7 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "singleQuote": true, 5 | "printWidth": 100 6 | } 7 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "vitest.explorer", 5 | "dbaeumer.vscode-eslint", 6 | "EditorConfig.EditorConfig", 7 | "esbenp.prettier-vscode" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}] 2 | charset = utf-8 3 | indent_size = 2 4 | indent_style = space 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | end_of_line = lf 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "include": ["src/**/__tests__/*", "env.d.ts"], 4 | "exclude": [], 5 | "compilerOptions": { 6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo", 7 | 8 | "lib": [], 9 | "types": ["node", "jsdom"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 7 | 8 | "paths": { 9 | "@/*": ["./src/*"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/__tests__/HelloWorld.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest' 2 | 3 | import { mount } from '@vue/test-utils' 4 | import HelloWorld from '../HelloWorld.vue' 5 | 6 | describe('HelloWorld', () => { 7 | it('renders properly', () => { 8 | const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } }) 9 | expect(wrapper.text()).toContain('Hello Vitest') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' 3 | import viteConfig from './vite.config' 4 | 5 | export default mergeConfig( 6 | viteConfig, 7 | defineConfig({ 8 | test: { 9 | environment: 'jsdom', 10 | exclude: [...configDefaults.exclude, 'e2e/**'], 11 | root: fileURLToPath(new URL('./', import.meta.url)), 12 | }, 13 | }), 14 | ) 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueDevTools from 'vite-plugin-vue-devtools' 6 | 7 | // https://vite.dev/config/ 8 | export default defineConfig({ 9 | plugins: [ 10 | vue(), 11 | vueDevTools(), 12 | ], 13 | resolve: { 14 | alias: { 15 | '@': fileURLToPath(new URL('./src', import.meta.url)) 16 | }, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node22/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*", 9 | "eslint.config.*" 10 | ], 11 | "compilerOptions": { 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /eslint.config.ts: -------------------------------------------------------------------------------- 1 | import { globalIgnores } from 'eslint/config' 2 | import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' 3 | import pluginVue from 'eslint-plugin-vue' 4 | import pluginVitest from '@vitest/eslint-plugin' 5 | import skipFormatting from '@vue/eslint-config-prettier/skip-formatting' 6 | 7 | // To allow more languages other than `ts` in `.vue` files, uncomment the following lines: 8 | // import { configureVueProject } from '@vue/eslint-config-typescript' 9 | // configureVueProject({ scriptLangs: ['ts', 'tsx'] }) 10 | // More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup 11 | 12 | export default defineConfigWithVueTs( 13 | { 14 | name: 'app/files-to-lint', 15 | files: ['**/*.{ts,mts,tsx,vue}'], 16 | }, 17 | 18 | globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), 19 | 20 | pluginVue.configs['flat/essential'], 21 | vueTsConfigs.recommended, 22 | 23 | { 24 | ...pluginVitest.configs.recommended, 25 | files: ['src/**/__tests__/*'], 26 | }, 27 | skipFormatting, 28 | ) 29 | -------------------------------------------------------------------------------- /src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fusion-vue-tailwind-starter 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). 8 | 9 | ## Type Support for `.vue` Imports in TS 10 | 11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. 12 | 13 | ## Customize configuration 14 | 15 | See [Vite Configuration Reference](https://vite.dev/config/). 16 | 17 | ## Project Setup 18 | 19 | ```sh 20 | npm install 21 | ``` 22 | 23 | ### Compile and Hot-Reload for Development 24 | 25 | ```sh 26 | npm run dev 27 | ``` 28 | 29 | ### Type-Check, Compile and Minify for Production 30 | 31 | ```sh 32 | npm run build 33 | ``` 34 | 35 | ### Run Unit Tests with [Vitest](https://vitest.dev/) 36 | 37 | ```sh 38 | npm run test:unit 39 | ``` 40 | 41 | ### Lint with [ESLint](https://eslint.org/) 42 | 43 | ```sh 44 | npm run lint 45 | ``` 46 | -------------------------------------------------------------------------------- /src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fusion-vue-tailwind-starter", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "test:unit": "vitest", 11 | "build-only": "vite build", 12 | "type-check": "vue-tsc --build", 13 | "lint": "eslint . --fix", 14 | "format": "prettier --write src/" 15 | }, 16 | "dependencies": { 17 | "vue": "^3.5.17" 18 | }, 19 | "devDependencies": { 20 | 21 | "@tsconfig/node22": "^22.0.2", 22 | "@types/jsdom": "^21.1.7", 23 | "@types/node": "^22.15.32", 24 | "@vitejs/plugin-vue": "^6.0.0", 25 | "@vitest/eslint-plugin": "^1.2.7", 26 | "@vue/eslint-config-prettier": "^10.2.0", 27 | "@vue/eslint-config-typescript": "^14.5.1", 28 | "@vue/test-utils": "^2.4.6", 29 | "@vue/tsconfig": "^0.7.0", 30 | "autoprefixer": "^10.4.21", 31 | "eslint": "^9.29.0", 32 | "eslint-plugin-vue": "~10.2.0", 33 | "jiti": "^2.4.2", 34 | "jsdom": "^26.1.0", 35 | "npm-run-all2": "^8.0.4", 36 | "postcss": "^8.5.6", 37 | "prettier": "3.5.3", 38 | "tailwindcss": "^3.4.11", 39 | "typescript": "~5.8.0", 40 | "vite": "^7.0.0", 41 | "vite-plugin-vue-devtools": "^7.7.7", 42 | "vitest": "^3.2.4", 43 | "vue-tsc": "^2.2.10" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/assets/base.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* color palette from */ 6 | :root { 7 | --vt-c-white: #ffffff; 8 | --vt-c-white-soft: #f8f8f8; 9 | --vt-c-white-mute: #f2f2f2; 10 | 11 | --vt-c-black: #181818; 12 | --vt-c-black-soft: #222222; 13 | --vt-c-black-mute: #282828; 14 | 15 | --vt-c-indigo: #2c3e50; 16 | 17 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 18 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 19 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 20 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 21 | 22 | --vt-c-text-light-1: var(--vt-c-indigo); 23 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 24 | --vt-c-text-dark-1: var(--vt-c-white); 25 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 26 | } 27 | 28 | /* semantic color variables for this project */ 29 | :root { 30 | --color-background: var(--vt-c-white); 31 | --color-background-soft: var(--vt-c-white-soft); 32 | --color-background-mute: var(--vt-c-white-mute); 33 | 34 | --color-border: var(--vt-c-divider-light-2); 35 | --color-border-hover: var(--vt-c-divider-light-1); 36 | 37 | --color-heading: var(--vt-c-text-light-1); 38 | --color-text: var(--vt-c-text-light-1); 39 | 40 | --section-gap: 160px; 41 | } 42 | 43 | @media (prefers-color-scheme: dark) { 44 | :root { 45 | --color-background: var(--vt-c-black); 46 | --color-background-soft: var(--vt-c-black-soft); 47 | --color-background-mute: var(--vt-c-black-mute); 48 | 49 | --color-border: var(--vt-c-divider-dark-2); 50 | --color-border-hover: var(--vt-c-divider-dark-1); 51 | 52 | --color-heading: var(--vt-c-text-dark-1); 53 | --color-text: var(--vt-c-text-dark-2); 54 | } 55 | } 56 | 57 | *, 58 | *::before, 59 | *::after { 60 | box-sizing: border-box; 61 | margin: 0; 62 | font-weight: normal; 63 | } 64 | 65 | body { 66 | min-height: 100vh; 67 | color: var(--color-text); 68 | background: var(--color-background); 69 | transition: 70 | color 0.5s, 71 | background-color 0.5s; 72 | line-height: 1.6; 73 | font-family: 74 | Inter, 75 | -apple-system, 76 | BlinkMacSystemFont, 77 | 'Segoe UI', 78 | Roboto, 79 | Oxygen, 80 | Ubuntu, 81 | Cantarell, 82 | 'Fira Sans', 83 | 'Droid Sans', 84 | 'Helvetica Neue', 85 | sans-serif; 86 | font-size: 15px; 87 | text-rendering: optimizeLegibility; 88 | -webkit-font-smoothing: antialiased; 89 | -moz-osx-font-smoothing: grayscale; 90 | } 91 | -------------------------------------------------------------------------------- /AGENTS.md: -------------------------------------------------------------------------------- 1 | # Fusion Vue Tailwind Starter 2 | 3 | A production-ready Vue.js application template with TypeScript, TailwindCSS 3, and modern tooling. 4 | 5 | ## Tech Stack 6 | 7 | - **Frontend**: Vue 3.5.17 + TypeScript + TailwindCSS 3.4.11 8 | - **Styling**: TailwindCSS 3 with PostCSS + Autoprefixer 9 | - **Testing**: Vitest with Vue Test Utils for component testing 10 | - **Build Tool**: Vite 7 with Vue plugin 11 | - **Package Manager**: npm 12 | - **Linting**: ESLint 9 + Prettier 13 | - **Type Checking**: TypeScript 5 + vue-tsc 14 | - **Development Tools**: Vue DevTools integration 15 | 16 | ## Project Structure 17 | 18 | ``` 19 | src/ # Vue application source 20 | ├── App.vue # Main app component 21 | ├── main.ts # Application entry point 22 | ├── assets/ # Static assets 23 | │ ├── base.css # Base styles 24 | │ ├── logo.svg # Logo asset 25 | │ └── main.css # Main styles with TailwindCSS imports 26 | ├── components/ # Vue components 27 | │ ├── __tests__/ # Component tests 28 | │ └── icons/ # Icon components 29 | ├── env.d.ts # TypeScript declarations 30 | └── ... # Other source files 31 | 32 | public/ # Static assets 33 | ├── favicon.ico # Site favicon 34 | └── ... # Other static files 35 | ``` 36 | 37 | ## Key Features 38 | 39 | ### Vue 3 Composition API 40 | 41 | The application uses Vue 3's modern Composition API with TypeScript: 42 | 43 | - ` 69 | ``` 70 | 71 | ### Development Commands 72 | 73 | ```bash 74 | npm run dev # Start development server 75 | npm run build # Production build 76 | npm run preview # Preview production build 77 | npm run type-check # Type check with vue-tsc 78 | npm run test:unit # Run tests with Vitest 79 | npm run lint # Lint with ESLint 80 | npm run format # Format with Prettier 81 | ``` 82 | 83 | ## Adding Features 84 | 85 | ### New Components 86 | 87 | 1. Create component in `src/components/`: 88 | 89 | ```vue 90 | 91 | 97 | 98 | 109 | ``` 110 | 111 | 2. Import in your app: 112 | 113 | ```vue 114 | 117 | 118 | 121 | ``` 122 | 123 | ### Custom TailwindCSS Configuration 124 | 125 | 1. Update `tailwind.config.js` for custom theming: 126 | 127 | ```javascript 128 | /** @type {import('tailwindcss').Config} */ 129 | export default { 130 | content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], 131 | theme: { 132 | extend: { 133 | colors: { 134 | primary: '#3b82f6', 135 | secondary: '#64748b', 136 | }, 137 | }, 138 | }, 139 | plugins: [], 140 | } 141 | ``` 142 | 143 | 2. Add custom styles in `src/assets/main.css`: 144 | 145 | ```css 146 | @tailwind base; 147 | @tailwind components; 148 | @tailwind utilities; 149 | 150 | @layer components { 151 | .btn-primary { 152 | @apply rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700; 153 | } 154 | } 155 | ``` 156 | 157 | ## Testing 158 | 159 | The project includes comprehensive testing setup: 160 | 161 | - **Unit Testing**: Vitest for fast unit tests 162 | - **Component Testing**: Vue Test Utils for Vue component testing 163 | - **Type Checking**: vue-tsc for TypeScript validation 164 | 165 | ```bash 166 | npm run test:unit # Run unit tests 167 | ``` 168 | 169 | ## Production Deployment 170 | 171 | - **Development**: `npm run dev` for local development 172 | - **Build**: `npm run build` creates optimized production build 173 | - **Preview**: `npm run preview` to preview production build 174 | - **Type Check**: `npm run type-check` for TypeScript validation 175 | 176 | ## Architecture Notes 177 | 178 | - Vue 3.5.17 with Composition API for modern reactive components 179 | - TypeScript throughout the application 180 | - TailwindCSS 3.4.11 for utility-first styling 181 | - Vite 7 for fast development and optimized builds 182 | - Vitest + Vue Test Utils for comprehensive testing 183 | - ESLint + Prettier for code quality 184 | - Vue DevTools integration for development debugging 185 | - Single-page application (SPA) architecture 186 | --------------------------------------------------------------------------------