Config API used by Backstage core, backend, and CLI
npx @tessl/cli install tessl/npm-backstage--config@1.0.0The Backstage Config package provides a type-safe configuration API used by Backstage core components, backend services, and CLI tools. It enables hierarchical configuration loading, environment variable overrides, and runtime configuration validation with built-in support for development and production scenarios.
@backstage/core, @backstage/cli, or @backstage/backend-commonimport {
Config,
ConfigReader,
AppConfig,
// Deprecated types (use @backstage/types instead)
JsonValue,
JsonObject,
JsonArray,
JsonPrimitive
} from "@backstage/config";For CommonJS:
const {
Config,
ConfigReader,
AppConfig,
JsonValue,
JsonObject,
JsonArray,
JsonPrimitive
} = require("@backstage/config");import { ConfigReader } from "@backstage/config";
// Create a config from plain data
const configData = {
app: {
title: "My Backstage App",
baseUrl: "http://localhost:3000"
},
backend: {
port: 7000
}
};
const config = new ConfigReader(configData);
// Read configuration values
const appTitle = config.getString("app.title"); // "My Backstage App"
const port = config.getNumber("backend.port"); // 7000
const debug = config.getOptionalBoolean("app.debug"); // undefined
// Work with nested config objects
const appConfig = config.getConfig("app");
const baseUrl = appConfig.getString("baseUrl"); // "http://localhost:3000"The Backstage Config system is built around several key components:
The core Config interface provides methods for reading typed configuration values with optional and required variants.
interface Config {
/** Subscribe to configuration changes (optional method) */
subscribe?(onChange: () => void): { unsubscribe: () => void };
/** Check if a configuration key exists */
has(key: string): boolean;
/** List all available configuration keys */
keys(): string[];
/** Get a required configuration value of any type */
get<T = JsonValue>(key?: string): T;
/** Get an optional configuration value of any type */
getOptional<T = JsonValue>(key?: string): T | undefined;
/** Get a required nested configuration object */
getConfig(key: string): Config;
/** Get an optional nested configuration object */
getOptionalConfig(key: string): Config | undefined;
/** Get a required array of configuration objects */
getConfigArray(key: string): Config[];
/** Get an optional array of configuration objects */
getOptionalConfigArray(key: string): Config[] | undefined;
/** Get a required number value */
getNumber(key: string): number;
/** Get an optional number value */
getOptionalNumber(key: string): number | undefined;
/** Get a required boolean value */
getBoolean(key: string): boolean;
/** Get an optional boolean value */
getOptionalBoolean(key: string): boolean | undefined;
/** Get a required string value */
getString(key: string): string;
/** Get an optional string value */
getOptionalString(key: string): string | undefined;
/** Get a required array of strings */
getStringArray(key: string): string[];
/** Get an optional array of strings */
getOptionalStringArray(key: string): string[] | undefined;
}ConfigReader provides the concrete implementation of the Config interface with support for fallback chains and multiple configuration sources.
class ConfigReader implements Config {
/** Create a ConfigReader from configuration data */
constructor(
data: JsonObject | undefined,
context?: string,
fallback?: ConfigReader,
prefix?: string
);
/** Create a ConfigReader from multiple AppConfig sources */
static fromConfigs(configs: AppConfig[]): ConfigReader;
// Implements all Config interface methods
has(key: string): boolean;
keys(): string[];
get<T = JsonValue>(key?: string): T;
getOptional<T = JsonValue>(key?: string): T | undefined;
getConfig(key: string): ConfigReader;
getOptionalConfig(key: string): ConfigReader | undefined;
getConfigArray(key: string): ConfigReader[];
getOptionalConfigArray(key: string): ConfigReader[] | undefined;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
}Usage Examples:
import { ConfigReader, AppConfig } from "@backstage/config";
// Single configuration source
const config = new ConfigReader({
database: {
host: "localhost",
port: 5432,
ssl: true
}
});
const dbHost = config.getString("database.host"); // "localhost"
const dbPort = config.getNumber("database.port"); // 5432
const dbSsl = config.getBoolean("database.ssl"); // true
// Multiple configuration sources with precedence
const appConfigs: AppConfig[] = [
{
context: "default-config",
data: { app: { name: "Default App" }, port: 3000 }
},
{
context: "environment-config",
data: { port: 8080 } // This overrides the default port
}
];
const mergedConfig = ConfigReader.fromConfigs(appConfigs);
const appName = mergedConfig.getString("app.name"); // "Default App"
const port = mergedConfig.getNumber("port"); // 8080 (overridden)
// Working with nested objects
const dbConfig = config.getConfig("database");
const host = dbConfig.getString("host"); // "localhost"
// Optional values with defaults
const timeout = config.getOptionalNumber("database.timeout") ?? 30000;Types for representing configuration data and metadata.
/** Serialized configuration data with context and metadata */
interface AppConfig {
/** Source context (e.g., file path, environment) */
context: string;
/** The configuration data itself */
data: JsonObject;
/** Keys that were filtered out during loading */
filteredKeys?: string[];
/** Deprecated keys found in the configuration */
deprecatedKeys?: Array<{
key: string;
description: string;
}>;
}These types are deprecated and should be imported from @backstage/types instead:
/** @deprecated Use JsonPrimitive from @backstage/types instead */
type JsonPrimitive = string | number | boolean | null;
/** @deprecated Use JsonObject from @backstage/types instead */
type JsonObject = { [key: string]: JsonValue };
/** @deprecated Use JsonArray from @backstage/types instead */
type JsonArray = JsonValue[];
/** @deprecated Use JsonValue from @backstage/types instead */
type JsonValue = JsonPrimitive | JsonObject | JsonArray;The configuration system provides detailed error handling:
Error with message "Missing required config value at 'key'"TypeError with detailed type information and expected vs actual typesTypeError for malformed configuration key pathsError when string-to-number conversion failsDevelopment Mode Features: