Skip to content
← All questions
🔥 Advanced

What are Nuxt layers and when would you use them?

💚 Nuxt🏗️ Architecture

Layers let you share partial Nuxt applications across projects. A layer can include components, composables, pages, layouts, middleware, plugins, server routes, and config. Think of them as Nuxt's inheritance model: your project extends one or more layers, and everything merges automatically.

Diagram showing project extending base and shared layers

Using a layer ​

Add it to extends in your config:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    '@my-org/base-layer', // from npm
    '../shared-layer', // local directory
    'github:user/repo#main' // from git
  ]
})

Everything the layer provides (components, composables, pages, etc.) becomes available in your project with no additional configuration.

Creating a layer ​

A layer is a minimal Nuxt project with a nuxt.config.ts:

my-layer/
├── nuxt.config.ts
├── components/
│   ├── BaseButton.vue
│   └── BaseCard.vue
├── composables/
│   └── useTheme.ts
├── layouts/
│   └── default.vue
├── server/
│   └── api/
│       └── health.get.ts
└── package.json
ts
// my-layer/nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui']
})

The consuming project gets all components, composables, layouts, and server routes from the layer, plus any modules it declares.

Overriding layer files ​

Your project always wins over the layer. If the layer provides components/BaseButton.vue and you create the same file, your version takes precedence.

Priority order (highest to lowest):

  1. Your project files
  2. Auto-scanned layers from ~~/layers directory (sorted alphabetically, Z has higher priority than A)
  3. Layers in extends (first entry wins over later ones)

Auto-scanned layers ​

Place layers in a layers/ directory and Nuxt discovers them automatically:

my-app/
├── layers/
│   ├── base/
│   │   ├── nuxt.config.ts
│   │   └── components/
│   └── theme/
│       ├── nuxt.config.ts
│       └── composables/
├── nuxt.config.ts
└── pages/

No extends config needed for these.

Practical example: theme layer ​

A reusable theme shared across multiple apps:

ts
// theme-layer/app.config.ts
export default defineAppConfig({
  theme: {
    primaryColor: '#00dc82',
    darkMode: false
  }
})
ts
// theme-layer/composables/useTheme.ts
export function useTheme() {
  const config = useAppConfig()
  const isDark = useState('dark', () => config.theme.darkMode)
  const toggle = () => (isDark.value = !isDark.value)
  return { isDark, toggle }
}

The consuming app overrides only what it needs:

ts
// my-app/app.config.ts
export default defineAppConfig({
  theme: {
    primaryColor: '#ff6347' // override, darkMode stays false
  }
})

Publishing as an npm package ​

json
{
  "name": "@my-org/base-layer",
  "version": "1.0.0",
  "type": "module",
  "main": "./nuxt.config.ts",
  "dependencies": {
    "@nuxt/ui": "^3.0.0"
  }
}

Then any project can npm install @my-org/base-layer and extend it.

Scaffolding a new layer ​

bash
npx nuxi init --template layer my-layer

Layers vs modules ​

LayerModule
What it isA partial Nuxt app (files and config)A build-time plugin (code that runs during build)
Can provideComponents, pages, layouts, composables, server routes, configAnything via @nuxt/kit programmatic API
MergingFile-based, automaticProgrammatic, explicit
OverrideReplace the file in your projectConfigure via module options
Use whenSharing a base app, design system, or preset across projectsAdding a capability (analytics, auth, image optimization)

See also: How do Nuxt modules work? · What is the Nuxt directory structure? · How do you deploy a Nuxt app?

References ​

Released under the MIT License.