Roles

Developers

Merge your code often.

One call, the same code in every environment. Where toggles come from is decided by files each environment provides — not by your code. Locally you work against a toggles file in your repository; in test and production the same code asks FTF.

main — merged often
  • Merge to the main branch often — an unfinished feature simply stays off.
  • One line in your code: isEnabled, in JavaScript, Python or Gosu.
  • Toggles live with your code and work on your laptop exactly as in production — edited with the same FTF screens, promoted and pulled like git push and pull. Local development
  • Clean up when done — FTF tracks a toggle until it's removed everywhere. A toggle's life

The JavaScript client

For browsers and Node 18 and later.

npm install @pntcc/ftf-client

Create it once, then ask wherever you need to. Pass what you know about the request as the context; the toggle's attributes decide.

Several toggles at once: evaluateBatch([...], context) answers each by name.

Fails loudly: missing configuration stops create(); a name outside your prefix throws. An unknown toggle is simply off. A provider error is thrown, never read as off.

import { FtfClient } from "@pntcc/ftf-client"; const ftf = await FtfClient.create(); if (await ftf.isEnabled("acme.web.new_checkout", { brand: "brandA", claimAmount: "12500" })) { // the new checkout } const flags = await ftf.evaluateBatch( ["acme.web.new_checkout", "acme.web.quote_summary_v2"], context);

Three files, and none of them change your code

FileCommitted?What it holds
config-ftf.jsonYes — the same in every environment Your company's toggle prefix and the application's name.
ftf-env.jsonNo — each environment supplies its own FTF's address and the environment's client key. Present: the client asks FTF.
toggles-ftf.jsonYes, with your code Your toggles, for local development and CI. Used when there's no ftf-env.json — evaluated in-process, with the same answers FTF gives.

Same answers locally and in FTF

The local evaluator and FTF's own are checked against one shared set of cases, so a toggle behaves the same on your laptop as in production.

Edit toggles like code

The dashboard opens the toggles file in your repository folder and edits it with the same screens used for FTF's environments — then promotes your changes into the first environment, Git-style.

Keys for browsers

A key in a web page is public. Use a key restricted to your application: FTF answers a page on another origin only for such a key, and only for evaluation.

No toggle switches in your app

Testers switch toggles in FTF's dashboard, never through a screen in your application — nothing about toggles ships to your customers.

The evaluation API, from any language

Two endpoints over HTTPS, with the environment's client key as a bearer token. Declare your application in X-FTF-Application; FTF answers only for that application's toggles and release toggles.

POST /v1/evaluate — one toggle. POST /v1/evaluate-batch — several, by name.

curl https://<your FTF address>/v1/evaluate \ -H "Authorization: Bearer $FTF_CLIENT_KEY" \ -H "X-FTF-Application: web" \ -H "Content-Type: application/json" \ -d '{"toggle": "acme.web.new_checkout", "context": {"brand": "brandA"}}' # {"toggle": "acme.web.new_checkout", "enabled": true}

OpenFeature, in any language

FTF implements the OpenFeature Remote Evaluation Protocol (OFREP), so an app in any language with an OpenFeature OFREP provider can use OpenFeature's own SDK and that provider — no FTF client to install. We test with OpenFeature's Python, Node and browser providers. Point it at FTF with your client key; the flag key is the toggle's full name.

In a browser, give the context a targetingKey (the user): the web provider fetches every toggle of your application for that user once, then answers locally. Use a key restricted to the application.

On your laptop, create a local key in FTF's toggle editor: every save uploads your toggles file to FTF, one way, and your OpenFeature apps get their answers from it — no local server. Fully offline, the JavaScript and Python clients' local mode reads the file directly. How it fits together

import { OpenFeature } from "@openfeature/server-sdk"; import { OFREPProvider } from "@openfeature/ofrep-provider"; await OpenFeature.setProviderAndWait(new OFREPProvider({ baseUrl: "https://<your FTF address>", headers: [["X-API-Key", FTF_CLIENT_KEY], ["X-FTF-Application", "web"]], })); const client = OpenFeature.getClient(); if (await client.getBooleanValue("acme.web.new_checkout", false, { brands: customer.brand })) { showNewCheckout(); }

Try it against a real environment

The trial's Getting started page gives you a browser key, the configuration and a snippet that answers live as you switch the sample toggle.