home / skills / secondsky / claude-skills / bun-nuxt

bun-nuxt skill

/plugins/bun/skills/bun-nuxt

This skill helps you run Nuxt 3 apps on Bun for faster development, building, and production previews.

npx playbooks add skill secondsky/claude-skills --skill bun-nuxt

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.0 KB
---
name: "Bun Nuxt"
description: Use when running Nuxt 3 with Bun runtime, building Vue/Nuxt apps with Bun, or configuring Nuxt projects to use Bun for development and production.
---

# Bun Nuxt

Run Nuxt 3 applications with Bun for faster development.

## Quick Start

```bash
# Create new Nuxt project
bunx nuxi@latest init my-app
cd my-app

# Install dependencies
bun install

# Development
bun run dev

# Build
bun run build

# Preview production
bun run preview
```

## Project Setup

### package.json

```json
{
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "nuxt": "^4.0.0",
    "vue": "^3.5.0"
  }
}
```

### Use Bun Runtime

```json
{
  "scripts": {
    "dev": "bun --bun nuxt dev",
    "build": "bun --bun nuxt build",
    "preview": "bun --bun .output/server/index.mjs"
  }
}
```

## Configuration

### nuxt.config.ts

```typescript
export default defineNuxtConfig({
  // Enable SSR
  ssr: true,

  // Nitro configuration
  nitro: {
    // Use Bun preset
    preset: "bun",

    // External packages
    externals: {
      external: ["bun:sqlite"],
    },
  },

  // Development
  devServer: {
    port: 3000,
  },

  // Modules
  modules: ["@nuxt/ui", "@pinia/nuxt"],
});
```

## Using Bun APIs

### Server Routes

```typescript
// server/api/users.ts
import { Database } from "bun:sqlite";

export default defineEventHandler(async (event) => {
  const db = new Database("data.sqlite");
  const users = db.query("SELECT * FROM users").all();
  db.close();

  return users;
});
```

### Server Middleware

```typescript
// server/middleware/auth.ts
export default defineEventHandler(async (event) => {
  const token = getHeader(event, "Authorization");

  if (!token && event.path.startsWith("/api/protected")) {
    throw createError({
      statusCode: 401,
      message: "Unauthorized",
    });
  }
});
```

### File Operations

```typescript
// server/api/files/[name].ts
export default defineEventHandler(async (event) => {
  const name = getRouterParam(event, "name");
  const file = Bun.file(`./data/${name}`);

  if (!(await file.exists())) {
    throw createError({
      statusCode: 404,
      message: "File not found",
    });
  }

  return file.text();
});
```

## Composables

### useFetch with Server Data

```vue
<script setup lang="ts">
// Fetches from server/api/users.ts
const { data: users, pending, error } = await useFetch("/api/users");
</script>

<template>
  <div v-if="pending">Loading...</div>
  <div v-else-if="error">Error: {{ error.message }}</div>
  <ul v-else>
    <li v-for="user in users" :key="user.id">{{ user.name }}</li>
  </ul>
</template>
```

### Server-Only Composables

```typescript
// composables/useDatabase.ts
export const useDatabase = () => {
  // Only runs on server
  if (process.server) {
    const { Database } = require("bun:sqlite");
    return new Database("data.sqlite");
  }
  return null;
};
```

## Server Utilities

### H3 Event Handling

```typescript
// server/api/users.post.ts
export default defineEventHandler(async (event) => {
  // Read body
  const body = await readBody(event);

  // Get query params
  const query = getQuery(event);

  // Get headers
  const auth = getHeader(event, "Authorization");

  // Get cookies
  const session = getCookie(event, "session");

  // Set cookie
  setCookie(event, "visited", "true", {
    httpOnly: true,
    maxAge: 60 * 60 * 24,
  });

  return { success: true };
});
```

### Database Utility

```typescript
// server/utils/db.ts
import { Database } from "bun:sqlite";

let db: Database | null = null;

export function getDb() {
  if (!db) {
    db = new Database("data.sqlite");
    db.run(`
      CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        name TEXT NOT NULL
      )
    `);
  }
  return db;
}
```

```typescript
// server/api/users.ts
export default defineEventHandler(() => {
  const db = getDb();
  return db.query("SELECT * FROM users").all();
});
```

## Nitro Features

### Server Plugins

```typescript
// server/plugins/database.ts
export default defineNitroPlugin((nitroApp) => {
  // Initialize on startup
  console.log("Database initialized");

  // Cleanup on shutdown
  nitroApp.hooks.hook("close", () => {
    console.log("Closing database");
  });
});
```

### Scheduled Tasks

```typescript
// server/tasks/cleanup.ts
export default defineTask({
  meta: {
    name: "cleanup",
    description: "Clean old data",
  },
  run() {
    const db = getDb();
    db.run("DELETE FROM logs WHERE created_at < ?", [
      Date.now() - 7 * 24 * 60 * 60 * 1000,
    ]);
    return { result: "Cleaned" };
  },
});
```

## Deployment

### Build for Bun

```bash
# Build with Bun preset
NITRO_PRESET=bun bun run build

# Run production server
bun .output/server/index.mjs
```

### Docker

```dockerfile
FROM oven/bun:1 AS builder

WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

COPY . .
RUN bun run build

FROM oven/bun:1

WORKDIR /app
COPY --from=builder /app/.output /app/.output

EXPOSE 3000

CMD ["bun", ".output/server/index.mjs"]
```

### Environment Variables

```bash
# .env
NUXT_PUBLIC_API_URL=https://api.example.com
DATABASE_URL=./data.sqlite
```

```typescript
// Access in code
const config = useRuntimeConfig();
console.log(config.public.apiUrl);
console.log(config.databaseUrl); // Server only
```

```typescript
// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    databaseUrl: "",
    public: {
      apiUrl: "",
    },
  },
});
```

## Common Errors

| Error | Cause | Fix |
|-------|-------|-----|
| `Cannot find bun:sqlite` | Wrong preset | Set `nitro.preset: "bun"` |
| `Module parse failed` | Build issue | Clear `.nuxt` and rebuild |
| `Hydration mismatch` | Server/client diff | Check async data |
| `EADDRINUSE` | Port in use | Change port or kill process |

## When to Load References

Load `references/nitro.md` when:
- Advanced Nitro configuration
- Storage drivers
- Cache handlers

Load `references/deployment.md` when:
- Edge deployment
- Cloudflare Workers
- Vercel/Netlify

Overview

This skill provides clear, production-ready guidance for running Nuxt 3 applications on the Bun runtime. It covers project setup, scripts, Nitro configuration, Bun APIs, server utilities, deployment, and common errors to get apps running faster in development and production with Bun.

How this skill works

The skill describes how to scaffold a Nuxt 3 project with Bun, install dependencies, and run dev/build/preview commands using bun or bunx. It explains Nitro's bun preset, how to expose Bun-specific APIs (bun:sqlite, Bun.file), and how to wire server routes, middleware, composables, plugins, scheduled tasks, and environment config for Bun deployments.

When to use it

  • When developing or building Nuxt 3 apps that should run on the Bun runtime for faster cold start and build times.
  • When you want to use Bun-specific APIs like bun:sqlite or Bun.file in server routes and utilities.
  • When deploying Nuxt apps to environments where Bun is the runtime (containers using oven/bun images).
  • When configuring Nitro to use the bun preset and external Bun packages.
  • When converting an existing Node-based Nuxt project to Bun for dev/prod parity.

Best practices

  • Set nitro.preset to "bun" in nuxt.config.ts and list Bun externals (e.g., "bun:sqlite") to avoid missing imports.
  • Use server-only composables and process.server checks for Bun-native modules to prevent client-side bundling errors.
  • Keep package.json scripts consistent: dev, build, preview, and postinstall (nuxt prepare) for smooth CI/CD.
  • Use Bun.file and bun:sqlite carefully and close databases after use; centralize DB init with a singleton helper.
  • Build with NITRO_PRESET=bun and test preview locally before containerizing; include .output handling in Docker.

Example use cases

  • A small SaaS using Nuxt 3 with an embedded SQLite DB via bun:sqlite for low-latency server endpoints.
  • Migrating a Nuxt app from Node to Bun to reduce development iteration time and speed production cold starts.
  • Creating API routes that read/write files using Bun.file for a lightweight file storage microservice.
  • Packaging a Nuxt app into a Docker image based on oven/bun for consistent Bun runtime in production.
  • Implementing scheduled cleanup tasks using Nitro tasks that run against a Bun-backed database.

FAQ

How do I enable Bun support in Nitro?

Set nitro.preset = "bun" in nuxt.config.ts and add any Bun-specific externals like "bun:sqlite".

What script should I use to run production with Bun?

Build with NITRO_PRESET=bun bun run build then run the server with bun .output/server/index.mjs.