bun-nuxt
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.
What this skill does
# 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
```
## Secure Installation
Scaffolding tools like `bunx nuxi init` download and execute remote code. Before running, follow supply chain security best practices:
- **Block post-install scripts** — Bun disables them by default; allow specific packages via `trustedDependencies` in `package.json`
- **Cooldown period** — Configure `minimumReleaseAge` in `bunfig.toml` to wait 7 days for new versions
- **Audit before installing** — Run `socket package score npm <pkg>` or use `socket npm install <pkg>` to check packages
Load the `dependency-upgrade` skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.
## 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
Related in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.