@t3-oss/env-nextjs and Zod for type safety.
Setup
- Copy
.env.exampleto.envin your project root:
- Fill in the required values for your environment
- Variables are validated in
src/config/env.ts
Validation
All environment variables are validated using Zod schemas:server object are only accessible server-side. Variables in client must be prefixed with NEXT_PUBLIC_ and are exposed to the browser.
Core Configuration
Database
string
required
PostgreSQL connection string used by Drizzle ORM.
string
Production database URL used when running migrations in production.
Application URL
string
default:"http://localhost:3000"
Public URL of your application. Used for OAuth callbacks, email links, and API endpoints.Local development:Production:
Node Environment
enum
Runtime environment. Values:
development, production, testValidated as:string
default:"development"
Client-side environment indicator exposed to the browser.
Authentication (Better-Auth)
string
default:"dev-secret-change-in-production"
required
Secret key used to encrypt sessions and sign tokens.Generate a secure secret:Never use the default in production!
string
default:"http://localhost:3000"
Base URL of your application. Must match
NEXT_PUBLIC_APP_URL.boolean
default:"false"
Enable billing enforcement across the application.Validated as:
boolean
default:"false"
Require email verification for new user accounts.
OAuth Providers
All OAuth providers are optional. Configure only the ones you need.Google OAuth
string
Google OAuth client ID.Get credentials from: Google Cloud Console
string
Google OAuth client secret.
GitHub OAuth
string
GitHub OAuth application ID.Get credentials from: GitHub Developer Settings
string
GitHub OAuth application secret.
Microsoft OAuth
string
Microsoft/Azure AD application ID.Get credentials from: Azure Portal
string
Microsoft/Azure AD application secret.
string
default:"common"
Azure AD tenant ID. Use
common for multi-tenant applications.Facebook OAuth
string
Facebook app ID.Get credentials from: Facebook Developers
string
Facebook app secret.
Email Configuration
enum
default:"log"
Email service provider to use for transactional emails.Options: Set to
resend, postmark, nodemailer, plunk, custom, logValidated as:log in development to print emails to console.Email Defaults
string
Default sender email address for outgoing emails.
string
Default sender name for outgoing emails.
Resend (Recommended)
string
string
Verified domain for sending emails via Resend.
Postmark
Plunk
string
Plunk API key.Get from: Plunk Settings
SMTP / Nodemailer
string
SMTP server hostname.
number
SMTP server port.Validated as:Common ports:
587 (TLS), 465 (SSL), 25 (unencrypted)string
SMTP authentication username.
string
SMTP authentication password.
string
Enable TLS/SSL. Set to
"true" for port 465, "false" for port 587.Payment Providers
ShipFree supports multiple payment providers. Configure only the one you’re using.enum
default:"stripe"
Payment provider to use for billing and subscriptions.Options:
stripe, polar, lemonsqueezyValidated as:Stripe
string
string
Stripe webhook signing secret (starts with
whsec_).Used to verify webhook events from Stripe.string
Default Stripe price ID for subscriptions.
Stripe Price IDs (Public)
These are exposed to the client for displaying pricing.string
Stripe price ID for Starter plan (monthly billing).
string
Stripe price ID for Starter plan (yearly billing).
string
Stripe price ID for Pro plan (monthly billing).
string
Stripe price ID for Pro plan (yearly billing).
string
Stripe price ID for Enterprise plan (monthly billing).
string
Stripe price ID for Enterprise plan (yearly billing).
Polar
string
Polar API access token.Get from: Polar Settings
string
Polar webhook secret for verifying webhook events.
string
Your Polar organization ID.
string
Polar product ID for subscriptions.
enum
default:"production"
Polar environment.Options:
production, sandboxValidated as:Polar Product IDs (Public)
string
Polar product ID for Starter plan (monthly).
string
Polar product ID for Pro plan (monthly).
string
Polar product ID for Enterprise plan (monthly).
Lemon Squeezy
string
Lemon Squeezy API key.Get from: Lemon Squeezy Settings
string
Your Lemon Squeezy store ID.
string
Lemon Squeezy webhook secret.
Lemon Squeezy Product IDs (Public)
string
Lemon Squeezy product ID for Starter plan (monthly).
string
Lemon Squeezy product ID for Pro plan (monthly).
string
Lemon Squeezy product ID for Enterprise plan (monthly).
Cloudflare R2 Storage
Optional file storage using Cloudflare R2 (S3-compatible).string
Your Cloudflare account ID.Get from: Cloudflare R2 Dashboard
string
R2 access key ID.
string
R2 secret access key.
string
R2 bucket URL.
string
Public storage domain for accessing files.
string
Name of the public R2 bucket.
string
Name of the private R2 bucket.
Observability
Sentry
string
Sentry DSN for error tracking (server-side).
string
Sentry DSN for client-side error tracking.
string
Sentry authentication token for uploading source maps.
Premium Template Purchase
These variables are for the premium template purchase feature. This is completely separate from your application’s payment system and can be removed if not needed. See the README for removal instructions.
Stripe secret key for template purchases (separate from app payments).
Stripe price ID for the one-time $90 premium template purchase.
Webhook secret for premium purchase webhooks.
Stripe publishable key for template purchases (client-side).
Discord invite link for premium template purchasers.
Utility Functions
ShipFree provides utility functions for working with environment variables insrc/config/feature-flags.ts:
Type Safety
Access environment variables through the validatedenv object:
env object ensures:
- All required variables are present at build time
- Values match expected types (string, number, boolean, enum)
- Default values are applied
- Client variables are properly prefixed