This website requires JavaScript.
Vue 3 App Template
src/assets/main.css
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --color-background: #ffffff;
  --color-background-soft: #f8fafc;
  --color-background-mute: #f1f5f9;
  --color-border: #e2e8f0;
  --color-border-hover: #cbd5e1;
  --color-heading: #1e293b;
  --color-text: #475569;
  --color-text-soft: #64748b;
  --color-primary: #0ea5e9;
  --color-primary-hover: #0284c7;
  --color-primary-soft: #e0f2fe;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #0f172a;
    --color-background-soft: #1e293b;
    --color-background-mute: #334155;
    --color-border: #475569;
    --color-border-hover: #64748b;
    --color-heading: #f1f5f9;
    --color-text: #cbd5e1;
    --color-text-soft: #94a3b8;
    --color-primary: #38bdf8;
    --color-primary-hover: #0ea5e9;
    --color-primary-soft: #0c4a6e;
  }
}

body {
  min-height: 100vh;
  color: var(--color-text);
  background: var(--color-background);
  transition: color 0.5s, background-color 0.5s;
  line-height: 1.6;
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
src/App.vue
<script setup lang="ts">
import { RouterView } from 'vue-router'
import AppHeader from './components/AppHeader.vue'
</script>

<template>
  <div id="app" class="min-h-screen bg-background">
    <AppHeader />
    <main class="container mx-auto px-4 py-8">
      <RouterView />
    </main>
  </div>
</template>

<style scoped>
#app {
  font-weight: normal;
}
</style>
src/components/AppHeader.vue
<script setup lang="ts">
import { ref } from 'vue'
import { RouterLink } from 'vue-router'

const isMenuOpen = ref(false)

const toggleMenu = () => {
  isMenuOpen.value = !isMenuOpen.value
}
</script>

<template>
  <header class="bg-background-soft border-b border-border">
    <nav class="container mx-auto px-4 py-4">
      <div class="flex items-center justify-between">
        <RouterLink
          to="/"
          class="text-2xl font-bold text-heading hover:text-primary transition-colors"
        >
          Vue App
        </RouterLink>

        <div class="hidden md:flex items-center space-x-6">
          <RouterLink
            to="/"
            class="text-text hover:text-primary transition-colors"
            active-class="text-primary font-semibold"
          >
            Home
          </RouterLink>
          <RouterLink
            to="/about"
            class="text-text hover:text-primary transition-colors"
            active-class="text-primary font-semibold"
          >
            About
          </RouterLink>
        </div>

        <button
          @click="toggleMenu"
          class="md:hidden p-2 rounded-lg hover:bg-background-mute transition-colors"
        >
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
          </svg>
        </button>
      </div>

      <div v-if="isMenuOpen" class="md:hidden mt-4 pb-4 border-t border-border pt-4">
        <RouterLink
          to="/"
          class="block py-2 text-text hover:text-primary transition-colors"
          @click="isMenuOpen = false"
        >
          Home
        </RouterLink>
        <RouterLink
          to="/about"
          class="block py-2 text-text hover:text-primary transition-colors"
          @click="isMenuOpen = false"
        >
          About
        </RouterLink>
      </div>
    </nav>
  </header>
</template>
src/views/HomeView.vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import HelloWorld from '../components/HelloWorld.vue'

const count = ref(0)

const increment = () => {
  count.value++
}

onMounted(() => {
  console.log('Home view mounted!')
})
</script>

<template>
  <div class="max-w-4xl mx-auto text-center">
    <HelloWorld />

    <div class="mt-12 p-8 bg-background-soft rounded-xl border border-border">
      <h2 class="text-2xl font-bold text-heading mb-4">Interactive Counter</h2>
      <p class="text-text-soft mb-6">
        Click the button to increment the counter and test Vue's reactivity.
      </p>

      <div class="flex items-center justify-center gap-4 mb-6">
        <button
          @click="increment"
          class="bg-primary hover:bg-primary-hover text-white px-6 py-3 rounded-lg transition-colors font-semibold"
        >
          Count: {{ count }}
        </button>
      </div>

      <p class="text-sm text-text-soft">
        The counter value is: <span class="font-mono text-primary">{{ count }}</span>
      </p>
    </div>
  </div>
</template>
src/views/AboutView.vue
<template>
  <div class="max-w-2xl mx-auto">
    <h1 class="text-4xl font-bold text-heading mb-6 text-center">About This App</h1>

    <div class="prose prose-slate dark:prose-invert mx-auto">
      <p class="text-lg text-text leading-relaxed mb-6">
        This is a modern Vue 3 application built with the Composition API, TypeScript,
        and Tailwind CSS. It demonstrates best practices for Vue development in 2025.
      </p>

      <div class="bg-background-soft rounded-lg p-6 border border-border mb-6">
        <h2 class="text-2xl font-semibold text-heading mb-4">Features</h2>
        <ul class="list-disc list-inside space-y-2 text-text">
          <li>Vue 3 with Composition API</li>
          <li>TypeScript for type safety</li>
          <li>Vue Router for navigation</li>
          <li>Vite for fast development</li>
          <li>Tailwind CSS for styling</li>
          <li>ESLint & Prettier for code quality</li>
          <li>Responsive design</li>
          <li>Dark mode support</li>
        </ul>
      </div>

      <div class="bg-primary-soft rounded-lg p-6 border border-primary/20">
        <h3 class="text-xl font-semibold text-heading mb-3">Tech Stack</h3>
        <div class="grid grid-cols-2 gap-4 text-sm">
          <div>
            <strong class="text-heading">Frontend:</strong>
            <p class="text-text">Vue 3, TypeScript, Tailwind CSS</p>
          </div>
          <div>
            <strong class="text-heading">Build Tool:</strong>
            <p class="text-text">Vite with HMR</p>
          </div>
          <div>
            <strong class="text-heading">Router:</strong>
            <p class="text-text">Vue Router 4</p>
          </div>
          <div>
            <strong class="text-heading">Linting:</strong>
            <p class="text-text">ESLint, Prettier</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
src/components/HelloWorld.vue
<script setup lang="ts">
interface Props {
  msg?: string
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'Welcome to Vue 3'
})
</script>

<template>
  <div class="text-center mb-12">
    <h1 class="text-5xl font-bold text-heading mb-4">
      {{ msg }}
    </h1>
    <p class="text-xl text-text-soft max-w-2xl mx-auto leading-relaxed">
      A modern, fast, and scalable web application built with Vue 3,
      TypeScript, and Vite. Experience the power of the Composition API
      and reactive programming.
    </p>

    <div class="flex gap-4 justify-center mt-8">
      <a
        href="https://vuejs.org/"
        target="_blank"
        class="bg-primary hover:bg-primary-hover text-white px-6 py-3 rounded-lg transition-colors font-semibold"
      >
        Learn Vue
      </a>
      <a
        href="https://vitejs.dev/"
        target="_blank"
        class="border border-border hover:border-border-hover px-6 py-3 rounded-lg transition-colors font-semibold text-text hover:text-heading"
      >
        Powered by Vite
      </a>
    </div>
  </div>
</template>
src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView,
      meta: {
        title: 'Home'
      }
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue'),
      meta: {
        title: 'About'
      }
    }
  ]
})

// Dynamic page titles
router.beforeEach((to) => {
  document.title = to.meta.title
    ? `${to.meta.title} | Vue App`
    : 'Vue App'
})

export default router
src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './assets/main.css'

const app = createApp(App)

app.use(router)
app.mount('#app')
package.json
{
  "name": "vue-app",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "type-check": "vue-tsc --noEmit",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
    "format": "prettier --write src/"
  },
  "dependencies": {
    "vue": "^3.5.13",
    "vue-router": "^4.5.0"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.10.4",
    "@tsconfig/node20": "^20.1.4",
    "@types/node": "^22.10.1",
    "@vitejs/plugin-vue": "^5.2.1",
    "@vue/eslint-config-prettier": "^10.1.0",
    "@vue/eslint-config-typescript": "^14.1.3",
    "@vue/tsconfig": "^0.7.0",
    "autoprefixer": "^10.4.20",
    "eslint": "^8.57.1",
    "eslint-plugin-vue": "^9.31.0",
    "postcss": "^8.5.1",
    "prettier": "^3.4.2",
    "tailwindcss": "^3.4.17",
    "typescript": "~5.7.2",
    "vite": "^6.0.3",
    "vue-tsc": "^2.2.0"
  }
}
tsconfig.json
{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.node.json"
    },
    {
      "path": "./tsconfig.app.json"
    }
  ]
}
tsconfig.app.json
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
tsconfig.node.json
{
  "extends": "@tsconfig/node20/tsconfig.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "cypress.config.*",
    "nightwatch.conf.*",
    "playwright.config.*"
  ],
  "compilerOptions": {
    "composite": true,
    "noEmit": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"]
  }
}
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
    port: 3000,
    open: true
  },
  build: {
    outDir: 'dist',
    sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router']
        }
      }
    }
  }
})
tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      colors: {
        'background': 'var(--color-background)',
        'background-soft': 'var(--color-background-soft)',
        'background-mute': 'var(--color-background-mute)',
        'border': 'var(--color-border)',
        'border-hover': 'var(--color-border-hover)',
        'heading': 'var(--color-heading)',
        'text': 'var(--color-text)',
        'text-soft': 'var(--color-text-soft)',
        'primary': {
          DEFAULT: 'var(--color-primary)',
          hover: 'var(--color-primary-hover)',
          soft: 'var(--color-primary-soft)',
        }
      },
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
      }
    },
  },
  plugins: [],
}
postcss.config.js
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
env.d.ts
/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>
README.md
# Vue 3 Modern Template

A modern Vue 3 application built with Composition API, TypeScript, Vue Router, and Tailwind CSS.

## Features

- ⚔ **Vue 3** - Latest version with Composition API
- šŸš€ **Vite** - Lightning fast build tool with HMR
- šŸ“ **TypeScript** - Full TypeScript support with strict mode
- šŸ›£ļø **Vue Router** - Official router with dynamic imports
- šŸŽØ **Tailwind CSS** - Utility-first CSS framework
- šŸŒ™ **Dark Mode** - Built-in dark mode support
- šŸ“± **Responsive** - Mobile-first responsive design
- šŸŽÆ **ESLint & Prettier** - Code linting and formatting
- šŸ”§ **Path Aliases** - Clean imports with @ alias
- šŸ—ļø **Component Structure** - Well-organized component architecture

## Getting Started

Install dependencies:

```bash
# npm
npm install

# pnpm
pnpm install

# yarn
yarn install

# bun
bun install
```

## Development

Run the development server:

```bash
# npm
npm run dev

# pnpm
pnpm run dev

# yarn
yarn dev

# bun
bun run dev
```

The application will open at [http://localhost:3000](http://localhost:3000).

## Production

Build for production:

```bash
# npm
npm run build

# pnpm
pnpm run build

# yarn
yarn build

# bun
bun run build
```

Preview production build:

```bash
# npm
npm run preview

# pnpm
pnpm run preview

# yarn
yarn preview

# bun
bun run preview
```

## Development Tools

Type checking:
```bash
npm run type-check
```

Lint and fix code:
```bash
npm run lint
```

Format code:
```bash
npm run format
```

## Project Structure

```
ā”œā”€ā”€ public/              # Static assets
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ assets/         # CSS and other assets
│   ā”œā”€ā”€ components/     # Reusable Vue components
│   ā”œā”€ā”€ router/         # Vue Router configuration
│   ā”œā”€ā”€ views/          # Page components
│   ā”œā”€ā”€ App.vue         # Root component
│   └── main.ts         # Application entry point
ā”œā”€ā”€ index.html          # HTML template
ā”œā”€ā”€ vite.config.ts      # Vite configuration
ā”œā”€ā”€ tailwind.config.js  # Tailwind configuration
└── tsconfig.*.json     # TypeScript configurations
```

## Key Technologies

- **Vue 3**: Modern reactive framework with Composition API
- **TypeScript**: Type-safe JavaScript with excellent IDE support
- **Vite**: Next-generation frontend build tool
- **Vue Router**: Official routing solution for Vue.js
- **Tailwind CSS**: Utility-first CSS framework
- **ESLint**: Code linting and error detection
- **Prettier**: Code formatting and style consistency

## Component Features

- **Composition API**: Modern Vue 3 syntax with `<script setup>`
- **TypeScript Props**: Type-safe component props with interfaces
- **Reactive State**: Vue's reactive system with `ref()` and `reactive()`
- **Navigation**: Vue Router with dynamic page titles
- **Responsive Design**: Mobile-first approach with Tailwind
- **Dark Mode**: CSS custom properties with system preference detection

## Learn More

- [Vue 3 Documentation](https://vuejs.org/)
- [Vue Router Documentation](https://router.vuejs.org/)
- [Vite Documentation](https://vitejs.dev/)
- [Tailwind CSS Documentation](https://tailwindcss.com/)
- [TypeScript Documentation](https://www.typescriptlang.org/)