A production-ready Vue 3 starter template that pairs TypeScript, Vite, and an opinionated architecture focused on fast development, authentication-ready dashboards, and maintainable code.
This template helps teams bootstrap admin dashboards or SaaS back offices. It provides:
- A scalable application shell with layout switching and route-based guards.
- A fully wired authentication flow with session persistence and API token injection.
- Built-in developer tooling for linting, formatting, and type safety.
- Mock data services so you can iterate on UI without a backend.
- Framework: Vue 3 with the Composition API and
<script setup>syntax. - Language: TypeScript for static typing across the stack.
- Build Tool: Vite for fast HMR and optimized production builds.
- State Management: Pinia with persisted state support.
- Routing: Vue Router with layered middleware guards.
- Networking: Axios clients abstracted for guest and authenticated requests.
- UI Utilities: Tailwind CSS, class-variance-authority, and shadcn-inspired components.
- Tooling: Bun task runner, ESLint + Oxlint, Prettier, and Vue TSC.
- βοΈ Convention-driven project structure ready for scaling modules and features.
- π Authentication middleware and login flow with persisted sessions.
- π§ Dynamic layout system that reacts to route metadata.
- π Internationalization and SEO meta management via
@unhead/vue. - π§ͺ Component testing setup and strict type checking.
- π§° Mock server powered by Mirage JS for API prototyping.
The Vue app registers head management, routing, state stores, and dayjs plugins before mounting, optionally spinning up a Mirage mock server based on environment flags (@filepath:src/main.ts#1-27).
Routes are declared as lazy-loaded modules with auth and guest metadata. Global navigation guards enforce access control using composable middleware (@filepath:src/routes/router.ts#1-13, @filepath:src/routes/routes.ts#1-87).
The login page calls the authentication API, persists tokens via Pinia, and redirects to the dashboard. Guest routes redirect authenticated users, while protected routes require a valid session (@filepath:src/pages/login.vue#37-44, @filepath:src/stores/auth.store.ts#4-39, @filepath:src/routes/middlewares/auth.middleware.ts#5-20).
Pinia stores are instantiated once, enhanced with persisted state, and hot-module-ready to keep sessions stable during development (@filepath:src/stores/index.ts#1-15).
Dual Axios instances power guest and authenticated calls. Authenticated requests automatically inject the bearer token from the Pinia store before dispatching (@filepath:src/api/client.ts#1-25).
Route metadata maps to layout components resolved at runtime. The default AppLayout combines sidebar navigation, breadcrumb support, and transition wrappers (@filepath:src/App.vue#1-71, @filepath:src/layouts/AppLayout.vue#1-57).
Global error captures push failures into a shared composable, while vue-sonner toasts surface feedback to end users (@filepath:src/App.vue#47-71).
When VITE_MOCK_SERVER is enabled, Mirage JS bootstraps fixture-backed endpoints so the front end can run without a live backend (@filepath:src/plugins/miragejs/server.ts#1-200).
- Email:
[email protected] - Password:
123 - OTP:
12345(used for both account verification and forgot-password flows)
Use these values to explore the authentication flow locally when the mock server is active.
@unhead/vue and the i18n plugin configure dynamic titles and localized content at startup (@filepath:src/main.ts#1-27, @filepath:src/plugins/i18n/index.ts#1-200).
- Bun β₯ 1.1
- Node.js β₯ 24 (for tooling compatibility)
# Clone the repository
git clone https://github.com/ducconit/vue-starter-template.git
cd vue-starter-template
# Install dependencies
bun install
# Start the development server
bun run devThe app will be available at http://localhost:5173 by default.
bun run build| Script | Description |
|---|---|
bun run dev |
Start the Vite development server with HMR. |
bun run build |
Type-check and generate a production build. |
bun run preview |
Preview the production build locally. |
bun run type-check |
Run Vue TSC in build mode. |
bun run lint |
Format code, run Oxlint, and execute ESLint. |
bun run lint:oxlint |
Run Oxlint with autofix for correctness issues. |
bun run lint:eslint |
Run ESLint with the Vue + TypeScript config. |
bun run format |
Format source files with Prettier. |
Copy .env.example into .env and adjust values as needed.
| Variable | Description | Default |
|---|---|---|
VITE_APP_NAME |
Application name displayed in the UI. | "Template Admin" |
VITE_BASE_URL |
Base URL for API requests. | /api |
VITE_MOCK_SERVER |
Toggle Mirage mock server (true / false). |
true |
βββ public/ # Static assets served as-is
βββ src/
β βββ api/ # Axios clients and API modules
β βββ components/ # UI library and reusable building blocks
β βββ composables/ # Shared Vue composables
β βββ layouts/ # Application shell components
β βββ pages/ # Route-level views (lazy-loaded)
β βββ plugins/ # App-wide plugin registrations (i18n, dayjs, mirage)
β βββ routes/ # Router config and middleware guards
β βββ stores/ # Pinia stores and persisted state setup
β βββ assets/ # Styles, images, and static resources
β βββ App.vue # Root component with layout resolution
β βββ main.ts # Entry point bootstrapping the app
βββ eslint.config.ts # ESLint multi-runner configuration
βββ package.json # Dependencies and Bun scripts
βββ tsconfig*.json # TypeScript configurations
βββ vite.config.ts # Vite bundler configuration
βββ bun.lock # Bun lockfile
- Type safety is enforced via
vue-tscduring builds. - Oxlint and ESLint keep the codebase aligned with Vue, TypeScript, and Prettier conventions.
- Component-level tests can be added under
src/components/__tests__using Vitest.
We welcome contributions! To get started:
- Fork the repository.
- Create a branch:
git checkout -b feat/amazing-improvement. - Commit using Conventional Commits:
git commit -m "feat: add amazing improvement". - Push your branch:
git push origin feat/amazing-improvement. - Open a Pull Request describing your changes and rationale.
Please ensure linting and type checks pass before submitting.
This project is licensed under the MIT License. See the LICENSE file for details.