JavaScript client
Package: nona-client
OpenFeature provider package: nona-openfeature-provider
Requirements:
- Node.js 18 or newer, or a runtime with
fetch,Headers, andResponse - ESM imports
The JavaScript client is a good fit for:
- Node.js services
- server-side JavaScript applications
- React Native and similar environments that can use
fetch - teams that want a lighter integration than OpenFeature but more convenience than raw HTTP
Install
Section titled “Install”npm install nona-clientPrepare the value in admin
Section titled “Prepare the value in admin”Before writing app code:
- open
Projects - open the project the app belongs to
- select the target environment such as
production - create the parameter or flag you want to read
- publish a release and set it active
- create an API key in the
API Keyssection - choose
clientscope for React Native or other app-side reads
For a first test, create a boolean parameter such as Features:Checkout.
Prepare the value with the CLI
Section titled “Prepare the value with the CLI”nona entries set \ --project storefront \ --environment production \ --key Features:Checkout \ --value true \ --scope client \ --content-type boolean
nona keys create \ --project storefront \ --name "React Native app" \ --scope client \ --environment productionThen publish and activate a release for the environment in admin.
Read a string
Section titled “Read a string”import { createNonaClient } from "nona-client";
const nona = createNonaClient({ baseUrl: "https://nona.example.com", environmentId: "production", apiKey: process.env.NONA_API_KEY});
const checkout = await nona.getStringValue("Features:Checkout");
const checkoutEnabled = checkout === "true";For actual feature flags, it is usually better to keep the entry typed as boolean, then inspect the metadata or use OpenFeature if you want a flag-oriented interface.
Read a boolean flag cleanly
Section titled “Read a boolean flag cleanly”const checkout = await nona.getConfigValue("Features:Checkout");
const checkoutEnabled = checkout.contentType === "boolean" && checkout.value === "true";That keeps the application aligned with Nona’s real content type instead of treating every flag as a plain string.
Read value metadata
Section titled “Read value metadata”const value = await nona.getConfigValue("Features:Checkout");
console.log(value.value);console.log(value.contentType);contentType is one of text, number, boolean, or json.
This is useful when one application needs to inspect the logical type before deciding how to handle the value.
Read JSON
Section titled “Read JSON”const settings = await nona.getJsonValue("App:Settings");Example setup in Nona:
- key:
App:Settings - content type:
json - scope:
client
Use JSON when related settings belong together and your application naturally consumes them as one object.
Return null for missing keys
Section titled “Return null for missing keys”const value = await nona.tryGetConfigValue("Missing:Key");
if (value === null) { console.log("Key was not found");}This is helpful for optional settings or cases where a key may not exist in every environment yet.
Pin a release version
Section titled “Pin a release version”By default, reads use the active release selected for the environment.
Pin a client to an exact release or release line with releaseVersion:
const nona = createNonaClient({ baseUrl: "https://nona.example.com", environmentId: "production", apiKey: process.env.NONA_API_KEY, releaseVersion: "1.1.x"});Use an exact version such as 1.1.0 for a fixed snapshot. Use a line such as 1.1.x to read the highest patch in that line.
You can override the configured version for one request:
const value = await nona.getConfigValue("Features:Checkout", { releaseVersion: "1.1.0"});Handle HTTP errors
Section titled “Handle HTTP errors”import { createNonaClient, NonaClientError } from "nona-client";
const nona = createNonaClient({ baseUrl: "https://nona.example.com", environmentId: "production", apiKey: process.env.NONA_API_KEY});
try { await nona.getConfigValue("Missing:Key");} catch (error) { if (error instanceof NonaClientError) { console.error(error.status); console.error(error.message); throw error; }
throw error;}When to use the JavaScript client
Section titled “When to use the JavaScript client”Use the JavaScript client when you want:
- a straightforward Nona-specific API
- runtime reads in JavaScript or TypeScript
- optional in-memory caching
- a smaller abstraction layer than OpenFeature
Use HTTP instead when the app only needs one very small direct read path.
Optional cache
Section titled “Optional cache”const nona = createNonaClient({ baseUrl: "https://nona.example.com", environmentId: "production", apiKey: process.env.NONA_API_KEY, cacheTtlMs: 30_000, cacheMemoryLimitMegabytes: 5});Use invalidateTtlCache(key) to remove one cached value or clearTtlCache() to clear all cached values.
The JavaScript client cache is optional and disabled by default. Set a positive cacheTtlMs value to enable it.
Cache is useful when:
- the same keys are read repeatedly
- you want to reduce request volume
- the application can tolerate slightly older values for a short TTL
Keep the TTL short for operational flags and kill switches unless you are sure longer cache windows are acceptable.
Basic troubleshooting
Section titled “Basic troubleshooting”If a JavaScript read fails:
- confirm
environmentIdmatches the environment name in Nona - confirm the environment has an active release, or configure
releaseVersion - confirm the API key belongs to the same project as the parameter
- confirm the parameter scope is readable by that key
- try the same key once with HTTP to isolate client-code issues
Good first app flow
Section titled “Good first app flow”For a mobile or JavaScript app, the usual sequence is:
- fetch one kill switch or banner text on startup
- confirm the value changes when you edit it in admin
- add TTL cache only if repeated reads justify it
- move to OpenFeature when the app becomes flag-heavy
OpenFeature provider
Section titled “OpenFeature provider”Install the optional provider package alongside the Nona client and OpenFeature server SDK:
npm install nona-client nona-openfeature-provider @openfeature/server-sdkimport { OpenFeature } from "@openfeature/server-sdk";import { createNonaOpenFeatureProvider } from "nona-openfeature-provider";
const domain = "nona-production";
await OpenFeature.setProviderAndWait(domain, createNonaOpenFeatureProvider({ baseUrl: "https://nona.example.com", apiKey: process.env.NONA_API_KEY, environmentId: "production"}));
const client = OpenFeature.getClient(domain);const enabled = await client.getBooleanValue("Features:Checkout", false);If your team thinks in terms of feature flags more than direct config reads, see OpenFeature.