10 Dev Tricks to Build Your Nuxt App Faster

Practical tips and tricks to speed up your Nuxt development workflow, from auto-imports to DevTools and beyond.

Charles Allotey
Nuxt 3

The Mastering Nuxt FullStack Unleashed Course is here!

Get notified when we release new tutorials, lessons, and other expert Nuxt content.

Click here to view course

Building a Nuxt app can be incredibly productive when you know the right shortcuts and patterns. These aren't just tips - they're workflow improvements that'll save you hours of development time.

Let's dive into some techniques that'll make you a more efficient Nuxt developer.

1. Auto-Import Everything (Yes, Really)

Nuxt auto-imports components, composables, and utils by default. Stop writing import statements for everything.

Instead of this:

<script setup>
import { ref, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import MyButton from '~/components/MyButton.vue'

const count = ref(0)
const router = useRouter()
</script>

Just write this:

<script setup>
const count = ref(0)
const router = useRouter()
</script>

<template>
  <MyButton />
</template>

Want to auto-import your own utilities? Just put them in the composables/ or utils/ directory:

// utils/formatPrice.ts
export const formatPrice = (price: number) => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(price)
}

// Use anywhere without importing
const total = formatPrice(99.99)

Pro move: Check .nuxt/types/components.d.ts and .nuxt/types/imports.d.ts to see exactly what Nuxt is auto-importing. It's like having documentation that's always up to date.

2. Use Server Routes for Quick APIs

Need an API endpoint? Don't set up a separate backend. Just create a file in server/api/:

// server/api/users.get.ts
export default defineEventHandler(async (event) => {
  const users = await db.users.findAll()
  return users
})

// server/api/users/[id].get.ts
export default defineEventHandler(async (event) => {
  const id = getRouterParam(event, 'id')
  const user = await db.users.findById(id)
  return user
})

// server/api/users.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const user = await db.users.create(body)
  return user
})

Now you can fetch from these routes with $fetch('/api/users'). The .get, .post, .put, .delete suffixes automatically set the HTTP method.

3. Optimize Images Without Thinking

Unoptimized images can have a significant negative impact on your website performance, specifically the Largest Contentful Paint (LCP) score. NuxtImage is a module that offers plug-and-play image optimization solution for your Nuxt apps.

Install @nuxt/image:

npx nuxt module add image

Then replace your <img> tags with <NuxtImg>:

<NuxtImg 
  src="/hero-banner.jpg" 
  format="webp" 
  preload 
  loading="eager"
  fetch-priority="high" 
  width="1200" 
  height="600"
/>

It allows resizing and transforming your images using built-in optimizer or your favorite images CDN. NuxtImage handles optimization, lazy loading, and modern formats automatically. For images that can load later use the lazy prop.

<NuxtImg 
  src="/gallery-photo.jpg"
  loading="lazy"
  format="webp"
/>

You will instantly notice the massive performance difference.

4. Leverage the Nuxt MCP Server for Confident AI-Powered Assistance

Let's be brutally honest—we're all using AI to write code in 2025. And we've all been burned by AI agents suggesting outdated Nuxt syntax, or hallucinating component props that don't exist.

With the Nuxt MCP your AI agents generate suggestions based on current docs, not outdated information from the AI's training data. So you can not only build your Nuxt apps faster but also more confidently. You can find out more on the Nuxt MCP and how to set it up in this article.

5. Lazy Load Heavy Components

Got a big chart library or rich text editor? Don't load it until you need it:

<template>
  <div>
    <!-- This only loads when rendered -->
    <LazyRichTextEditor v-if="showEditor" />

    <!-- Or use the Lazy prefix -->
    <LazyDataVisualization :data="chartData" />
  </div>
</template>

Nuxt automatically code-splits lazy components. Just prefix any component with Lazy and it won't be in your initial bundle.

6. Global Middleware for Auth

Stop repeating auth checks on every page. Create global middleware:

// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const user = useUser()

  // Public routes
  const publicPages = ['/login', '/signup', '/']
  if (publicPages.includes(to.path)) {
    return
  }

  // Redirect to login if not authenticated
  if (!user.value) {
    return navigateTo('/login')
  }
  
  // or just gate everything under /admin/** with a rule like:
  if(to.path.startsWith('/admin') && !user.value){
    return navigateTo('/login')
  }
})

The .global suffix makes it run on every route automatically.

7. Use Nitro Storage for Caching

Need to cache API responses or expensive computations? Nitro provides a caching system built on top of it’s storage layer.

// server/api/expensive-data.get.ts
export default defineCachedEventHandler(async (event) => {

  const data = await fetchFromSlowAPI()

  return data
}, { maxAge: 60 * 60 /* 1 hour */ })

You can use different storage drivers like Redis, Cloudflare KV, or the filesystem.

Use the built in useStorage function directly for precise control, whenever you need it!

const cachedUser = useStorage().getItem(`user:${userId}`);
const user = cachedUser ?? await getUser();

8. DevTools Shortcuts

Nuxt Devtools overview panel displays info about the Nuxt version, number of pages on your site, components count, modules, and more.

Nuxt Devtools overview panel displays info about the Nuxt version, number of pages on your site, components count, modules, and more.

Nuxt DevTools are super powerful. Press Shift + Alt + D to open it and:

  • Pages tab: See all your routes and their metadata
  • Components tab: Browse all auto-imported components
  • Imports tab: See everything that's auto-imported
  • Hooks tab: Debug lifecycle hooks in real-time
  • Virtual Files tab: See what Nuxt generates under the hood
  • Even create your own custom tabs if you want!

The Components tab is especially useful - you can search for any component and see where it's used.

9. Quick API Mocking

Building a feature before the backend is ready? Mock your API routes:

// server/api/products.get.ts
export default defineEventHandler(() => {
  // Return mock data during development
  if (process.dev) {
    return [
      { id: 1, name: 'Product 1', price: 99 },
      { id: 2, name: 'Product 2', price: 149 }
    ]
  }

  // Real implementation for production
  return db.products.findAll()
})

Or use route rules to proxy to a real API:

export default defineNuxtConfig({
  routeRules: {
    '/api/**': {
      proxy: 'https://staging-api.example.com/**'
    }
  }
})

10. Custom Error Pages by Status Code

Create different error pages for different status codes:

<!-- error.vue -->
<script setup>
const props = defineProps({
  error: Object
})

const is404 = computed(() => props.error?.statusCode === 404)
const is500 = computed(() => props.error?.statusCode === 500)
</script>

<template>
  <div>
    <div v-if="is404">
      <h1>Page Not Found</h1>
      <p>The page you're looking for doesn't exist.</p>
    </div>

    <div v-else-if="is500">
      <h1>Server Error</h1>
      <p>Something went wrong on our end.</p>
    </div>

    <div v-else>
      <h1>Error {{ error?.statusCode }}</h1>
      <p>{{ error?.message }}</p>
    </div>

    <NuxtLink to="/">Go Home</NuxtLink>
  </div>
</template>

Bonus: Keyboard and CLI Shortcuts You Should Know

Here are some lesser-known shortcuts that'll speed up your workflow:

In the terminal:

  • npm run dev -- -o: Start dev server and open browser
  • npm run dev -- --host: Expose server to your network (great for mobile testing)

DevTools tricks:

  • Click any component in the DevTools to see its source code
  • Use the Timeline tab to debug hydration issues
  • The Inspector shows you which components are server-rendered vs client-rendered

Wrapping Up

These tricks aren't just about writing less code - they're about working smarter. Auto-imports eliminate boilerplate, server routes give you a full-stack framework in one project, and lazy loading keeps your bundles small.

The best part? Most of these work out of the box. Nuxt is designed to make you productive, and once you learn these patterns, you'll wonder how you ever built without them.


Start using these tricks today and watch your development speed improve. Your future self will thank you.

Charles Allotey
Charles is a Frontend Developer at Vueschool. Has a passion for building great experiences and products using Vue.js and Nuxt.

Follow MasteringNuxt on