STACK IT FAST
ALL RULES & SKILLS

Nuxt 3 + Vue + PostgreSQL

Raw .MD nuxt-vue-postgres
CURATED RULE AGENTS.MD + CLAUDE.MD + .MDC + SKILL.MD

Production guidelines for Nuxt 3 server routes and universal rendering, Vue 3 Composition API, and PostgreSQL via a typed query layer.

AGENTS.md
Paste in your project root
SKILL.md
Installs to .claude/skills/nuxt-vue-postgres
INTERACTIVE RULE & SKILL VIEWER (AGENTS.MD, CLAUDE.MD, .MDC & SKILL.MD)
Optimized for:CursorClaude CodeWindsurfAGY
AGENTS.md·38 lines · 3.5 KB
1# Project Architecture & Guidelines (Nuxt 3 + Vue + PostgreSQL)
2
3## 1. System Architecture
4- **Framework**: Nuxt 3 (Vue 3 Composition API, `<script setup>`, universal rendering).
5- **Server Layer**: Nitro server routes in `server/api/` for backend logic — Nuxt ships its own request-handling runtime, no separate Express/Fastify process needed.
6- **Database**: PostgreSQL, accessed from server routes only, via a typed query layer (Drizzle ORM or `postgres`/`pg` with hand-written types) — for solo builders and small teams, default to a managed provider (Supabase or Neon) rather than operating your own instance. The self-hosted examples below (Baserow, Directus, n8n) run their own Postgres because they're full self-hostable platforms, not because a typical Nuxt app needs to.
7- **Validation**: TypeScript strict mode + Zod (or `valibot`) for both server route input and form validation.
8
9## 2. Server Routes & Data Access
10- Define API endpoints as files under `server/api/` (e.g. `server/api/projects.get.ts`, `server/api/projects/[id].patch.ts`) — the filename encodes the route and HTTP method.
11- Never import a database client into a `.vue` component or a `composables/` file that runs on the client; database access is server-route-only.
12- Use `useFetch`/`useAsyncData` in components/pages to call server routes with automatic SSR data hydration — avoid raw `fetch` in `onMounted` for data needed on first render.
13
14## 3. Composition API Conventions
15- Extract shared reactive logic into `composables/` (auto-imported by Nuxt); one concern per composable (`useAuth`, `useProjectFilters`).
16- Prefer `<script setup lang="ts">` with typed `defineProps`/`defineEmits` over the Options API for all new components.
17- Use Pinia for cross-page client state; avoid global mutable state outside a store.
18
19## 4. Database Client & Migrations
20- Singleton PostgreSQL client instantiated once in a Nitro plugin or a `server/utils/db.ts` module, reused across requests.
21- If using Drizzle: `drizzle-kit generate` for migrations, applied via a deploy-time migration script — never `drizzle-kit push` in production.
22- Default to Supabase or Neon for the database itself (managed Postgres, free tier, zero server ops) — use their built-in pooler (Supabase's transaction pooler, or Neon's pooled connection string) when deploying server routes to a serverless/edge runtime, since each cold start can otherwise open a new connection.
23
24## 5. Common Pitfalls / Coding Standards
25- ❌ Calling `fetch('/api/...')` directly instead of `useFetch`/`$fetch` — loses SSR hydration and can cause duplicate requests on the client.
26- ❌ Putting database credentials in `runtimeConfig.public` instead of the private `runtimeConfig` — public config ships to the browser.
27- ✅ Validate every server route's `body`/`query` with Zod before it reaches the database layer.
28
29## 6. Testing Conventions
30- Vitest with `@nuxt/test-utils` for unit/component tests, and for testing server routes in isolation.
31- Playwright for e2e coverage of critical flows (auth, checkout, primary CRUD screens).
32- Run `nuxi typecheck` (wraps `vue-tsc`) as a required check — plain `tsc` doesn't understand `.vue` SFCs.
33
34## 7. Git Workflow & PR Conventions
35- Conventional Commits scoped to the route or composable, e.g. `fix(api/projects): enforce owner check on delete`.
36- Generated migrations ship in the same PR as the schema change they correspond to.
37- Require `nuxi typecheck` and `bun run build` green before merge.
38- Squash-merge; never run a migration `push` directly against a shared or production database from a feature branch.
ARCHITECTURE NOTES & IMPLEMENTATION GUIDE
Export as Markdown

Architecture Overview

Standardized production guidelines for Nuxt 3, Vue 3 Composition API, and PostgreSQL, using Nitro server routes as the backend layer.

Verified Real-World Adoption

This pattern is the backbone of several production internal-tool and developer-tool platforms: Baserow (no-code database, Nuxt + Vue frontend over a Django/FastAPI + PostgreSQL backend), Hoppscotch (API testing client, Vue + Nuxt + Node + PostgreSQL), Directus (headless CMS, Vue + Node + PostgreSQL), n8n (workflow automation, Vue + Node + PostgreSQL), and NocoDB (smart spreadsheet, Vue + Node + PostgreSQL/MySQL).

Key Architectural Nuances

  • Nitro as the Backend: Server routes deploy as part of the same Nuxt build output, targeting Node, Deno, or edge runtimes without a separate backend service to provision.
  • SSR Payload Reuse: useFetch/useAsyncData deduplicate server-rendered data on hydration, avoiding the double-fetch flash common in naive SPA-over-API setups.
FREQUENTLY ASKED QUESTIONS

Does this AGENTS.md work with Cursor, Claude Code, and Windsurf?

Yes — AGENTS.md is the open, cross-tool standard read by Cursor, Claude Code, Windsurf, and 30+ other agents. A dedicated .mdc file is also included for Cursor's native .cursor/rules format.

Why do server routes live under server/api/ instead of a separate backend?

Nuxt's Nitro engine is a full server runtime built into the framework, so server/api/ routes deploy alongside the frontend as one unit (to Node, a Cloudflare Worker, or a serverless function) without standing up a separate Express/Fastify service. This removes an entire deployment target and keeps client and server types in one project.

Why use useFetch instead of a plain fetch() call?

useFetch (and its lower-level $fetch) integrates with Nuxt's SSR payload: data fetched on the server during the initial render is serialized and reused on the client instead of being re-fetched, avoiding a duplicate request and a flash of loading state on hydration.

Do I need to self-host PostgreSQL for this stack?

No — for most Nuxt apps, point your DATABASE_URL at Supabase or Neon and skip running a Postgres server yourself; both have a free tier that covers a solo project or early-stage small team comfortably. The self-hosted tools referenced above (Baserow, Directus, n8n) run their own Postgres because they're distributed as self-hostable platforms, not because this stack requires it.

MORE AI AGENT CODING RULES & SKILLS
View All Rules & Skills