{"id":27071,"plugin_id":"plugin_connector_690a90ec05c881918afb6a55dc9bbaa1","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-06T18:03:11.893Z","digest":"02414ff36c29987fa850ee0d345fa78dcd48ae7da563b926f480cd781732ec86","against":24899,"payload":{"description":"Vercel storage expert guidance — Blob, Global Config (formerly Edge Config), and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":176}],"name":"vercel-storage","skill_md_contents":"---\nname: vercel-storage\ndescription: Vercel storage expert guidance — Blob, Global Config (formerly Edge Config), and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/storage\"\n  sitemap: \"https://vercel.com/sitemap.xml\"\n  pathPatterns:\n    - 'lib/blob/**'\n    - 'lib/storage/**'\n    - 'src/lib/blob/**'\n    - 'src/lib/storage/**'\n    - 'lib/blob.*'\n    - 'lib/storage.*'\n    - 'lib/edge-config.*'\n    - 'lib/global-config.*'\n    - 'src/lib/blob.*'\n    - 'src/lib/storage.*'\n    - 'src/lib/edge-config.*'\n    - 'src/lib/global-config.*'\n    - 'supabase/**'\n    - 'lib/supabase.*'\n    - 'src/lib/supabase.*'\n    - 'prisma/schema.prisma'\n    - 'prisma/**'\n  bashPatterns:\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@prisma/client\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bconvex\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@libsql/client\\b'\n  importPatterns:\n    - \"@vercel/blob\"\n    - \"@vercel/edge-config\"\n    - \"@vercel/global-config\"\n    - \"@neondatabase/serverless\"\n    - \"@upstash/redis\"\n    - \"@vercel/kv\"\n    - \"@vercel/postgres\"\n    - \"@supabase/supabase-js\"\n    - \"@prisma/client\"\nvalidate:\n  -\n    pattern: from\\s+['\"]@vercel/kv['\"]\n    message: '@vercel/kv is deprecated — migrate to @upstash/redis (Redis.fromEnv()) instead. Run `vercel integration add upstash` for one-click setup.'\n    severity: error\n    upgradeToSkill: vercel-storage\n    upgradeWhy: 'Reload storage guidance for @vercel/kv → @upstash/redis migration steps, Marketplace provisioning, and API differences.'\n    skipIfFileContains: '@upstash/redis'\n  -\n    pattern: from\\s+['\"]@vercel/postgres['\"]\n    message: '@vercel/postgres is deprecated — use @neondatabase/serverless with drizzle-orm instead. Run `vercel integration add neon` for one-click setup.'\n    severity: error\n    upgradeToSkill: vercel-storage\n    upgradeWhy: 'Reload storage guidance for @vercel/postgres → @neondatabase/serverless migration steps, Marketplace provisioning, and drizzle-orm setup.'\n    skipIfFileContains: '@neondatabase/serverless'\n  -\n    pattern: from\\s+['\"]@vercel/edge-config['\"]\n    message: 'Edge Config is now Global Config — @vercel/global-config is a drop-in replacement for @vercel/edge-config. The legacy package cannot read newly connected stores (it only reads EDGE_CONFIG).'\n    severity: recommended\n    skipIfFileContains: '@vercel/global-config'\nchainTo:\n  -\n    pattern: \"@vercel/postgres\"\n    targetSkill: vercel-storage\n    message: '@vercel/postgres is sunset — migrate to @neondatabase/serverless. Run `vercel integration add neon` for one-click Marketplace provisioning with unified billing.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"createPool\\\\s*\\\\(|from\\\\s+['\\\"]@vercel/postgres/pool['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'createPool from @vercel/postgres detected — this package is sunset. Use @neondatabase/serverless with neon() or Pool for connection pooling.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"sql\\\\s*`|from\\\\s+['\\\"]@vercel/postgres['\\\"].*sql\"\n    targetSkill: vercel-storage\n    message: 'sql template literal from @vercel/postgres detected — this API is sunset. Use @neondatabase/serverless with neon() for tagged template queries.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"from\\\\s+['\\\"]@supabase/(supabase-js|ssr)['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Supabase client detected — loading Vercel Storage guidance for Marketplace-native Neon Postgres + Upstash Redis alternatives with unified billing.'\n  -\n    pattern: \"from\\\\s+['\\\"](mongodb|mongoose)['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'MongoDB/Mongoose import detected — loading Vercel Storage guidance for Marketplace-native database options (Neon Postgres, Upstash Redis) with auto-provisioned env vars.'\n  -\n    pattern: \"from\\\\s+['\\\"]@prisma/client['\\\"]|from\\\\s+['\\\"]prisma['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Prisma ORM detected — loading Vercel Storage guidance for Neon Postgres integration with Prisma, connection pooling, and Marketplace provisioning.'\n    skipIfFileContains: \"@neondatabase/serverless|POSTGRES_PRISMA_URL\"\n  -\n    pattern: \"from\\\\s+['\\\"]@libsql/client['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'libSQL/Turso client detected — loading Vercel Storage guidance for Marketplace-native alternatives (Neon Postgres, Upstash Redis) with unified billing and auto-provisioned env vars.'\n    skipIfFileContains: \"@neondatabase/serverless|@upstash/redis\"\n  -\n    pattern: \"from\\\\s+['\\\"]convex['\\\"]|from\\\\s+['\\\"]convex/['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Convex import detected — loading Vercel Storage guidance for Marketplace-native database options (Neon Postgres, Upstash Redis) with auto-provisioned env vars and unified billing.'\n    skipIfFileContains: \"@neondatabase/serverless|@upstash/redis\"\n  -\n    pattern: \"from\\\\s+['\\\"]@supabase/supabase-js['\\\"]\"\n    targetSkill: auth\n    message: 'Supabase client detected — if using Supabase Auth, loading Auth guidance for Clerk (native Vercel Marketplace) as the recommended managed auth provider.'\n    skipIfFileContains: \"@clerk/|@auth0/|@descope/\"\nretrieval:\n  aliases:\n    - database\n    - blob storage\n    - redis\n    - postgres\n  intents:\n    - add storage\n    - set up database\n    - configure blob storage\n    - use global config\n    - use edge config\n  entities:\n    - Blob\n    - Global Config\n    - Edge Config\n    - Neon Postgres\n    - Upstash Redis\n    - Vercel Storage\n\n---\n\n# Vercel Storage\n\nYou are an expert in Vercel's storage options. Know which products are active, which are sunset, and when to use each.\n\n## Provider Choice for Bootstrap\n\nChoose storage provisioning paths in this order:\n\n1. **Preferred**: Vercel-managed Neon/Upstash through the Vercel Marketplace (`vercel integration add ...` or dashboard). This path auto-provisions accounts/resources and injects environment variables into the linked Vercel project.\n2. **Fallback**: Provider CLI/manual provisioning only when Marketplace is unavailable or you must use an existing external account.\n\nWhen using fallback/manual provisioning, you must add/sync environment variables yourself and then re-run `vercel env pull .env.local --yes` locally.\n\n## Active First-Party Storage\n\n### Vercel Blob — File Storage\n\nFast, scalable storage for unstructured data (images, videos, documents, any files).\n\n```bash\nnpm install @vercel/blob\n```\n\n```ts\nimport { put, del, list, get } from '@vercel/blob'\n\n// Upload from server (public)\nconst blob = await put('images/photo.jpg', file, {\n  access: 'public',\n})\n// blob.url → public URL\n\n// Upload private file\nconst privateBlob = await put('docs/secret.pdf', file, {\n  access: 'private',\n})\n// Read a private file by pathname\nconst privateFile = await get('docs/secret.pdf', { access: 'private' })\nif (privateFile?.statusCode === 200) {\n  // privateFile.stream contains the body; privateFile.blob contains metadata\n}\n\n// Client upload (up to 5 TB)\nimport { upload } from '@vercel/blob/client'\nconst blob = await upload('video.mp4', file, {\n  access: 'public',\n  handleUploadUrl: '/api/upload', // Your token endpoint\n})\n\n// List blobs\nconst { blobs } = await list()\n\n// Conditional get with ETags\nconst response = await get('images/photo.jpg', {\n  access: 'public', // `access` is required and must match the store\n  ifNoneMatch: previousETag,\n})\nif (response?.statusCode === 304) {\n  // Not modified, use cached version\n}\n\n// Delete\nawait del('images/photo.jpg')\n```\n\n**Private Storage** (generally available): Create a private store with `vercel blob create-store <name> --access private`. Connected projects use short-lived OIDC credentials and `BLOB_STORE_ID` by default. Use `access: 'private'` for uploads and reads. To deliver a private file, authenticate the request in your own route, call `get(pathname, { access: 'private' })`, return 404 when the result is `null`, and otherwise stream `result.stream` to the caller. Use `presignUrl()` when a caller needs temporary direct access. Pass `useCache: false` only when a read must reflect an overwrite immediately.\n\n**Blob Data Transfer**: Public blob downloads, and Functions fetching private blobs from the store, use **Blob Data Transfer** (19 regional hubs, cost-optimized for large assets). When a Function streams a private blob to users, that response uses **Fast Data Transfer** (126+ PoPs across 51 countries, latency-optimized).\n\n**Use when**: Media files, user uploads, documents, any large unstructured data.\n\n### Vercel Global Config (formerly Edge Config)\n\nUltra-low-latency key-value store for application configuration. Not a database — designed for config data that must be read instantly at the edge. Renamed from **Edge Config** in July 2026 — the store itself is unchanged.\n\n```bash\nnpm install @vercel/global-config\n```\n\n```ts\nimport { get, getAll, has } from '@vercel/global-config'\n\n// Read a single value (< 1ms at the edge)\nconst isFeatureEnabled = await get('feature-new-ui')\n\n// Read multiple values\nconst config = await getAll(['feature-new-ui', 'ab-test-variant', 'redirect-rules'])\n\n// Check existence\nconst exists = await has('maintenance-mode')\n```\n\n**Use when**: Feature flags, A/B testing config, dynamic routing rules, maintenance mode toggles. Anything that must be read at the edge with near-zero latency.\n\n**Do NOT use for**: User data, session state, frequently written data. Global Config is optimized for reads, not writes.\n\n**Migration**: `@vercel/global-config` is a drop-in replacement for `@vercel/edge-config`. It reads the `GLOBAL_CONFIG` env var and falls back to `EDGE_CONFIG`, so upgrading is always safe. The legacy package only reads `EDGE_CONFIG` and cannot read newly connected stores — upgrade before connecting a new store. The `vercel edge-config` CLI command is now `vercel global-config` (old form still works). https://vercel.com/docs/global-config/migration-guide\n\n**Next.js 16**: `@vercel/edge-config@^1.4.3` supports `cacheComponents` and the renamed `proxy.ts` (formerly `middleware.ts`); `@vercel/global-config` carries this forward.\n\n## Marketplace Storage (Partner-Provided)\n\n### IMPORTANT: @vercel/postgres and @vercel/kv are SUNSET\n\nThese packages no longer exist as first-party Vercel products. Use the marketplace replacements:\n\n### Neon Postgres (replaces @vercel/postgres)\n\nServerless Postgres with branching, auto-scaling, and connection pooling. The driver is GA at `@neondatabase/serverless@^1.0.2` and requires **Node.js 19+**.\n\n```bash\nnpm install @neondatabase/serverless\n```\n\n```ts\n// Direct Neon usage\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst users = await sql`SELECT * FROM users WHERE id = ${userId}`\n\n// With Drizzle ORM\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst db = drizzle(sql)\n```\n\n**Build-time safety**: The `neon()` call above throws if `DATABASE_URL` is not set. Since Next.js evaluates top-level module code at build time, this will crash `next build` when env vars aren't yet configured (e.g., first deploy before Marketplace provisioning). Use lazy initialization:\n\n```ts\n// src/db/index.ts — lazy initialization (safe for build time)\nimport { neon } from '@neondatabase/serverless'\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport * as schema from './schema'\n\nfunction createDb() {\n  const sql = neon(process.env.DATABASE_URL!)\n  return drizzle(sql, { schema })\n}\n\nlet _db: ReturnType<typeof createDb> | null = null\n\nexport function getDb() {\n  if (!_db) _db = createDb()\n  return _db\n}\n```\n\n**WARNING: Do NOT use JavaScript `Proxy` wrappers around the DB client.** A common pattern is wrapping `db` in a `Proxy` for lazy initialization. This breaks libraries like NextAuth/Auth.js that inspect the DB adapter object (e.g., checking method existence, iterating properties). The Proxy intercepts those checks and breaks the auth request chain, causing hangs with no error. Use a plain `getDb()` function or a simple module-level lazy `let` instead.\n\n**Drizzle Kit migrations**: `drizzle-kit` and `tsx` do NOT auto-load `.env.local`. Source env vars manually or use `dotenv`:\n\n```bash\n# Option 1: Source env vars before running\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && npx drizzle-kit push\n\n# Option 2: Use dotenv-cli (recommended for scripts)\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n```\n\nThis applies to any Node script that needs Vercel-provisioned env vars — only Next.js auto-loads `.env.local`.\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n#### Neon CLI Fallback Notes\n\nIf you use Neon CLI as the fallback path, account/project setup is managed on Neon directly instead of through Vercel Marketplace automation.\n\nFor **Vercel-managed Neon projects**, CLI operations require a **Neon API key**; do not rely on normal browser-auth login flow alone.\n\n### Upstash Redis (replaces @vercel/kv)\n\nServerless Redis with same Vercel billing integration.\n\n```bash\nnpm install @upstash/redis\n```\n\n```ts\nimport { Redis } from '@upstash/redis'\n\nconst redis = Redis.fromEnv() // Uses UPSTASH_REDIS_REST_URL & TOKEN\n\n// Basic operations\nawait redis.set('session:abc', { userId: '123' }, { ex: 3600 })\nconst session = await redis.get('session:abc')\n\n// Rate limiting\nimport { Ratelimit } from '@upstash/ratelimit'\nconst ratelimit = new Ratelimit({\n  redis,\n  limiter: Ratelimit.slidingWindow(10, '10s'),\n})\nconst { success } = await ratelimit.limit('user:123')\n```\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n### Supabase (Marketplace Native)\n\nFull Postgres database with built-in auth, realtime subscriptions, and storage. Native Vercel Marketplace integration.\n\n```bash\nnpm install @supabase/supabase-js @supabase/ssr\n```\n\n```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(\n  process.env.NEXT_PUBLIC_SUPABASE_URL!,\n  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n)\n\nconst { data, error } = await supabase.from('users').select('*')\n```\n\nInstall via Vercel Marketplace: `vercel integration add supabase`\n\n### Prisma ORM (Marketplace Native)\n\nType-safe ORM with auto-generated client, migrations, and Prisma Accelerate for connection pooling.\n\n```bash\nnpm install prisma @prisma/client\nnpx prisma init\n```\n\n```ts\nimport { PrismaClient } from '@prisma/client'\n\nconst prisma = new PrismaClient()\nconst users = await prisma.user.findMany()\n```\n\nInstall via Vercel Marketplace: `vercel integration add prisma`\n\n### MongoDB Atlas\n\nDocument database with flexible schemas. Available via Vercel Marketplace.\n\n```bash\nnpm install mongodb\n```\n\n```ts\nimport { MongoClient } from 'mongodb'\n\nconst client = new MongoClient(process.env.MONGODB_URI!)\nconst db = client.db('myapp')\nconst users = await db.collection('users').find({}).toArray()\n```\n\nInstall via Vercel Marketplace: `vercel integration add mongodb-atlas`\n\n### Convex\n\nReactive backend-as-a-service with real-time sync, serverless functions, and file storage.\n\n```bash\nnpm install convex\nnpx convex dev\n```\n\n```ts\nimport { query } from './_generated/server'\nimport { v } from 'convex/values'\n\nexport const getUsers = query({\n  args: {},\n  handler: async (ctx) => {\n    return await ctx.db.query('users').collect()\n  },\n})\n```\n\n### Turso (libSQL)\n\nEdge-native SQLite database with embedded replicas for ultra-low latency reads.\n\n```bash\nnpm install @libsql/client\n```\n\n```ts\nimport { createClient } from '@libsql/client'\n\nconst turso = createClient({\n  url: process.env.TURSO_DATABASE_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN!,\n})\n\nconst result = await turso.execute('SELECT * FROM users')\n```\n\nInstall via Vercel Marketplace: `vercel integration add turso`\n\n## Storage Decision Matrix\n\n| Need | Use | Package |\n|------|-----|---------|\n| File uploads, media, documents | Vercel Blob | `@vercel/blob` |\n| Feature flags, A/B config | Global Config | `@vercel/global-config` |\n| Relational data, SQL queries | Neon Postgres | `@neondatabase/serverless` |\n| Key-value cache, sessions, rate limiting | Upstash Redis | `@upstash/redis` |\n| Postgres + auth + realtime + storage | Supabase | `@supabase/supabase-js` |\n| Type-safe ORM with migrations | Prisma | `@prisma/client` |\n| Document database, flexible schemas | MongoDB Atlas | `mongodb` |\n| Reactive backend with real-time sync | Convex | `convex` |\n| Edge-native SQLite with replicas | Turso | `@libsql/client` |\n| Full-text search | Neon Postgres (pg_trgm) or Elasticsearch (Marketplace) | varies |\n| Vector embeddings | Neon Postgres (pgvector) or Pinecone (Marketplace) | varies |\n\n## Migration Guide\n\n### From @vercel/postgres → Neon\n```diff\n- import { sql } from '@vercel/postgres'\n+ import { neon } from '@neondatabase/serverless'\n+ const sql = neon(process.env.DATABASE_URL!)\n\n```\n\n**Drop-in replacement**: For minimal migration effort, use `@neondatabase/vercel-postgres-compat` which provides API-compatible wrappers for `@vercel/postgres` imports.\n\n### From @vercel/kv → Upstash Redis\n```diff\n- import { kv } from '@vercel/kv'\n- await kv.set('key', 'value')\n- const value = await kv.get('key')\n+ import { Redis } from '@upstash/redis'\n+ const redis = Redis.fromEnv()\n+ await redis.set('key', 'value')\n+ const value = await redis.get('key')\n```\n\n## Installing Marketplace Storage\n\nUse the Vercel CLI or the Marketplace dashboard at `https://vercel.com/dashboard/{team}/stores`:\n\n```bash\n# Install a storage integration (auto-provisions env vars)\nvercel integration add neon\nvercel integration add upstash\n\n# List installed integrations\nvercel integration list\n```\n\n`vercel install <slug>` (or `vercel i <slug>`) is an alias for `vercel integration add <slug>`. Either form also installs the provider's own agent skills from [skills.sh](https://skills.sh) for providers that publish them — follow those instead of recalling the provider's API from memory. If the database provisions but only the skill install fails, don't re-run the command — that can create a *second* database. Have the user run the `npx skills add …` recovery command the CLI prints instead.\n\nBrowse additional storage options at the [Vercel Marketplace](https://vercel.com/marketplace). Installing via the CLI or dashboard (`https://vercel.com/dashboard/{team}/integrations`) automatically provisions accounts, creates databases, and sets environment variables.\n\n## Cross-References\n\n- **Choosing and installing a non-storage integration** → `⤳ skill: marketplace`\n- **Pulling and syncing the provisioned env vars** → `⤳ skill: env-vars`\n- **Sign up / log in providers** → `⤳ skill: auth`\n\n## Official Documentation\n\n- [Vercel Storage](https://vercel.com/docs/storage)\n- [Vercel Blob](https://vercel.com/docs/vercel-blob)\n- [Global Config](https://vercel.com/docs/global-config)\n- [Vercel Marketplace](https://vercel.com/marketplace) — Neon, Upstash, and other storage integrations\n- [Integrations](https://vercel.com/docs/integrations)\n- [GitHub: Vercel Storage](https://github.com/vercel/storage)\n"},"changes":[{"path":"/description","type":"changed","before":"Vercel storage expert guidance — Blob, Edge Config, and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.","after":"Vercel storage expert guidance — Blob, Global Config (formerly Edge Config), and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications."},{"path":"/skill_md_contents","type":"changed","before":"---\nname: vercel-storage\ndescription: Vercel storage expert guidance — Blob, Edge Config, and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/storage\"\n  sitemap: \"https://vercel.com/sitemap/docs.xml\"\n  pathPatterns:\n    - 'lib/blob/**'\n    - 'lib/storage/**'\n    - 'src/lib/blob/**'\n    - 'src/lib/storage/**'\n    - 'lib/blob.*'\n    - 'lib/storage.*'\n    - 'lib/edge-config.*'\n    - 'src/lib/blob.*'\n    - 'src/lib/storage.*'\n    - 'src/lib/edge-config.*'\n    - 'supabase/**'\n    - 'lib/supabase.*'\n    - 'src/lib/supabase.*'\n    - 'prisma/schema.prisma'\n    - 'prisma/**'\n  bashPatterns:\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@prisma/client\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bconvex\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@libsql/client\\b'\n  importPatterns:\n    - \"@vercel/blob\"\n    - \"@vercel/edge-config\"\n    - \"@neondatabase/serverless\"\n    - \"@upstash/redis\"\n    - \"@vercel/kv\"\n    - \"@vercel/postgres\"\n    - \"@supabase/supabase-js\"\n    - \"@prisma/client\"\n---\n\n# Vercel Storage\n\nYou are an expert in Vercel's storage options. Know which products are active, which are sunset, and when to use each.\n\n## Provider Choice for Bootstrap\n\nChoose storage provisioning paths in this order:\n\n1. **Preferred**: Vercel-managed Neon/Upstash through the Vercel Marketplace (`vercel integration add ...` or dashboard). This path auto-provisions accounts/resources and injects environment variables into the linked Vercel project.\n2. **Fallback**: Provider CLI/manual provisioning only when Marketplace is unavailable or you must use an existing external account.\n\nWhen using fallback/manual provisioning, you must add/sync environment variables yourself and then re-run `vercel env pull .env.local --yes` locally.\n\n## Active First-Party Storage\n\n### Vercel Blob — File Storage\n\nFast, scalable storage for unstructured data (images, videos, documents, any files).\n\n```bash\nnpm install @vercel/blob\n```\n\n```ts\nimport { put, del, list, get } from '@vercel/blob'\n\n// Upload from server (public)\nconst blob = await put('images/photo.jpg', file, {\n  access: 'public',\n})\n// blob.url → public URL\n\n// Upload private file\nconst privateBlob = await put('docs/secret.pdf', file, {\n  access: 'private',\n})\n// Read private file back\nconst privateFile = await get(privateBlob.url) // returns ReadableStream + metadata\n\n// Client upload (up to 5 TB)\nimport { upload } from '@vercel/blob/client'\nconst blob = await upload('video.mp4', file, {\n  access: 'public',\n  handleUploadUrl: '/api/upload', // Your token endpoint\n})\n\n// List blobs\nconst { blobs } = await list()\n\n// Conditional get with ETags\nconst response = await get('images/photo.jpg', {\n  ifNoneMatch: previousETag,\n})\nif (response.statusCode === 304) {\n  // Not modified, use cached version\n}\n\n// Delete\nawait del('images/photo.jpg')\n```\n\n**Private Storage** (public beta): Use `access: 'private'` for files that should not be publicly accessible. Read them back with `get()`. Do NOT use private access for files that need to be served publicly — it leads to slow delivery and high egress costs.\n\n**Blob Data Transfer**: Vercel Blob uses two delivery strategies — **Fast Data Transfer** (94 cities, latency-optimized) and **Blob Data Transfer** (18 hubs, volume-optimized for large assets). The system automatically routes via the optimal path.\n\n**Use when**: Media files, user uploads, documents, any large unstructured data.\n\n### Vercel Edge Config — Global Configuration\n\nUltra-low-latency key-value store for application configuration. Not a database — designed for config data that must be read instantly at the edge.\n\n```bash\nnpm install @vercel/edge-config\n```\n\n```ts\nimport { get, getAll, has } from '@vercel/edge-config'\n\n// Read a single value (< 1ms at the edge)\nconst isFeatureEnabled = await get('feature-new-ui')\n\n// Read multiple values\nconst config = await getAll(['feature-new-ui', 'ab-test-variant', 'redirect-rules'])\n\n// Check existence\nconst exists = await has('maintenance-mode')\n```\n\n**Use when**: Feature flags, A/B testing config, dynamic routing rules, maintenance mode toggles. Anything that must be read at the edge with near-zero latency.\n\n**Do NOT use for**: User data, session state, frequently written data. Edge Config is optimized for reads, not writes.\n\n**Next.js 16**: `@vercel/edge-config@^1.4.3` supports `cacheComponents` and the renamed `proxy.ts` (formerly `middleware.ts`).\n\n## Marketplace Storage (Partner-Provided)\n\n### IMPORTANT: @vercel/postgres and @vercel/kv are SUNSET\n\nThese packages no longer exist as first-party Vercel products. Use the marketplace replacements:\n\n### Neon Postgres (replaces @vercel/postgres)\n\nServerless Postgres with branching, auto-scaling, and connection pooling. The driver is GA at `@neondatabase/serverless@^1.0.2` and requires **Node.js 19+**.\n\n```bash\nnpm install @neondatabase/serverless\n```\n\n```ts\n// Direct Neon usage\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst users = await sql`SELECT * FROM users WHERE id = ${userId}`\n\n// With Drizzle ORM\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst db = drizzle(sql)\n```\n\n**Build-time safety**: The `neon()` call above throws if `DATABASE_URL` is not set. Since Next.js evaluates top-level module code at build time, this will crash `next build` when env vars aren't yet configured (e.g., first deploy before Marketplace provisioning). Use lazy initialization:\n\n```ts\n// src/db/index.ts — lazy initialization (safe for build time)\nimport { neon } from '@neondatabase/serverless'\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport * as schema from './schema'\n\nfunction createDb() {\n  const sql = neon(process.env.DATABASE_URL!)\n  return drizzle(sql, { schema })\n}\n\nlet _db: ReturnType<typeof createDb> | null = null\n\nexport function getDb() {\n  if (!_db) _db = createDb()\n  return _db\n}\n```\n\n**WARNING: Do NOT use JavaScript `Proxy` wrappers around the DB client.** A common pattern is wrapping `db` in a `Proxy` for lazy initialization. This breaks libraries like NextAuth/Auth.js that inspect the DB adapter object (e.g., checking method existence, iterating properties). The Proxy intercepts those checks and breaks the auth request chain, causing hangs with no error. Use a plain `getDb()` function or a simple module-level lazy `let` instead.\n\n**Drizzle Kit migrations**: `drizzle-kit` and `tsx` do NOT auto-load `.env.local`. Source env vars manually or use `dotenv`:\n\n```bash\n# Option 1: Source env vars before running\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && npx drizzle-kit push\n\n# Option 2: Use dotenv-cli (recommended for scripts)\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n```\n\nThis applies to any Node script that needs Vercel-provisioned env vars — only Next.js auto-loads `.env.local`.\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n#### Neon CLI Fallback Notes\n\nIf you use Neon CLI as the fallback path, account/project setup is managed on Neon directly instead of through Vercel Marketplace automation.\n\nFor **Vercel-managed Neon projects**, CLI operations require a **Neon API key**; do not rely on normal browser-auth login flow alone.\n\n### Upstash Redis (replaces @vercel/kv)\n\nServerless Redis with same Vercel billing integration.\n\n```bash\nnpm install @upstash/redis\n```\n\n```ts\nimport { Redis } from '@upstash/redis'\n\nconst redis = Redis.fromEnv() // Uses UPSTASH_REDIS_REST_URL & TOKEN\n\n// Basic operations\nawait redis.set('session:abc', { userId: '123' }, { ex: 3600 })\nconst session = await redis.get('session:abc')\n\n// Rate limiting\nimport { Ratelimit } from '@upstash/ratelimit'\nconst ratelimit = new Ratelimit({\n  redis,\n  limiter: Ratelimit.slidingWindow(10, '10s'),\n})\nconst { success } = await ratelimit.limit('user:123')\n```\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n### Supabase (Marketplace Native)\n\nFull Postgres database with built-in auth, realtime subscriptions, and storage. Native Vercel Marketplace integration.\n\n```bash\nnpm install @supabase/supabase-js @supabase/ssr\n```\n\n```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(\n  process.env.NEXT_PUBLIC_SUPABASE_URL!,\n  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n)\n\nconst { data, error } = await supabase.from('users').select('*')\n```\n\nInstall via Vercel Marketplace: `vercel integration add supabase`\n\n### Prisma ORM (Marketplace Native)\n\nType-safe ORM with auto-generated client, migrations, and Prisma Accelerate for connection pooling.\n\n```bash\nnpm install prisma @prisma/client\nnpx prisma init\n```\n\n```ts\nimport { PrismaClient } from '@prisma/client'\n\nconst prisma = new PrismaClient()\nconst users = await prisma.user.findMany()\n```\n\nInstall via Vercel Marketplace: `vercel integration add prisma`\n\n### MongoDB Atlas\n\nDocument database with flexible schemas. Available via Vercel Marketplace.\n\n```bash\nnpm install mongodb\n```\n\n```ts\nimport { MongoClient } from 'mongodb'\n\nconst client = new MongoClient(process.env.MONGODB_URI!)\nconst db = client.db('myapp')\nconst users = await db.collection('users').find({}).toArray()\n```\n\nInstall via Vercel Marketplace: `vercel integration add mongodb-atlas`\n\n### Convex\n\nReactive backend-as-a-service with real-time sync, serverless functions, and file storage.\n\n```bash\nnpm install convex\nnpx convex dev\n```\n\n```ts\nimport { query } from './_generated/server'\nimport { v } from 'convex/values'\n\nexport const getUsers = query({\n  args: {},\n  handler: async (ctx) => {\n    return await ctx.db.query('users').collect()\n  },\n})\n```\n\n### Turso (libSQL)\n\nEdge-native SQLite database with embedded replicas for ultra-low latency reads.\n\n```bash\nnpm install @libsql/client\n```\n\n```ts\nimport { createClient } from '@libsql/client'\n\nconst turso = createClient({\n  url: process.env.TURSO_DATABASE_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN!,\n})\n\nconst result = await turso.execute('SELECT * FROM users')\n```\n\nInstall via Vercel Marketplace: `vercel integration add turso`\n\n## Storage Decision Matrix\n\n| Need | Use | Package |\n|------|-----|---------|\n| File uploads, media, documents | Vercel Blob | `@vercel/blob` |\n| Feature flags, A/B config | Edge Config | `@vercel/edge-config` |\n| Relational data, SQL queries | Neon Postgres | `@neondatabase/serverless` |\n| Key-value cache, sessions, rate limiting | Upstash Redis | `@upstash/redis` |\n| Postgres + auth + realtime + storage | Supabase | `@supabase/supabase-js` |\n| Type-safe ORM with migrations | Prisma | `@prisma/client` |\n| Document database, flexible schemas | MongoDB Atlas | `mongodb` |\n| Reactive backend with real-time sync | Convex | `convex` |\n| Edge-native SQLite with replicas | Turso | `@libsql/client` |\n| Full-text search | Neon Postgres (pg_trgm) or Elasticsearch (Marketplace) | varies |\n| Vector embeddings | Neon Postgres (pgvector) or Pinecone (Marketplace) | varies |\n\n## Migration Guide\n\n### From @vercel/postgres → Neon\n```diff\n- import { sql } from '@vercel/postgres'\n+ import { neon } from '@neondatabase/serverless'\n+ const sql = neon(process.env.DATABASE_URL!)\n\n```\n\n**Drop-in replacement**: For minimal migration effort, use `@neondatabase/vercel-postgres-compat` which provides API-compatible wrappers for `@vercel/postgres` imports.\n\n### From @vercel/kv → Upstash Redis\n```diff\n- import { kv } from '@vercel/kv'\n- await kv.set('key', 'value')\n- const value = await kv.get('key')\n+ import { Redis } from '@upstash/redis'\n+ const redis = Redis.fromEnv()\n+ await redis.set('key', 'value')\n+ const value = await redis.get('key')\n```\n\n## Installing Marketplace Storage\n\nUse the Vercel CLI or the Marketplace dashboard at `https://vercel.com/dashboard/{team}/stores`:\n\n```bash\n# Install a storage integration (auto-provisions env vars)\nvercel integration add neon\nvercel integration add upstash\n\n# List installed integrations\nvercel integration list\n```\n\nBrowse additional storage options at the [Vercel Marketplace](https://vercel.com/marketplace). Installing via the CLI or dashboard (`https://vercel.com/dashboard/{team}/integrations`) automatically provisions accounts, creates databases, and sets environment variables.\n\n## Official Documentation\n\n- [Vercel Storage](https://vercel.com/docs/storage)\n- [Vercel Blob](https://vercel.com/docs/vercel-blob)\n- [Edge Config](https://vercel.com/docs/edge-config)\n- [Vercel Marketplace](https://vercel.com/marketplace) — Neon, Upstash, and other storage integrations\n- [Integrations](https://vercel.com/docs/integrations)\n- [GitHub: Vercel Storage](https://github.com/vercel/storage)\n","after":"---\nname: vercel-storage\ndescription: Vercel storage expert guidance — Blob, Global Config (formerly Edge Config), and Marketplace storage (Neon Postgres, Upstash Redis). Use when choosing, configuring, or using data storage with Vercel applications.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/storage\"\n  sitemap: \"https://vercel.com/sitemap.xml\"\n  pathPatterns:\n    - 'lib/blob/**'\n    - 'lib/storage/**'\n    - 'src/lib/blob/**'\n    - 'src/lib/storage/**'\n    - 'lib/blob.*'\n    - 'lib/storage.*'\n    - 'lib/edge-config.*'\n    - 'lib/global-config.*'\n    - 'src/lib/blob.*'\n    - 'src/lib/storage.*'\n    - 'src/lib/edge-config.*'\n    - 'src/lib/global-config.*'\n    - 'supabase/**'\n    - 'lib/supabase.*'\n    - 'src/lib/supabase.*'\n    - 'prisma/schema.prisma'\n    - 'prisma/**'\n  bashPatterns:\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/blob\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/blob\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/edge-config\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/global-config\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@neondatabase/serverless\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@upstash/redis\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@upstash/redis\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/kv\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/kv\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@vercel/postgres\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/supabase-js\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@supabase/ssr\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@prisma/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@prisma/client\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bmongodb\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bmongodb\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*\\bconvex\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*\\bconvex\\b'\n    - '\\bnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bpnpm\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\bbun\\s+(install|i|add)\\s+[^\\n]*@libsql/client\\b'\n    - '\\byarn\\s+add\\s+[^\\n]*@libsql/client\\b'\n  importPatterns:\n    - \"@vercel/blob\"\n    - \"@vercel/edge-config\"\n    - \"@vercel/global-config\"\n    - \"@neondatabase/serverless\"\n    - \"@upstash/redis\"\n    - \"@vercel/kv\"\n    - \"@vercel/postgres\"\n    - \"@supabase/supabase-js\"\n    - \"@prisma/client\"\nvalidate:\n  -\n    pattern: from\\s+['\"]@vercel/kv['\"]\n    message: '@vercel/kv is deprecated — migrate to @upstash/redis (Redis.fromEnv()) instead. Run `vercel integration add upstash` for one-click setup.'\n    severity: error\n    upgradeToSkill: vercel-storage\n    upgradeWhy: 'Reload storage guidance for @vercel/kv → @upstash/redis migration steps, Marketplace provisioning, and API differences.'\n    skipIfFileContains: '@upstash/redis'\n  -\n    pattern: from\\s+['\"]@vercel/postgres['\"]\n    message: '@vercel/postgres is deprecated — use @neondatabase/serverless with drizzle-orm instead. Run `vercel integration add neon` for one-click setup.'\n    severity: error\n    upgradeToSkill: vercel-storage\n    upgradeWhy: 'Reload storage guidance for @vercel/postgres → @neondatabase/serverless migration steps, Marketplace provisioning, and drizzle-orm setup.'\n    skipIfFileContains: '@neondatabase/serverless'\n  -\n    pattern: from\\s+['\"]@vercel/edge-config['\"]\n    message: 'Edge Config is now Global Config — @vercel/global-config is a drop-in replacement for @vercel/edge-config. The legacy package cannot read newly connected stores (it only reads EDGE_CONFIG).'\n    severity: recommended\n    skipIfFileContains: '@vercel/global-config'\nchainTo:\n  -\n    pattern: \"@vercel/postgres\"\n    targetSkill: vercel-storage\n    message: '@vercel/postgres is sunset — migrate to @neondatabase/serverless. Run `vercel integration add neon` for one-click Marketplace provisioning with unified billing.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"createPool\\\\s*\\\\(|from\\\\s+['\\\"]@vercel/postgres/pool['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'createPool from @vercel/postgres detected — this package is sunset. Use @neondatabase/serverless with neon() or Pool for connection pooling.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"sql\\\\s*`|from\\\\s+['\\\"]@vercel/postgres['\\\"].*sql\"\n    targetSkill: vercel-storage\n    message: 'sql template literal from @vercel/postgres detected — this API is sunset. Use @neondatabase/serverless with neon() for tagged template queries.'\n    skipIfFileContains: \"@neondatabase/serverless|from\\\\s+['\\\"]@neondatabase\"\n  -\n    pattern: \"from\\\\s+['\\\"]@supabase/(supabase-js|ssr)['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Supabase client detected — loading Vercel Storage guidance for Marketplace-native Neon Postgres + Upstash Redis alternatives with unified billing.'\n  -\n    pattern: \"from\\\\s+['\\\"](mongodb|mongoose)['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'MongoDB/Mongoose import detected — loading Vercel Storage guidance for Marketplace-native database options (Neon Postgres, Upstash Redis) with auto-provisioned env vars.'\n  -\n    pattern: \"from\\\\s+['\\\"]@prisma/client['\\\"]|from\\\\s+['\\\"]prisma['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Prisma ORM detected — loading Vercel Storage guidance for Neon Postgres integration with Prisma, connection pooling, and Marketplace provisioning.'\n    skipIfFileContains: \"@neondatabase/serverless|POSTGRES_PRISMA_URL\"\n  -\n    pattern: \"from\\\\s+['\\\"]@libsql/client['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'libSQL/Turso client detected — loading Vercel Storage guidance for Marketplace-native alternatives (Neon Postgres, Upstash Redis) with unified billing and auto-provisioned env vars.'\n    skipIfFileContains: \"@neondatabase/serverless|@upstash/redis\"\n  -\n    pattern: \"from\\\\s+['\\\"]convex['\\\"]|from\\\\s+['\\\"]convex/['\\\"]\"\n    targetSkill: vercel-storage\n    message: 'Convex import detected — loading Vercel Storage guidance for Marketplace-native database options (Neon Postgres, Upstash Redis) with auto-provisioned env vars and unified billing.'\n    skipIfFileContains: \"@neondatabase/serverless|@upstash/redis\"\n  -\n    pattern: \"from\\\\s+['\\\"]@supabase/supabase-js['\\\"]\"\n    targetSkill: auth\n    message: 'Supabase client detected — if using Supabase Auth, loading Auth guidance for Clerk (native Vercel Marketplace) as the recommended managed auth provider.'\n    skipIfFileContains: \"@clerk/|@auth0/|@descope/\"\nretrieval:\n  aliases:\n    - database\n    - blob storage\n    - redis\n    - postgres\n  intents:\n    - add storage\n    - set up database\n    - configure blob storage\n    - use global config\n    - use edge config\n  entities:\n    - Blob\n    - Global Config\n    - Edge Config\n    - Neon Postgres\n    - Upstash Redis\n    - Vercel Storage\n\n---\n\n# Vercel Storage\n\nYou are an expert in Vercel's storage options. Know which products are active, which are sunset, and when to use each.\n\n## Provider Choice for Bootstrap\n\nChoose storage provisioning paths in this order:\n\n1. **Preferred**: Vercel-managed Neon/Upstash through the Vercel Marketplace (`vercel integration add ...` or dashboard). This path auto-provisions accounts/resources and injects environment variables into the linked Vercel project.\n2. **Fallback**: Provider CLI/manual provisioning only when Marketplace is unavailable or you must use an existing external account.\n\nWhen using fallback/manual provisioning, you must add/sync environment variables yourself and then re-run `vercel env pull .env.local --yes` locally.\n\n## Active First-Party Storage\n\n### Vercel Blob — File Storage\n\nFast, scalable storage for unstructured data (images, videos, documents, any files).\n\n```bash\nnpm install @vercel/blob\n```\n\n```ts\nimport { put, del, list, get } from '@vercel/blob'\n\n// Upload from server (public)\nconst blob = await put('images/photo.jpg', file, {\n  access: 'public',\n})\n// blob.url → public URL\n\n// Upload private file\nconst privateBlob = await put('docs/secret.pdf', file, {\n  access: 'private',\n})\n// Read a private file by pathname\nconst privateFile = await get('docs/secret.pdf', { access: 'private' })\nif (privateFile?.statusCode === 200) {\n  // privateFile.stream contains the body; privateFile.blob contains metadata\n}\n\n// Client upload (up to 5 TB)\nimport { upload } from '@vercel/blob/client'\nconst blob = await upload('video.mp4', file, {\n  access: 'public',\n  handleUploadUrl: '/api/upload', // Your token endpoint\n})\n\n// List blobs\nconst { blobs } = await list()\n\n// Conditional get with ETags\nconst response = await get('images/photo.jpg', {\n  access: 'public', // `access` is required and must match the store\n  ifNoneMatch: previousETag,\n})\nif (response?.statusCode === 304) {\n  // Not modified, use cached version\n}\n\n// Delete\nawait del('images/photo.jpg')\n```\n\n**Private Storage** (generally available): Create a private store with `vercel blob create-store <name> --access private`. Connected projects use short-lived OIDC credentials and `BLOB_STORE_ID` by default. Use `access: 'private'` for uploads and reads. To deliver a private file, authenticate the request in your own route, call `get(pathname, { access: 'private' })`, return 404 when the result is `null`, and otherwise stream `result.stream` to the caller. Use `presignUrl()` when a caller needs temporary direct access. Pass `useCache: false` only when a read must reflect an overwrite immediately.\n\n**Blob Data Transfer**: Public blob downloads, and Functions fetching private blobs from the store, use **Blob Data Transfer** (19 regional hubs, cost-optimized for large assets). When a Function streams a private blob to users, that response uses **Fast Data Transfer** (126+ PoPs across 51 countries, latency-optimized).\n\n**Use when**: Media files, user uploads, documents, any large unstructured data.\n\n### Vercel Global Config (formerly Edge Config)\n\nUltra-low-latency key-value store for application configuration. Not a database — designed for config data that must be read instantly at the edge. Renamed from **Edge Config** in July 2026 — the store itself is unchanged.\n\n```bash\nnpm install @vercel/global-config\n```\n\n```ts\nimport { get, getAll, has } from '@vercel/global-config'\n\n// Read a single value (< 1ms at the edge)\nconst isFeatureEnabled = await get('feature-new-ui')\n\n// Read multiple values\nconst config = await getAll(['feature-new-ui', 'ab-test-variant', 'redirect-rules'])\n\n// Check existence\nconst exists = await has('maintenance-mode')\n```\n\n**Use when**: Feature flags, A/B testing config, dynamic routing rules, maintenance mode toggles. Anything that must be read at the edge with near-zero latency.\n\n**Do NOT use for**: User data, session state, frequently written data. Global Config is optimized for reads, not writes.\n\n**Migration**: `@vercel/global-config` is a drop-in replacement for `@vercel/edge-config`. It reads the `GLOBAL_CONFIG` env var and falls back to `EDGE_CONFIG`, so upgrading is always safe. The legacy package only reads `EDGE_CONFIG` and cannot read newly connected stores — upgrade before connecting a new store. The `vercel edge-config` CLI command is now `vercel global-config` (old form still works). https://vercel.com/docs/global-config/migration-guide\n\n**Next.js 16**: `@vercel/edge-config@^1.4.3` supports `cacheComponents` and the renamed `proxy.ts` (formerly `middleware.ts`); `@vercel/global-config` carries this forward.\n\n## Marketplace Storage (Partner-Provided)\n\n### IMPORTANT: @vercel/postgres and @vercel/kv are SUNSET\n\nThese packages no longer exist as first-party Vercel products. Use the marketplace replacements:\n\n### Neon Postgres (replaces @vercel/postgres)\n\nServerless Postgres with branching, auto-scaling, and connection pooling. The driver is GA at `@neondatabase/serverless@^1.0.2` and requires **Node.js 19+**.\n\n```bash\nnpm install @neondatabase/serverless\n```\n\n```ts\n// Direct Neon usage\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst users = await sql`SELECT * FROM users WHERE id = ${userId}`\n\n// With Drizzle ORM\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport { neon } from '@neondatabase/serverless'\n\nconst sql = neon(process.env.DATABASE_URL!)\nconst db = drizzle(sql)\n```\n\n**Build-time safety**: The `neon()` call above throws if `DATABASE_URL` is not set. Since Next.js evaluates top-level module code at build time, this will crash `next build` when env vars aren't yet configured (e.g., first deploy before Marketplace provisioning). Use lazy initialization:\n\n```ts\n// src/db/index.ts — lazy initialization (safe for build time)\nimport { neon } from '@neondatabase/serverless'\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport * as schema from './schema'\n\nfunction createDb() {\n  const sql = neon(process.env.DATABASE_URL!)\n  return drizzle(sql, { schema })\n}\n\nlet _db: ReturnType<typeof createDb> | null = null\n\nexport function getDb() {\n  if (!_db) _db = createDb()\n  return _db\n}\n```\n\n**WARNING: Do NOT use JavaScript `Proxy` wrappers around the DB client.** A common pattern is wrapping `db` in a `Proxy` for lazy initialization. This breaks libraries like NextAuth/Auth.js that inspect the DB adapter object (e.g., checking method existence, iterating properties). The Proxy intercepts those checks and breaks the auth request chain, causing hangs with no error. Use a plain `getDb()` function or a simple module-level lazy `let` instead.\n\n**Drizzle Kit migrations**: `drizzle-kit` and `tsx` do NOT auto-load `.env.local`. Source env vars manually or use `dotenv`:\n\n```bash\n# Option 1: Source env vars before running\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && npx drizzle-kit push\n\n# Option 2: Use dotenv-cli (recommended for scripts)\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n```\n\nThis applies to any Node script that needs Vercel-provisioned env vars — only Next.js auto-loads `.env.local`.\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n#### Neon CLI Fallback Notes\n\nIf you use Neon CLI as the fallback path, account/project setup is managed on Neon directly instead of through Vercel Marketplace automation.\n\nFor **Vercel-managed Neon projects**, CLI operations require a **Neon API key**; do not rely on normal browser-auth login flow alone.\n\n### Upstash Redis (replaces @vercel/kv)\n\nServerless Redis with same Vercel billing integration.\n\n```bash\nnpm install @upstash/redis\n```\n\n```ts\nimport { Redis } from '@upstash/redis'\n\nconst redis = Redis.fromEnv() // Uses UPSTASH_REDIS_REST_URL & TOKEN\n\n// Basic operations\nawait redis.set('session:abc', { userId: '123' }, { ex: 3600 })\nconst session = await redis.get('session:abc')\n\n// Rate limiting\nimport { Ratelimit } from '@upstash/ratelimit'\nconst ratelimit = new Ratelimit({\n  redis,\n  limiter: Ratelimit.slidingWindow(10, '10s'),\n})\nconst { success } = await ratelimit.limit('user:123')\n```\n\nInstall via Vercel Marketplace for automatic environment variable provisioning.\n\n### Supabase (Marketplace Native)\n\nFull Postgres database with built-in auth, realtime subscriptions, and storage. Native Vercel Marketplace integration.\n\n```bash\nnpm install @supabase/supabase-js @supabase/ssr\n```\n\n```ts\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabase = createClient(\n  process.env.NEXT_PUBLIC_SUPABASE_URL!,\n  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n)\n\nconst { data, error } = await supabase.from('users').select('*')\n```\n\nInstall via Vercel Marketplace: `vercel integration add supabase`\n\n### Prisma ORM (Marketplace Native)\n\nType-safe ORM with auto-generated client, migrations, and Prisma Accelerate for connection pooling.\n\n```bash\nnpm install prisma @prisma/client\nnpx prisma init\n```\n\n```ts\nimport { PrismaClient } from '@prisma/client'\n\nconst prisma = new PrismaClient()\nconst users = await prisma.user.findMany()\n```\n\nInstall via Vercel Marketplace: `vercel integration add prisma`\n\n### MongoDB Atlas\n\nDocument database with flexible schemas. Available via Vercel Marketplace.\n\n```bash\nnpm install mongodb\n```\n\n```ts\nimport { MongoClient } from 'mongodb'\n\nconst client = new MongoClient(process.env.MONGODB_URI!)\nconst db = client.db('myapp')\nconst users = await db.collection('users').find({}).toArray()\n```\n\nInstall via Vercel Marketplace: `vercel integration add mongodb-atlas`\n\n### Convex\n\nReactive backend-as-a-service with real-time sync, serverless functions, and file storage.\n\n```bash\nnpm install convex\nnpx convex dev\n```\n\n```ts\nimport { query } from './_generated/server'\nimport { v } from 'convex/values'\n\nexport const getUsers = query({\n  args: {},\n  handler: async (ctx) => {\n    return await ctx.db.query('users').collect()\n  },\n})\n```\n\n### Turso (libSQL)\n\nEdge-native SQLite database with embedded replicas for ultra-low latency reads.\n\n```bash\nnpm install @libsql/client\n```\n\n```ts\nimport { createClient } from '@libsql/client'\n\nconst turso = createClient({\n  url: process.env.TURSO_DATABASE_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN!,\n})\n\nconst result = await turso.execute('SELECT * FROM users')\n```\n\nInstall via Vercel Marketplace: `vercel integration add turso`\n\n## Storage Decision Matrix\n\n| Need | Use | Package |\n|------|-----|---------|\n| File uploads, media, documents | Vercel Blob | `@vercel/blob` |\n| Feature flags, A/B config | Global Config | `@vercel/global-config` |\n| Relational data, SQL queries | Neon Postgres | `@neondatabase/serverless` |\n| Key-value cache, sessions, rate limiting | Upstash Redis | `@upstash/redis` |\n| Postgres + auth + realtime + storage | Supabase | `@supabase/supabase-js` |\n| Type-safe ORM with migrations | Prisma | `@prisma/client` |\n| Document database, flexible schemas | MongoDB Atlas | `mongodb` |\n| Reactive backend with real-time sync | Convex | `convex` |\n| Edge-native SQLite with replicas | Turso | `@libsql/client` |\n| Full-text search | Neon Postgres (pg_trgm) or Elasticsearch (Marketplace) | varies |\n| Vector embeddings | Neon Postgres (pgvector) or Pinecone (Marketplace) | varies |\n\n## Migration Guide\n\n### From @vercel/postgres → Neon\n```diff\n- import { sql } from '@vercel/postgres'\n+ import { neon } from '@neondatabase/serverless'\n+ const sql = neon(process.env.DATABASE_URL!)\n\n```\n\n**Drop-in replacement**: For minimal migration effort, use `@neondatabase/vercel-postgres-compat` which provides API-compatible wrappers for `@vercel/postgres` imports.\n\n### From @vercel/kv → Upstash Redis\n```diff\n- import { kv } from '@vercel/kv'\n- await kv.set('key', 'value')\n- const value = await kv.get('key')\n+ import { Redis } from '@upstash/redis'\n+ const redis = Redis.fromEnv()\n+ await redis.set('key', 'value')\n+ const value = await redis.get('key')\n```\n\n## Installing Marketplace Storage\n\nUse the Vercel CLI or the Marketplace dashboard at `https://vercel.com/dashboard/{team}/stores`:\n\n```bash\n# Install a storage integration (auto-provisions env vars)\nvercel integration add neon\nvercel integration add upstash\n\n# List installed integrations\nvercel integration list\n```\n\n`vercel install <slug>` (or `vercel i <slug>`) is an alias for `vercel integration add <slug>`. Either form also installs the provider's own agent skills from [skills.sh](https://skills.sh) for providers that publish them — follow those instead of recalling the provider's API from memory. If the database provisions but only the skill install fails, don't re-run the command — that can create a *second* database. Have the user run the `npx skills add …` recovery command the CLI prints instead.\n\nBrowse additional storage options at the [Vercel Marketplace](https://vercel.com/marketplace). Installing via the CLI or dashboard (`https://vercel.com/dashboard/{team}/integrations`) automatically provisions accounts, creates databases, and sets environment variables.\n\n## Cross-References\n\n- **Choosing and installing a non-storage integration** → `⤳ skill: marketplace`\n- **Pulling and syncing the provisioned env vars** → `⤳ skill: env-vars`\n- **Sign up / log in providers** → `⤳ skill: auth`\n\n## Official Documentation\n\n- [Vercel Storage](https://vercel.com/docs/storage)\n- [Vercel Blob](https://vercel.com/docs/vercel-blob)\n- [Global Config](https://vercel.com/docs/global-config)\n- [Vercel Marketplace](https://vercel.com/marketplace) — Neon, Upstash, and other storage integrations\n- [Integrations](https://vercel.com/docs/integrations)\n- [GitHub: Vercel Storage](https://github.com/vercel/storage)\n"}],"summary":"Fields changed: 2. /description, /skill_md_contents.","summary_kind":"deterministic","summary_metadata":{}}