Fix: Nuxt Instance Is Unavailable (@nuxt/kit) in Nuxt

Error message:
Nuxt instance is unavailable!
initialization 2025-01-25

What Causes This Error?

This error from @nuxt/kit occurs when you try to use Nuxt utilities that require an active Nuxt instance, but the instance hasn’t been created yet or you’re outside the Nuxt context.

Common Scenarios

1. Module Setup Running Too Early

// modules/my-module/index.ts
import { useNuxt } from '@nuxt/kit'

// ❌ Wrong - called at module import time
const nuxt = useNuxt()  // Error!

export default defineNuxtModule({
  setup(options, nuxt) {
    // ✅ Correct - nuxt is passed to setup
    console.log(nuxt.options.rootDir)
  }
})

2. Script Running Outside Nuxt

// scripts/generate.ts
import { useNuxt } from '@nuxt/kit'

// ❌ Wrong - no Nuxt instance in standalone script
const nuxt = useNuxt()

3. Hook Running After Nuxt Closes

// modules/my-module.ts
export default defineNuxtModule({
  setup(options, nuxt) {
    // ❌ Wrong - Nuxt may be closed when this runs
    setTimeout(() => {
      const n = useNuxt()  // Might fail
    }, 10000)
  }
})

The Fix

Use the Passed Nuxt Instance

// modules/my-module.ts
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
  meta: {
    name: 'my-module'
  },
  setup(options, nuxt) {
    // ✅ Use the nuxt parameter
    const resolver = createResolver(import.meta.url)

    // Access Nuxt options
    console.log('Root:', nuxt.options.rootDir)
    console.log('Dev:', nuxt.options.dev)

    // Add things to Nuxt
    addPlugin(resolver.resolve('./runtime/plugin'))
  }
})

For Standalone Scripts, Load Nuxt First

// scripts/generate.ts
import { loadNuxt, buildNuxt } from '@nuxt/kit'

async function main() {
  // ✅ Load Nuxt instance first
  const nuxt = await loadNuxt({
    rootDir: process.cwd(),
    dev: false
  })

  try {
    // Now you can use it
    console.log('Config:', nuxt.options.runtimeConfig)

    // Build if needed
    await buildNuxt(nuxt)
  } finally {
    // Always close
    await nuxt.close()
  }
}

main().catch(console.error)

Use Hooks Instead of Direct Access

// modules/my-module.ts
export default defineNuxtModule({
  setup(options, nuxt) {
    // ✅ Use hooks for lifecycle events
    nuxt.hook('ready', () => {
      // Nuxt is fully ready here
      console.log('Nuxt is ready!')
    })

    nuxt.hook('close', () => {
      // Cleanup before Nuxt closes
      console.log('Nuxt is closing')
    })

    nuxt.hook('build:before', () => {
      // Before build starts
    })
  }
})

Common @nuxt/kit Utilities

Safe to Use in Module Setup

import {
  defineNuxtModule,
  addPlugin,
  addComponent,
  addImports,
  addServerHandler,
  createResolver,
  addTemplate
} from '@nuxt/kit'

export default defineNuxtModule({
  setup(options, nuxt) {
    const resolver = createResolver(import.meta.url)

    // ✅ All these are safe
    addPlugin(resolver.resolve('./runtime/plugin'))

    addComponent({
      name: 'MyComponent',
      filePath: resolver.resolve('./runtime/components/MyComponent.vue')
    })

    addImports({
      name: 'useMyFeature',
      from: resolver.resolve('./runtime/composables')
    })
  }
})

Require Active Nuxt Instance

import { useNuxt, tryUseNuxt } from '@nuxt/kit'

// useNuxt() - throws if no instance
// tryUseNuxt() - returns undefined if no instance

export default defineNuxtModule({
  setup(options, nuxt) {
    // ✅ Safe - we have nuxt from parameter

    // If you must use useNuxt elsewhere in module:
    nuxt.hook('ready', () => {
      // ✅ Safe - Nuxt is definitely available
      const n = useNuxt()
    })
  }
})

Checking for Nuxt Instance

import { tryUseNuxt } from '@nuxt/kit'

function doSomething() {
  const nuxt = tryUseNuxt()

  if (!nuxt) {
    console.warn('No Nuxt instance available')
    return
  }

  // Safe to use nuxt
  console.log(nuxt.options.dev)
}

Loading Nuxt for Scripts

Basic Loading

import { loadNuxt } from '@nuxt/kit'

const nuxt = await loadNuxt({
  rootDir: '.',
  dev: false,
  overrides: {
    // Override any config
  }
})

With Build

import { loadNuxt, buildNuxt } from '@nuxt/kit'

const nuxt = await loadNuxt({ dev: false })
await buildNuxt(nuxt)
await nuxt.close()

For Testing

import { loadNuxt } from '@nuxt/kit'
import { describe, it, beforeAll, afterAll } from 'vitest'

describe('My Module', () => {
  let nuxt

  beforeAll(async () => {
    nuxt = await loadNuxt({
      rootDir: './fixtures/basic',
      dev: false
    })
  })

  afterAll(async () => {
    await nuxt?.close()
  })

  it('should work', () => {
    expect(nuxt.options.modules).toContain('my-module')
  })
})

Quick Checklist

  • Don’t call useNuxt() at module top level
  • Use the nuxt parameter passed to setup()
  • Use hooks for lifecycle events
  • Use tryUseNuxt() for optional access
  • Load Nuxt explicitly in standalone scripts
  • Always close Nuxt when done (nuxt.close())