Skip to content

Plugins

Plugins extend nevr-env with pre-built schemas, auto-discovery, and CLI integration for popular services.

Why Plugins?

Instead of manually defining schemas for every service:

ts
// ❌ Without plugins - repetitive and error-prone
const env = createEnv({
  server: {
    DATABASE_URL: z.string().url().refine(s => s.startsWith("postgres://")),
    STRIPE_SECRET_KEY: z.string().regex(/^sk_(test|live)_/),
    CLERK_SECRET_KEY: z.string(),
    // ... more boilerplate
  },
  runtimeEnv: process.env,
});

Use plugins with namespaces:

ts
// ✅ With plugins - instant, correct, discoverable
import { createEnv } from "nevr-env";
import { auth, database, payment } from "nevr-env/plugins";

const env = createEnv({
  plugins: [
    auth.clerk(),
    database.postgres({ pool: true }),
    payment.stripe({ webhook: true }),
  ],
  runtimeEnv: process.env,
});

// env.CLERK_SECRET_KEY, env.DATABASE_URL, env.STRIPE_SECRET_KEY - all typed!

Available Namespaces

auth - Authentication Providers

  • betterAuth - Better-Auth with OAuth providers
  • clerk - Clerk authentication
  • auth0 - Auth0 identity platform
  • nextauth - NextAuth.js / Auth.js

database - Database Providers

  • postgres - PostgreSQL with Docker auto-discovery
  • redis - Redis with Upstash support
  • supabase - Supabase Backend-as-a-Service

payment - Payment Providers

  • stripe - Stripe payments with webhooks

ai - AI/LLM Providers

  • openai - OpenAI API with Azure support

email - Email Providers

  • resend - Resend email API

cloud - Cloud Providers

  • aws - AWS services (S3, SES, SQS, etc.)

Using Plugins

ts
import { createEnv } from "nevr-env";
import { auth, database, payment, ai, email, cloud } from "nevr-env/plugins";

const env = createEnv({
  plugins: [
    // Authentication
    auth.betterAuth({ providers: ["google", "github"] }),
    
    // Database
    database.postgres({ pool: true }),
    database.redis({ cluster: true }),
    
    // Payments
    payment.stripe({ webhook: true }),
    
    // AI
    ai.openai({ organization: true }),
    
    // Email
    email.resend({ fromEmail: true }),
    
    // Cloud
    cloud.aws({ s3: true, ses: true }),
  ],
  server: {
    // Add your custom variables
    NODE_ENV: z.enum(["development", "test", "production"]),
  },
  runtimeEnv: process.env,
});

The extend Option

Every plugin supports extend to add custom fields:

ts
const env = createEnv({
  plugins: [
    stripe({
      webhook: true,
      extend: {
        STRIPE_PRODUCT_ID: z.string().startsWith("prod_"),
        STRIPE_TAX_RATE_ID: z.string().startsWith("txr_").optional(),
      },
    }),
  ],
});

Plugin Options

Authentication Plugins

Better-Auth Options

ts
auth.betterAuth({
  // OAuth providers to include
  providers: ["google", "github", "discord"],
  // Include email/password fields
  emailPassword: true,
  // Include magic link configuration
  magicLink: true,
  // Include 2FA configuration
  twoFactor: true,
  // Include session configuration
  session: true,
  // Include rate limiting
  rateLimit: true,
})

Clerk Options

ts
auth.clerk({
  // Include JWT verification key
  jwtKey: true,
  // Include webhook secret
  webhook: true,
  // Include sign-in/sign-up URLs
  urls: true,
  // Include organization settings
  organization: true,
})

Auth0 Options

ts
auth.auth0({
  // Include custom domain
  domain: true,
  // Include Management API settings
  management: true,
  // Include API audience
  api: true,
})

NextAuth Options

ts
auth.nextauth({
  // OAuth providers
  providers: ["google", "github"],
  // Include database adapter config
  database: true,
})

Database Plugins

PostgreSQL Options

ts
database.postgres({
  // Include read replica URL field
  readReplica: true,
  // Include connection pool settings
  pool: true,
  // SSL settings
  ssl: true,
  // Custom variable names
  variableNames: {
    url: "MY_DATABASE_URL",
    host: "DB_HOST",
  },
})

Redis Options

ts
database.redis({
  // Include cluster configuration
  cluster: true,
  // Include sentinel configuration
  sentinel: true,
  // Require TLS connections
  tls: true,
  // Custom variable names
  variableNames: {
    url: "REDIS_URL",
  },
})

Supabase Options

ts
database.supabase({
  // Include direct database connection
  database: true,
  // Include storage configuration
  storage: true,
  // Include edge functions config
  functions: true,
})

Payment Plugins

Stripe Options

ts
payment.stripe({
  // Only allow test keys (useful for development)
  testMode: true,
  // Include webhook secret field
  webhook: true,
  // Include Stripe Connect configuration
  connect: true,
  // Custom variable names
  variableNames: {
    secretKey: "MY_STRIPE_KEY",
  },
})

AI Plugins

OpenAI Options

ts
ai.openai({
  // Include organization ID field
  organization: true,
  // Include project ID field
  project: true,
  // Include model configuration
  model: true,
  // Default model to use
  defaultModel: "gpt-4o",
  // Include Azure OpenAI configuration
  azure: true,
})

Email Plugins

Resend Options

ts
email.resend({
  // Include from email configuration
  fromEmail: true,
  // Include audience/contacts configuration
  audience: true,
  // Include webhook secret
  webhook: true,
})

Cloud Plugins

AWS Options

ts
cloud.aws({
  // Include S3 configuration
  s3: true,
  // Include SES email configuration
  ses: true,
  // Include SQS queue configuration
  sqs: true,
  // Include Lambda configuration
  lambda: true,
  // AWS region
  region: "us-east-1",
})

Full documentation for each plugin is available in the Plugins Reference section.

Auto-Discovery

Plugins automatically discover configuration from:

  • Docker / Podman containers - Running postgres/redis containers (auto-detects docker or podman CLI)
  • Config files - docker-compose.yml, .env.example
  • Cloud providers - Vercel, Railway, Heroku environment detection
  • AWS credentials - ~/.aws/credentials and ~/.aws/config files

Auto-discovery is enabled by default for all plugins. It works with both Docker and Podman — the container runtime is detected automatically, so no configuration is needed. You can disable it per-plugin:

ts
database.postgres({ autoDiscover: false })

CLI Integration

Plugins integrate with the CLI wizard:

bash
$ npx nevr-env fix

Missing: DATABASE_URL
[postgres plugin detected]

? How would you like to set DATABASE_URL?
 Use discovered Docker container (postgres:5432/mydb)
  Enter connection string manually
  Skip for now

Tree-Shaking & Deep Imports

For optimal bundle size, use standalone deep imports instead of the barrel export. Each plugin has its own entry point that only pulls in the code for that specific plugin:

ts
// ✅ Best for bundle size — only loads the postgres plugin code
import { postgres } from "nevr-env/plugins/postgres";
import { stripe } from "nevr-env/plugins/stripe";

const env = createEnv({
  plugins: [postgres(), stripe({ webhook: true })],
  runtimeEnv: process.env,
});

Available deep import paths:

Import PathPlugin
nevr-env/plugins/postgresPostgreSQL
nevr-env/plugins/redisRedis
nevr-env/plugins/supabaseSupabase
nevr-env/plugins/stripeStripe
nevr-env/plugins/openaiOpenAI
nevr-env/plugins/resendResend
nevr-env/plugins/clerkClerk
nevr-env/plugins/auth0Auth0
nevr-env/plugins/awsAWS
nevr-env/plugins/better-authBetter Auth
nevr-env/plugins/nextauthNextAuth

You can also import by namespace (pulls all providers in that namespace):

ts
import { auth } from "nevr-env/plugins/auth";
import { database } from "nevr-env/plugins/database";

Or use the barrel export when bundle size is not a concern:

ts
// Pulls all plugins — convenient but heavier
import { auth, database, payment } from "nevr-env/plugins";

Next Steps

Released under the MIT License.