nona-client
v4.0.1
Published
Typed JavaScript/TypeScript client for Nona — open-source, self-hosted remote config and feature flags (a Firebase Remote Config alternative).
Maintainers
Readme
nona-client
Official JavaScript/Node.js client for Nona — an open-source, self-hosted remote configuration and feature flag service, and a Firebase Remote Config alternative you run yourself. Read your config values and feature flags at runtime with a single typed call.
- Website: https://nonaconfig.com
- Source & docs: https://github.com/Ryware/nona-config/tree/development/client/javascript
Install
npm install nona-clientImport
This package is ESM-only, so use import:
import { createNonaClient, NonaClientError } from "nona-client";Create a client
const nona = createNonaClient({
baseUrl: "https://nona.example.com",
environmentId: "production",
apiKey: "your-api-key"
});Reads use working parameters by default. To use the active release, or pin a client to an exact release or release line, select release mode when constructing it:
const nona = createNonaClient({
baseUrl: "https://nona.example.com",
environmentId: "production",
apiKey: "your-api-key",
useReleases: true,
releaseVersion: "1.1.x"
});Omit releaseVersion while keeping useReleases: true to follow the active release. Source and release selection are fixed for the client lifetime; create another client for a different source or selector. When useReleases is false (the default), releaseVersion is retained on the client but ignored for requests and cache identity.
You can also pass the base URL as the first argument:
const nona = createNonaClient("https://nona.example.com", {
environmentId: "production",
apiKey: "your-api-key"
});Read config values
API keys are bound to one project, and the client is bound to one environment, so config reads only take a key.
const value = await nona.getConfigValue("Features:Checkout");
console.log(value.value);
console.log(value.contentType);If you only want the string value:
const checkoutEnabled = await nona.getStringValue("Features:Checkout");If the value contains JSON:
const settings = await nona.getJsonValue("App:Settings");
console.log(settings);If a key might not exist, use tryGetConfigValue:
const maybeValue = await nona.tryGetConfigValue("Missing:Key");
if (maybeValue === null) {
console.log("No value found");
}Fetch all values at startup
Use one bulk request to fetch every client-visible value and prime subsequent reads:
const values = await nona.getAllValues();
const checkout = await nona.tryGetConfigValue("Features:Checkout");
const banner = await nona.tryGetConfigValue("App:Banner");values is a map of { key: { value, contentType } }. The reads after getAllValues() are served from the in-memory snapshot even when cacheTtlMs is not enabled, so six startup flags require one HTTP request.
Pass an optional prefix to fetch one key group. Matching is case-insensitive, and a prefix may contain ASCII letters, digits, colons, dots, underscores, and dashes:
const groupA = await nona.getAllValues({ prefix: "GroupA:" });Omitting prefix or passing an empty string fetches all values. Each prefix has an independent ETag-backed snapshot; prefix casing variants such as GroupA: and groupa: share the same cache identity. Any other character causes the server to return 400 Bad Request; the client throws NonaClientError with status === 400, and the failed response is not cached.
The bulk endpoint accepts client and all API keys. It includes client-visible (client and all) entries and never returns server-only entries.
Repeated getAllValues() calls automatically use the response ETag. An unchanged snapshot produces 304 Not Modified and reuses the existing values.
Handle errors
Requests that fail with an HTTP error throw NonaClientError:
try {
await nona.getConfigValue("Missing:Key");
} catch (error) {
if (error instanceof NonaClientError) {
console.error(error.status);
console.error(error.errorCode);
console.error(error.detail);
console.error(error.message);
console.error(error.responseBody);
return;
}
throw error;
}Options
createNonaClient accepts these options:
baseUrl: the Nona server URLenvironmentId: environment used for config readsapiKey: API key for config readsuseReleases: read release snapshots instead of working parameters (defaultfalse)releaseVersion: optional exact release such as1.1.0or line such as1.1.xfetch: custom fetch implementationdefaultHeaders: headers added to every requestcacheTtlMs: cache TTL in milliseconds (disabled by default; set a positive value to enable)cacheMemoryLimitMegabytes: shared TTL and bulk-snapshot cache limit in MB (default5)
Cache helpers:
invalidateTtlCache(key, options?): removes only the matching cached requestclearTtlCache(): removes all TTL and bulk-primed cache entries
Runtime requirements
- Node.js 18 or newer
- Or any environment that provides
fetch,Headers, andResponse
