Env Variables
Environment variables are used to configure projects based on the context in which they run. This allows them to exhibit different behaviors in different environments, such as development, staging, or production.
For instance, during development, you may want your project to connect to a local development database running on your machine, but in production, you want it to connect to the production database. Similarly, in development, you may want to use a test Stripe account, while in production, your app should use a real Stripe account.
While some env vars are required by Wasp, such as the database connection or secrets for social auth, you can also define your env vars for any other useful purposes, and then access them in the code.
Let's go over the available env vars in Wasp, how to define them, and how to use them in your project.
Client Env Vars
Client environment variables are injected into the client Javascript code during the build process, making them public and readable by anyone. Therefore, you should never store secrets in them (such as secret API keys, you should store secrets in the server env variables).
Client env vars must be prefixed with REACT_APP_
, for example: REACT_APP_SOME_VAR_NAME=...
for security reasons. Wasp will only inject env vars that start with this prefix into the client code to prevent accidental exposure of sensitive information.
You can read them from the client code like this:
- JavaScript
- TypeScript
import { env } from 'wasp/client'
console.log(env.REACT_APP_SOME_VAR_NAME)
import { env } from 'wasp/client'
console.log(env.REACT_APP_SOME_VAR_NAME)
Read more about the env
object in the API reference.
Wasp Client Env Vars
Here are the client env vars that Wasp defines:
General Configuration
These are some general env variables used for various Wasp features:
Name | Type | Notes |
---|---|---|
REACT_APP_API_URL | URLoptionalDefault: http://localhost:3001 | The client uses this as the server URL. |
Server Env Vars
You can store secret values (e.g. secret API keys) in the server env variables since they are not publicly readable. You can define them without any special prefix, such as SOME_VAR_NAME=...
.
You can read the env vars from server code like this:
- JavaScript
- TypeScript
import { env } from 'wasp/server'
console.log(env.SOME_VAR_NAME)
import { env } from 'wasp/server'
console.log(env.SOME_VAR_NAME)
Read more about the env
object in the API reference.
Wasp Server Env Vars
General Configuration
These are some general env variables used for various Wasp features:
Name | Type | Notes |
---|---|---|
DATABASE_URL | Stringrequired | The URL of the PostgreSQL database you want your app to use. |
WASP_WEB_CLIENT_URL | URLrequired | Server uses this value as your client URL in various features e.g. linking to your app in e-mails. |
WASP_SERVER_URL | URLrequired | Server uses this value as your server URL in various features e.g. to redirect users when logging in with OAuth providers like Google or GitHub. |
JWT_SECRET | Stringrequired | Needed to generate secure tokens. Generate a random string at least 32 characters long. |
PORT | IntegeroptionalDefault: 3001 | This is where the server listens for requests. |
SMTP Email Sender
If you are using SMTP
as your email sender, you need to provide the following environment variables:
Name | Type | Notes |
---|---|---|
SMTP_HOST | Stringrequired | The SMTP server host. |
SMTP_PORT | Integerrequired | The SMTP server port. |
SMTP_USERNAME | Stringrequired | The SMTP server username. |
SMTP_PASSWORD | Stringrequired | The SMTP server password. |
SendGrid Email Sender
If you are using SendGrid
as your email sender, you need to provide the following environment variables:
Name | Type | Notes |
---|---|---|
SENDGRID_API_KEY | Stringrequired | The SendGrid API key. |
Mailgun Email Sender
If you are using Mailgun
as your email sender, you need to provide the following environment variables:
Name | Type | Notes |
---|---|---|
MAILGUN_API_KEY | Stringrequired | The Mailgun API key. |
MAILGUN_DOMAIN | Stringrequired | The Mailgun domain. |
MAILGUN_API_URL | URLoptional | Useful if you want to use the EU API endpoint (https://api.eu.mailgun.net ). |
OAuth Providers
If you are using OAuth, you need to provide the following environment variables:
Name | Type | Notes |
---|---|---|
<PROVIDER_NAME>_CLIENT_ID | Stringrequired | The client ID provided by the OAuth provider. |
<PROVIDER_NAME>_CLIENT_SECRET | Stringrequired | The client secret provided by the OAuth provider. |
* <PROVIDER_NAME>
is the uppercase name of the provider you are using. For example, if you are using Google OAuth, you need to provide the GOOGLE_CLIENT_ID
and GOOGLE_CLIENT_SECRET
environment variables.
If you are using Keycloak, you'll need to provide one extra environment variable:
Name | Type | Notes |
---|---|---|
KEYCLOAK_REALM_URL | URLrequired | The URL of the Keycloak realm. |
Jobs
Name | Type | Notes |
---|---|---|
PG_BOSS_NEW_OPTIONS | Stringoptional | It's parsed as JSON. Enables you to provide custom config for PgBoss. |
Development
We provide some helper env variables in development:
Name | Type | Notes |
---|---|---|
SKIP_EMAIL_VERIFICATION_IN_DEV | BooleanoptionalDefault: false | If set to true, automatically sets user emails as verified in development. |
Defining Env Vars in Development
During development (wasp start
), there are two ways to provide env vars to your Wasp project:
- Using
.env
files. (recommended) - Using shell. (useful for overrides)
1. Using .env (dotenv) Files
This is the recommended method for providing env vars to your Wasp project during development.
In the root of your Wasp project you can create two distinct files:
.env.server
for env vars that will be provided to the server.
Variables are defined in these files in the form of NAME=VALUE
, for example:
DATABASE_URL=postgresql://localhost:5432
SOME_VAR_NAME=somevalue
.env.client
for env vars that will be provided to the client.Variables are defined in these files in the form of
NAME=VALUE
, for example:.env.clientREACT_APP_SOME_VAR_NAME=somevalue
Client Env Var PrefixClient env vars must be prefixed with
REACT_APP_
, for example:REACT_APP_SOME_VAR_NAME=...
for security reasons. Wasp will only inject env vars that start with this prefix into the client code to prevent accidental exposure of sensitive information.
.env.server
should not be committed to version control as it can contain secrets, while .env.client
can be versioned as it must not contain any secrets.
By default, in the .gitignore
file that comes with a new Wasp app, we ignore all dotenv files.
2. Using Shell
If you set environment variables in the shell where you run your Wasp commands (e.g., wasp start
), Wasp will recognize them.
You can set environment variables in the .profile
or a similar file, which will set them permanently, or you can set them temporarily by defining them at the start of a command (SOME_VAR_NAME=SOMEVALUE wasp start
).
This is not specific to Wasp and is simply how environment variables can be set in the shell.
Defining environment variables in this way can be cumbersome even for a single project and even more challenging to manage if you have multiple Wasp projects. Therefore, we do not recommend this as a default method for providing environment variables to Wasp projects during development, you should use .env files instead. However, it can be useful for occasionally overriding specific environment variables because environment variables set this way take precedence over those defined in .env
files.
Defining Env Vars in Production
Defining env variables in production will depend on where you are deploying your Wasp project. In general, you will define them via mechanisms that your hosting provider provides.
We talk about how to define env vars for each deployment option in the deployment section.
Custom Env Var Validations
If your code requires some environment variables, you usually want to ensure that they are correctly defined. In Wasp, you can define your environment variables validation by defining a Zod object schema and telling Wasp to use it.
Zod is a library that lets you define what you expect from your data. For example, you can use Zod to define that:
- A value should be a string that's a valid email address.
- A value should be a number between 0 and 100.
- ... and much more.
Take a look at an example of defining env vars validation:
- JavaScript
- TypeScript
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const serverEnvValidationSchema = defineEnvValidationSchema(
z.object({
STRIPE_API_KEY: z.string({
required_error: 'STRIPE_API_KEY is required.',
}),
})
)
export const clientEnvValidationSchema = defineEnvValidationSchema(
z.object({
REACT_APP_NAME: z.string().default('TODO App'),
})
)
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const serverEnvValidationSchema = defineEnvValidationSchema(
z.object({
STRIPE_API_KEY: z.string({
required_error: 'STRIPE_API_KEY is required.',
}),
})
)
export const clientEnvValidationSchema = defineEnvValidationSchema(
z.object({
REACT_APP_NAME: z.string().default('TODO App'),
})
)
The defineEnvValidationSchema
function ensures your Zod schema is type-checked.
app myApp {
...
client: {
envValidationSchema: import { clientEnvValidationSchema } from "@src/env",
},
server: {
envValidationSchema: import { serverEnvValidationSchema } from "@src/env",
},
}
You defined schemas for both the client and the server env vars and told Wasp to use them. Wasp merges your env validation schemas with the built-in env vars validation schemas when it validates the process.env
object on the server and the import.meta.env
object on the client.
This means you can use the env
object to access your env vars like this:
import { env } from 'wasp/server'
const stripeApiKey = env.STRIPE_API_KEY
Read more about the env object in the API Reference.
API Reference
There are Wasp-defined and user-defined env vars. Wasp already comes with built-in validation for Wasp-defined env vars. For your env vars, you can define your own validation.
Client Env Vars
User-defined env vars validation
You can define your client env vars validation like this:
- JavaScript
- TypeScript
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const envValidationSchema = defineEnvValidationSchema(
z.object({
REACT_APP_ANALYTICS_ID: z.string({
required_error: 'REACT_APP_ANALYTICS_ID is required.',
}),
})
)
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const envValidationSchema = defineEnvValidationSchema(
z.object({
REACT_APP_ANALYTICS_ID: z.string({
required_error: 'REACT_APP_ANALYTICS_ID is required.',
}),
})
)
The defineEnvValidationSchema
function ensures your Zod schema is type-checked.
app myApp {
...
client: {
envValidationSchema: import { envValidationSchema } from "@src/env",
},
}
Wasp merges your env validation schemas with the built-in env vars validation schemas when it validates the import.meta.env
object.
Accessing env vars in client code
You can access both Wasp-defined and user-defined client env vars in your client code using the env
object:
- JavaScript
- TypeScript
import { env } from 'wasp/client'
// Wasp-defined
const apiUrl = env.REACT_APP_API_URL
// User-defined
const analyticsId = env.REACT_APP_ANALYTICS_ID
import { env } from 'wasp/client'
// Wasp-defined
const apiUrl = env.REACT_APP_API_URL
// User-defined
const analyticsId = env.REACT_APP_ANALYTICS_ID
You can use import.meta.env.REACT_APP_SOME_VAR_NAME
directly in your code. We don't recommend this since import.meta.env
isn't validated and missing env vars can cause runtime errors.
Server Env Vars
User-defined env vars validation
You can define your env vars validation like this:
- JavaScript
- TypeScript
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const envValidationSchema = defineEnvValidationSchema(
z.object({
STRIPE_API_KEY: z.string({
required_error: 'STRIPE_API_KEY is required.',
}),
})
)
import * as z from 'zod'
import { defineEnvValidationSchema } from 'wasp/env'
export const envValidationSchema = defineEnvValidationSchema(
z.object({
STRIPE_API_KEY: z.string({
required_error: 'STRIPE_API_KEY is required.',
}),
})
)
The defineEnvValidationSchema
function ensures your Zod schema is type-checked.
app myApp {
...
server: {
envValidationSchema: import { envValidationSchema } from "@src/env",
},
}
Wasp merges your env validation schemas with the built-in env vars validation schemas when it validates the process.env
object.
Accessing env vars in server code
You can access both Wasp-defined and user-defined client env vars in your client code using the env
object:
- JavaScript
- TypeScript
import { env } from 'wasp/server'
// Wasp-defined
const serverUrl = env.WASP_SERVER_URL
// User-defined
const stripeApiKey = env.STRIPE_API_KEY
import { env } from 'wasp/server'
// Wasp-defined
const serverUrl = env.WASP_SERVER_URL
// User-defined
const stripeApiKey = env.STRIPE_API_KEY
You can use process.env.SOME_SECRET
directly in your code. We don't recommend this since process.env
isn't validated and missing env vars can cause runtime errors.