This is a boilerplate for starting Nuxt3 projects with Vite, TypeScript, ESLint, Tailwind CSS, Pinia and Docker.
- Vite ⚡: Utilize the fast build tool for web development.
- TypeScript 🛡️: Write safer and more maintainable code with TypeScript.
- ESLint & Stylistic 🧹: Maintain code quality and consistency with ESLint (Flat config) and Stylistic.
- Tailwind CSS 🌬️: Rapidly build custom user interfaces with Tailwind CSS.
- Pinia 🍍: Best store for Vue & Nuxt.
- Docker 🐳: Containerize your application for easy deployment and scalability.
- Custom Composables 🛠️: Simplify API handling and metadata management with custom composable utilities like
useApi
.
Before getting started, ensure you have the following installed:
- Node.js (v20 or higher but LTS
v22.14
recommended) - npm, pnpm or Yarn package manager (pnpm recommended)
- Docker (if you plan to use Docker for containerization)
- Clone the repo:
git clone https://github.com/mdotme/nuxt-starter my-awesome-project
- Navigate to the cloned directory:
cd my-awesome-project
- Install deps:
pnpm i
- In the root directory, there is example env file:
.env.example
. - Copy to
.env
:
cp .env.example .env
- Modify
.env
.
- ESLint & Prettier: Configuration files for ESLint in
eslint.config.mts
file. - Tailwind CSS: Customize Tailwind CSS settings in the
./assets/css/tailwind.css
file.
Sample flat project structure for Nuxt3. If your project is more complex and bigger than simple landing page consider using Nuxt layers.
Sample vue file:
<script setup lang="ts">
interface Props {
loading?: boolean; // Boolean props should be optional
}
const props = defineProps<Props>();
const emit = defineEmits<{
submit: [data: Record<string, any>];
}>();
// Project provided first
const { $api } = useNuxtApp();
const route = useRoute();
const { t } = useI18n();
const localePath = useLocalePath()
// Custom composables
const api = useApi()
// Stores
const authStore = useAuthStore() // Name just store if it's related to store like Login.vue
// Other stuff
const data = ref()
function sayHi() {
console.log("HII")
}
const getData = computed(() => data.value)
watch(data, () => {
console.log("Do something")
})
const
</script>
<template>...</template>
<style scoped>
...
</style>
Directories & Files:
/my-awesome-project
├── assets/
│ ├── css/
│ ├── fonts/
│ └── images/
│
├── composables/
│ ├── useApi.ts
│ ├── useApiFetch.ts
│
├── layouts/
│ ├── default.vue
│ └── auth.vue
│
├── middleware/
│ └── auth.global.ts
│
├── pages/
│ ├── index.vue
│ ├── login.vue
│ ├── register.vue
│ └── profile.vue
│
├── plugins/
│ └── api.ts
│
├── public/
│ └── favicon.ico
│
├── stores/
│ ├── auth.store.ts
│ └── user.store.ts
│
├── types/
│ ├── auth.types.ts
│ ├── common.types.ts
│ └── enums/
│ ├── roles.enum.ts
│ └── status.enum.ts
│
├── components/
│ ├── Auth/
│ │ ├── LoginForm.vue
│ │ └── RegisterForm.vue
│ └── User/
│ └── ProfileCard.vue
│
├── utils/
│ ├── sum.util.ts
│ └── format-date.util.ts
│
├── constants/
│ ├── maska.const.ts
│ └── regexes.const.ts
│
├── app.vue
├── error.vue
├── nuxt.config.ts
...
- Composable files must be same as composable function names (
useCamelCase.ts
) - Middlewares must be
kebab-case.ts
- Stores must be
kebab-case.store.ts
with store suffix - Types must be
kebab-case.types.ts
with types suffix - Enums must be inside types directory and
kebab-case.enum.ts
with enum suffix - Directories and component names inside
components/
directory all must bePascal/Case.vue
- Utilities must be
kebab-case.util.ts
with util prefix - Constants must be
kebab-case.const.ts
with const prefix
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.