Configuration API

Catalyst reads runtime and build configuration from config/config.json. This page covers the contract that the framework expects. For a guided walkthrough, see Configuration.

Top-Level Configuration

These keys are part of the core web runtime:

KeyTypeRequiredPurpose
NODE_SERVER_HOSTNAMEstringYesHostname for the Node SSR server
NODE_SERVER_PORTnumberYesPort for the Node SSR server
BUILD_OUTPUT_PATHstringYesOutput directory for production assets
PUBLIC_STATIC_ASSET_PATHstringYesPublic mount path for static assets
PUBLIC_STATIC_ASSET_URLstringYesBase URL for emitted static assets
CLIENT_ENV_VARIABLESstring[]YesVariables that should be exposed to the client bundle

Application-specific values such as API_URL can also live in this file. They are available on the server through process.env.

Client-Exposed Environment Variables

Catalyst does not expose every config key to browser code automatically. Add the keys you want available on the client to CLIENT_ENV_VARIABLES.

{
"API_URL": "https://api.example.com",
"ANALYTICS_ID": "UA-123456",
"DATABASE_URL": "postgresql://internal-db",
"CLIENT_ENV_VARIABLES": ["API_URL", "ANALYTICS_ID"]
}

In this example:

  • process.env.API_URL is available on both server and client.
  • process.env.ANALYTICS_ID is available on both server and client.
  • process.env.DATABASE_URL stays server-only.

Keep this list small. Any key included here becomes visible in the client bundle.

WEBVIEW_CONFIG

Universal app settings live under WEBVIEW_CONFIG inside the same file.

config/config.json
{
"WEBVIEW_CONFIG": {
"port": "3005",
"LOCAL_IP": "192.168.XX.XX",
"appInfo": "android-5Feb2026-v2.1.0",
"useHttps": false,
"profiler": {
"enabled": false
},
"android": {
"appName": "My App",
"packageName": "com.example.myapp",
"buildType": "debug",
"sdkPath": "/Users/yourname/Library/Android/sdk",
"emulatorName": "Pixel_5_API_30"
},
"ios": {
"appName": "My App",
"appBundleId": "com.example.myapp",
"buildType": "Debug",
"simulatorName": "iPhone 17 Pro"
},
"accessControl": {
"enabled": true,
"allowedUrls": [
"*.yourdomain.com*",
"http://localhost:*"
]
},
"splashScreen": {
"duration": 2000,
"minDuration": 0,
"backgroundColor": "#ffffff",
"imageWidth": 400,
"imageHeight": 200,
"cornerRadius": 20
}
}
}

Required Universal App Fields

Shared fields

KeyRequiredNotes
WEBVIEW_CONFIG.portYesPort the native WebView should load
WEBVIEW_CONFIG.LOCAL_IPYesUse your LAN IP, not localhost
WEBVIEW_CONFIG.appInfoYesBuild identifier used by native tooling
WEBVIEW_CONFIG.useHttpsNoDefaults to false
WEBVIEW_CONFIG.profiler.enabledNoEnables the debug-only Catalyst Profiler; defaults to false

Android fields

KeyRequiredNotes
WEBVIEW_CONFIG.android.sdkPathYesAbsolute path to the Android SDK
WEBVIEW_CONFIG.android.emulatorNameYes for debugRequired for emulator-based debug builds
WEBVIEW_CONFIG.android.buildTypeNodebug or release
WEBVIEW_CONFIG.android.keystoreConfigYes for releaseNeeded to sign release output
WEBVIEW_CONFIG.android.buildOptimisationNoEnables Android build optimisation

iOS fields

KeyRequiredNotes
WEBVIEW_CONFIG.ios.appBundleIdRequired for distributionSet this explicitly for release builds
WEBVIEW_CONFIG.ios.buildTypeNoMust be Debug or Release, case-sensitive
WEBVIEW_CONFIG.ios.simulatorNameNoUsed for simulator builds
WEBVIEW_CONFIG.ios.deviceUDIDNoFor physical device builds
WEBVIEW_CONFIG.ios.developmentTeamRequired with deviceUDIDApple team ID for signing
WEBVIEW_CONFIG.ios.cachePatternNoArray of glob-style URL patterns (e.g. ["*.css", "*.js"]) the native WebView cache should match — a single string is treated as one literal pattern, not comma-split; when unset, no pattern-based caching is enabled (offline-route caching can still apply)

Access Control

Use WEBVIEW_CONFIG.accessControl to whitelist outbound URLs used by the WebView and native request flows.

{
"WEBVIEW_CONFIG": {
"accessControl": {
"enabled": true,
"allowedUrls": [
"*.yourdomain.com*",
"https://api.example.com/*",
"http://localhost:*"
]
}
}
}

If you enable access control, make sure every required API, CDN, and localhost URL is included.

Splash Screen

The splash screen configuration belongs inside WEBVIEW_CONFIG.splashScreen, not at the top level of config.json.

KeyTypeNotes
backgroundColorstringDefaults to white
durationnumberPrimarily relevant on iOS. Ignored when public/splashscreen.html exists
minDurationnumberMinimum time in ms the HTML splash stays on screen. Defaults to 0
imageWidthnumberWidth of the splash asset
imageHeightnumberHeight of the splash asset
cornerRadiusnumberiOS rounded corners

Place splash assets at:

  • public/android/splashscreen.{png|jpg|jpeg|gif|bmp|webp}
  • public/ios/splashscreen.{png|jpg|jpeg}
  • public/splashscreen.html (optional, shared by both platforms)

When splashScreen is set and public/splashscreen.html exists, the app shows the native image first, then the HTML splash, and switches to the app once its first page has loaded and minDuration has passed. The HTML splash is dismissed after 10 seconds even if the page is still loading. The file must be self-contained, with inline CSS and JavaScript and images as data: URIs. It has no access to the native bridge and should not make network requests, which Android blocks. Remove the file to go back to the image-only splash. See Universal App Configuration for the full rules and an example.

Validation Notes

  • Missing required top-level config keys cause startup failures.
  • Using CLIENT_ENV_KEYS is outdated. The current key is CLIENT_ENV_VARIABLES.
  • iOS build types are case-sensitive: use Debug or Release.
  • LOCAL_IP should be a reachable LAN IP for emulator or device builds.
  • WEBPACK_DEV_SERVER_HOSTNAME, WEBPACK_DEV_SERVER_PORT, and ANALYZE_BUNDLE are no longer required or read, so you can delete them or leave them in place.