Environment Variables
Relevant source files
The following files were used as context for generating this wiki page:Environment variables are used to manage configuration and secrets for both the server-side and client-side components of the application. The system employs a custom loading script that reads from a .env file but gives precedence to system-level environment variables. This ensures that variables injected by a deployment platform (like Manus) are not overridden by local development values.
Variables are segregated: sensitive keys are used only on the server, while non-sensitive configuration is exposed to the Expo client application using an EXPO_PUBLIC_ prefix.
Loading and Precedence
The application uses a custom script, scripts/load-env.js, to load environment variables. This script is explicitly imported at the top of the Expo configuration file, ensuring variables are available before the app build process begins.
The loading process prioritizes system environment variables over those defined in the local .env file. If a variable is already present in process.env, its corresponding value in the .env file is ignored.
Sources: app.config.ts:2, scripts/load-env.js:5-8
Loading Flow
The following diagram illustrates the logic for loading an environment variable.
Sources: scripts/load-env.js:18-23
Server-Side Variables
The server-side code, running in a Node.js environment, uses a Zod schema to validate and parse environment variables. This provides type safety and ensures that critical variables are present at runtime.
Sources: server/_core/env.ts:3-12
Schema and Usage
The ENV object is derived from process.env and validated against the envSchema.
// server/_core/env.ts
import { z } from "zod";
const envSchema = z.object({
// ...
FORGE_API_KEY: z.string().min(1),
FORGE_API_URL: z.string().url().optional(),
// ...
});
export const ENV = envSchema.parse(process.env);
Sources: server/_core/env.ts:3-12
These variables are then used to configure backend services like the LLM and storage proxies.
// server/_core/llm.ts
const assertApiKey = () => {
if (!ENV.forgeApiKey) {
throw new Error("OPENAI_API_KEY is not configured");
}
};
Sources: server/_core/llm.ts:182-186
Key Server-Side Variables
| Variable | Type | Description | Source File |
|---|---|---|---|
FORGE_API_KEY | string | API key for the Manus Forge service (used for LLM and storage). | server/_core/env.ts:7 |
FORGE_API_URL | string (URL) | Base URL for the Manus Forge API. | server/_core/env.ts:8 |
Sources: server/_core/env.ts, server/_core/llm.ts, server/storage.ts
Client-Side (Expo) Variables
For variables to be accessible in the Expo client application, they must be prefixed with EXPO_PUBLIC_. The load-env.js script handles the mapping from system/.env variables to these public-facing variables. This prevents sensitive keys from being bundled with the client-side code.
Sources: scripts/load-env.js:26-34
System to Expo Mapping
A specific mapping is defined to translate system-level variables (which might have generic names like VITE_APP_ID) into the required EXPO_PUBLIC_ format. This mapping only occurs if the target EXPO_PUBLIC_ variable is not already set.
The diagram below shows how a system variable is mapped for client-side use.
Sources: scripts/load-env.js:26-39
Mapping Table
System / .env Variable | Expo Public Variable | Condition |
|---|---|---|
VITE_APP_ID | EXPO_PUBLIC_APP_ID | process.env.EXPO_PUBLIC_APP_ID is not set. |
VITE_OAUTH_PORTAL_URL | EXPO_PUBLIC_OAUTH_PORTAL_URL | process.env.EXPO_PUBLIC_OAUTH_PORTAL_URL is not set. |
OAUTH_SERVER_URL | EXPO_PUBLIC_OAUTH_SERVER_URL | process.env.EXPO_PUBLIC_OAUTH_SERVER_URL is not set. |
OWNER_OPEN_ID | EXPO_PUBLIC_OWNER_OPEN_ID | process.env.EXPO_PUBLIC_OWNER_OPEN_ID is not set. |
OWNER_NAME | EXPO_PUBLIC_OWNER_NAME | process.env.EXPO_PUBLIC_OWNER_NAME is not set. |
Sources: scripts/load-env.js:27-33
Client-Side Consumption
Components within the app/ directory access these variables via process.env. For example, the OAuth configuration relies heavily on these public variables.
// constants/oauth.ts
const env = {
portal: process.env.EXPO_PUBLIC_OAUTH_PORTAL_URL ?? "",
server: process.env.EXPO_PUBLIC_OAUTH_SERVER_URL ?? "",
appId: process.env.EXPO_PUBLIC_APP_ID ?? "",
ownerId: process.env.EXPO_PUBLIC_OWNER_OPEN_ID ?? "",
ownerName: process.env.EXPO_PUBLIC_OWNER_NAME ?? "",
apiBaseUrl: process.env.EXPO_PUBLIC_API_BASE_URL ?? "",
// ...
};
Sources: constants/oauth.ts:9-17
The following sequence diagram shows how the OAuth module retrieves its configuration.
Sources: scripts/load-env.js, constants/oauth.ts, app.config.ts