Background Paths
Background Paths

Getting Started

ftureX lets you turn features on or off across environments without redeploying. Install the client, grab an API key from the dashboard, and start checking flags in your code.

1. Install

bash
npm install @codetiles/fturex

2. Get your API key

  1. Log in to the ftureX dashboard
  2. Go to your project → Environments
  3. Click on an environment → Apps
  4. Click Add App and give it a name
  5. Copy the generated API key

3. Start checking features

tsx
// 1. Install
// npm install @codetiles/fturex
// 2. Wrap your app (e.g. main.tsx or App.tsx)
import { FeatureToggleProvider } from '@codetiles/fturex/react';
export function App() {
return (
<FeatureToggleProvider config={{ baseUrl: 'https://your-fturex-instance.com', appKey: 'your-api-key' }}>
<YourApp />
</FeatureToggleProvider>
);
}
// 3. Check features anywhere in your app
import { useFeatureToggle } from '@codetiles/fturex/react';
function MyComponent() {
const { isEnabled, loading } = useFeatureToggle('my-feature');
if (loading) return null;
return isEnabled ? <NewUI /> : <OldUI />;
}
TipFeature flags are auto-created on first evaluation — no need to set them up in the dashboard before shipping code. They appear automatically (disabled by default) the first time your app checks them.

Installation

bash
npm install @codetiles/fturex

.NET SDK

Basic Setup (Standalone)

csharp
using Fturex;
var client = new FtureXClient(new FtureXConfiguration
{
BaseUrl = "https://your-fturex-instance.com",
AppKey = "your-api-key",
UseCache = true,
SendStatistics = true
});
// Check if a feature is enabled
if (await client.IsEnabled("new-checkout"))
{
// New checkout flow
}
// Cleanup when done
client.Dispose();

ASP.NET Core (Dependency Injection)

Register ftureX in your service container, then inject IFtureX anywhere you need it.

csharp
using Fturex.Bootstrap;
using Fturex.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFtureX(new FtureXConfiguration
{
BaseUrl = builder.Configuration["FtureX:BaseUrl"],
AppKey = builder.Configuration["FtureX:AppKey"]
});
var app = builder.Build();

Then inject IFtureX anywhere:

csharp
public class CheckoutController : ControllerBase
{
private readonly IFtureX _features;
public CheckoutController(IFtureX features)
{
_features = features;
}
public async Task<IActionResult> Checkout()
{
if (await _features.IsEnabled("new-checkout"))
return NewCheckoutFlow();
else
return OldCheckoutFlow();
}
}

Context-Based Evaluation

Target features to specific users, roles, or tenants:

csharp
// Pass context as a dictionary
var context = new Dictionary<string, string>
{
{ "UserId", "user-123" },
{ "UserRole", "admin" },
{ "TenantId", "tenant-abc" }
};
await features.IsEnabled("beta-feature", context);

Configuration Options

PropertyTypeDefaultDescription
BaseUrlstringrequiredYour ftureX API URL
AppKeystringrequiredAPI key from your environment
UseCachebooltrueEnable in-memory caching
SendStatisticsbooltrueSend usage stats to ftureX
CacheRefreshIntervalSecondsint5How often to refresh cached features
StatisticsReportIntervalSecondsint30How often to send usage stats
EnableFilePersistenceboolfalsePersist cache to disk (survives restarts)
CacheFilePathstring"feature-cache.json"File path for disk persistence
MaxTrackedFeaturesint10000Max features tracked for background refresh
CleanupIntervalMinutesint10Cleanup interval for tracking list
ContextCacheDurationMinutesint5TTL for context-specific evaluations

Fallback Behavior

TipIf the API is unreachable, IsEnabled returns the fallbackTo value (default: false). Use this to keep critical features running even during outages.
csharp
// Returns true if API is down (safe fallback for critical features)
await features.IsEnabled("payments", fallbackTo: true);
// Returns false if API is down (default, new features stay off)
await features.IsEnabled("experimental-ui");

Statistics

csharp
var stats = client.GetFeatureHitCounts(); // Total evaluations per feature
var enabled = client.GetFeatureEnabledCounts(); // Times returned true
var disabled = client.GetFeatureDisabledCounts(); // Times returned false
var lastUsed = client.GetFeatureLastAccessed(); // Last evaluation timestamp
client.ResetStatistics(); // Clear local stats

JavaScript / TypeScript SDK

Basic Setup

typescript
import { FtureXClient } from '@codetiles/fturex';
const client = new FtureXClient({
baseUrl: 'https://your-fturex-instance.com',
appKey: 'your-api-key'
});
await client.initialize();
if (await client.isEnabled('new-checkout')) {
// New checkout flow
}
// Cleanup
client.dispose();

Configuration

typescript
import { FtureXClient } from '@codetiles/fturex';
const client = new FtureXClient(
// Required config
{
baseUrl: 'https://your-fturex-instance.com',
appKey: 'your-api-key',
sendStatistics: true // default: true
},
// Optional cache settings
{
refreshIntervalSeconds: 5,
enableLocalStoragePersistence: true,
localStorageKey: 'feature-toggle-cache',
maxTrackedFeatures: 10000,
cleanupIntervalMinutes: 10,
contextCacheDurationMinutes: 5
}
);
OptionTypeDefaultDescription
baseUrlstringrequiredYour ftureX API URL
appKeystringrequiredAPI key from your environment
sendStatisticsbooleantrueSend usage stats to ftureX
refreshIntervalSecondsnumber5How often to refresh cached features
enableLocalStoragePersistencebooleantruePersist cache to localStorage
localStorageKeystring"feature-toggle-cache"localStorage key for persistence
maxTrackedFeaturesnumber10000Max features tracked for background refresh
cleanupIntervalMinutesnumber10Cleanup interval for tracking list
contextCacheDurationMinutesnumber5TTL for context-specific evaluations

Context-Based Evaluation

typescript
// isEnabledWithContext lets you pass user/role/tenant for targeted rollouts
const isEnabled = await client.isEnabledWithContext('beta-feature', {
userId: 'user-123',
role: 'admin',
tenantId: 'tenant-abc'
});

Fallback Behavior

TipIf the API is unreachable, isEnabled returns the fallback value (default: false). Pass true as the second argument to keep critical features running during outages.
typescript
// Returns true if API is down (safe fallback for critical features)
await client.isEnabled('payments', true);
// Returns false if API is down (default)
await client.isEnabled('experimental-ui');
// With context and fallback
await client.isEnabledWithContext('beta-feature', { role: 'admin' }, true);

Statistics & Cache

typescript
const stats = client.getStatistics();
// Returns: FeatureStatistics[]
// Each: { featureName, hitCount, enabledCount, disabledCount, lastAccessed }
const cachedNames = client.getCachedFeatureNames();
client.clearCache();

Context Properties

Context properties are a set of key/value pairs that you define in your own code and pass along when evaluating a feature flag. ftureX does not enforce any fixed set of property names — they can be anything that exists in your application.

Common uses include targeting a flag to specific users, subscription plans, geographic regions, or any other dimension your app already tracks. The ftureX backend receives these properties and can use them in targeting rules configured in the dashboard.

NoteThe property names in the examples below (userId, plan, region) are illustrations only. Use whatever property names make sense for your application. Any string key/value pair is valid.

How to Pass Context

typescript
// These property names are YOUR choice — use whatever exists in your application.
// The examples below (userId, plan, region) are just illustrations.
const isEnabled = await client.isEnabledWithContext('new-checkout', {
userId: currentUser.id,
plan: currentUser.subscriptionPlan, // e.g. "free", "pro", "enterprise"
region: currentUser.region // e.g. "eu", "us-east"
});

What Properties Can You Pass?

Anything you already have access to in your code. Some examples to spark ideas:

Example KeyExample ValueWhat it enables
userId"user-abc"Target a specific user (e.g. beta testers)
plan"pro"Enable a feature only for paid plans
region"eu"Roll out to one geographic region first
role"admin"Show internal tools to admins only
companyId"acme-corp"Target a specific customer/tenant
TipThese are just examples. You are not limited to these keys. Pass whatever properties your application tracks and configure your targeting rules in the ftureX dashboard to match.

React Integration

Provider Setup

Wrap your app with the provider:

tsx
import { FeatureToggleProvider } from '@codetiles/fturex/react';
function App() {
return (
<FeatureToggleProvider
config={{
baseUrl: 'https://your-fturex-instance.com',
appKey: 'your-api-key'
}}
cacheOptions={{
enableLocalStoragePersistence: true
}}
>
<YourApp />
</FeatureToggleProvider>
);
}

useFeatureToggle Hook

tsx
import { useFeatureToggle } from '@codetiles/fturex/react';
function MyComponent() {
const { isEnabled, loading, error } = useFeatureToggle('new-checkout');
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return isEnabled ? <NewCheckout /> : <OldCheckout />;
}

With Context & Fallback

tsx
// With context targeting
const { isEnabled, loading, error } = useFeatureToggle('beta-feature', {
userId: 'user-123',
role: 'admin'
});
// With context and fallback (3rd argument)
const { isEnabled: payEnabled } = useFeatureToggle('payments', undefined, true);

Multiple Features at Once

tsx
import { useFeatureToggles } from '@codetiles/fturex/react';
function Dashboard() {
const { features, loading, error } = useFeatureToggles([
'new-dashboard',
'dark-mode',
'beta-analytics'
]);
// features = { 'new-dashboard': true, 'dark-mode': false, ... }
}

FeatureToggle Component

A declarative component that renders children when the feature is enabled, with optional fallback and loading slots:

tsx
import { FeatureToggle } from '@codetiles/fturex/react';
function Page() {
return (
<FeatureToggle
featureName="new-checkout"
context={{ userId: 'user-123' }}
fallback={<OldCheckout />}
loading={<p>Loading...</p>}
>
<NewCheckout />
</FeatureToggle>
);
}

Vue 3 Integration

Setup (Provide/Inject)

typescript
// main.ts
import { createApp } from 'vue';
import { FtureXClient } from '@codetiles/fturex';
import { FeatureToggleClientKey } from '@codetiles/fturex/vue';
const client = new FtureXClient({
baseUrl: 'https://your-fturex-instance.com',
appKey: 'your-api-key'
});
await client.initialize();
const app = createApp(App);
app.provide(FeatureToggleClientKey, client);
app.mount('#app');

useFeatureToggle Composable

vue
<script setup>
import { useFeatureToggle } from '@codetiles/fturex/vue';
const { isEnabled, loading, error, refresh } = useFeatureToggle('new-checkout');
</script>
<template>
<div v-if="loading">Loading...</div>
<NewCheckout v-else-if="isEnabled" />
<OldCheckout v-else />
</template>

With Context

typescript
const { isEnabled, loading, error, refresh } = useFeatureToggle('beta-feature', {
userId: 'user-123',
role: 'admin'
});
// Manually refresh
await refresh();

Multiple Features

typescript
const { features, loading, error, refresh } = useFeatureToggles([
'feature-a',
'feature-b'
]);

FeatureToggle Component

A declarative component with named slots for each state:

vue
<script setup>
import { FeatureToggle } from '@codetiles/fturex/vue';
</script>
<template>
<FeatureToggle featureName="new-checkout" :context="{ userId: 'user-123' }">
<NewCheckout />
<template #fallback>
<OldCheckout />
</template>
<template #loading>
<p>Loading...</p>
</template>
</FeatureToggle>
</template>

REST API Reference

Authentication

Client applications authenticate using an API key passed in the X-API-Key header.

MethodHeaderUsed By
API KeyX-API-Key: <your-app-key>SDKs, client applications

Get an API Key

  1. Log in to the ftureX dashboard
  2. Go to your project → Environments
  3. Click on an environment → Apps
  4. Click "Add App" and give it a name
  5. Copy the generated API key

Feature Evaluation (Client Endpoint)

NoteThis is the endpoint the SDKs call internally. You can also call it directly for custom integrations.
http
POST /feature/enabled?featureName=new-checkout
X-API-Key: your-api-key
Content-Type: application/json
{
"properties": [
{ "key": "userId", "value": "user-123" },
{ "key": "role", "value": "admin" }
]
}

Response: true or false

Without context (simple toggle check):

http
POST /feature/enabled?featureName=new-checkout
X-API-Key: your-api-key
Content-Type: application/json
{}

Statistics Reporting

The SDKs automatically report usage statistics. You can also send them manually:

http
POST /api/Statistics/Report
X-API-Key: your-api-key
{
"appKey": "your-api-key",
"features": [
{
"featureName": "new-checkout",
"hitCount": 150,
"enabledCount": 100,
"disabledCount": 50,
"lastAccessed": "2026-03-23T14:30:00Z"
}
],
"reportTimestamp": "2026-03-23T14:30:00Z"
}

Caching Behavior

Type.NETJS / Browser
In-memory cacheAlways on (if UseCache = true)Always on
Background refreshEvery 5 sec (configurable)Every 5 sec (configurable)
Disk / localStorage persistenceEnableFilePersistence = trueenableLocalStoragePersistence = true
Context-specific cache TTL5 min (configurable)5 min (configurable)
Fallback when API is downReturns cached value, then fallbackToReturns cached value, then fallbackTo

Auto Feature Discovery

When a client SDK checks a feature that doesn't exist yet in ftureX, the system can auto-create it (if enabled on the project). This means:

  1. Developer adds isEnabled("new-feature") in code
  2. First evaluation hits the API
  3. ftureX auto-creates the feature (disabled by default)
  4. Feature appears in the dashboard, ready to configure
TipNo need to create features in the dashboard first. Just start using them in code and they'll appear automatically.

OpenTelemetry

ftureX ships a first-class OpenTelemetry integration via a hook that attaches to every feature evaluation. It follows the OpenTelemetry semantic conventions for feature flags and emits both span events and metrics so you can observe flag behaviour directly in your existing observability stack.

Installation

bash
dotnet add package Fturex.OpenTelemetry

Setup

csharp
using Fturex.Bootstrap;
using Fturex.OpenTelemetry;
builder.Services.AddFtureX(new FtureXConfiguration
{
BaseUrl = builder.Configuration["FtureX:BaseUrl"],
AppKey = builder.Configuration["FtureX:AppKey"]
});
// Register the OpenTelemetry hook
builder.Services.AddFtureXOpenTelemetry(options =>
{
options.AddSpanEvents = true; // Add events to the active span (default: true)
options.AddMetrics = true; // Emit evaluation counters (default: true)
options.RecordFlagValue = false; // Include the flag value in span events (default: false)
options.SetId = "production"; // Optional: identify the flag set / environment
});
// Wire up sources and meters with your OTel providers
builder.Services.AddOpenTelemetry()
.WithTracing(t => t.AddSource(FtureXOtelExtensions.ActivitySourceName))
.WithMetrics(m => m.AddMeter(FtureXOtelExtensions.MeterName));

What gets emitted

On every call to isEnabled the hook adds a feature_flag.evaluation event to the currently active span and increments one of two counters:

SignalNameDescription
Span eventfeature_flag.evaluationAdded to the active trace span on each evaluation
Metric (counter)feature_flag.evaluation_success_totalIncremented on every successful evaluation
Metric (counter)feature_flag.evaluation_error_totalIncremented when an evaluation throws an error

Span event attributes

AttributeAlways presentDescription
feature_flag.keyYesThe feature flag name
feature_flag.provider.nameYesAlways "FtureX"
feature_flag.result.reasonYesstatic · targeting_match · default · error · stale · disabled
feature_flag.result.valueNoThe evaluated value ("true"/"false") — only when recordFlagValue = true
feature_flag.set.idNoFlag set identifier — only when setId is configured
feature_flag.context.idNouserId or tenantId from the evaluation context, when present
error.typeNoException type name — only on error evaluations

Configuration options

OptionTypeDefaultDescription
addSpanEvents / AddSpanEventsbooltrueAdd a span event to the active trace span on each evaluation
addMetrics / AddMetricsbooltrueEmit evaluation success/error counters as OTel metrics
recordFlagValue / RecordFlagValueboolfalseInclude the evaluated flag value in span event attributes
setId / SetIdstringnullOptional identifier for the flag set or environment
TipKeep recordFlagValue set to false (the default) unless you need it — flag values can be considered sensitive in some compliance contexts, and omitting them keeps your traces leaner.

Vibe Coder Prompt

Building with an AI coding assistant? Copy this prompt, fill in the two placeholders, and paste it into your chat. The assistant reads the docs itself and picks the right SDK for whatever framework you're already using — React, Vue, .NET, or plain JS.

NoteReplace [DESCRIBE YOUR FEATURE HERE] and [your-feature-name] before sending. That's it.
prompt
Add a feature flag to control [DESCRIBE YOUR FEATURE HERE].
Flag name: "[your-feature-name]"
Read the full SDK docs here: https://fturex.com/docs
Use whatever framework this project already uses (React, Vue, .NET, vanilla JS, etc.).
Rules:
- Flag OFF → keep the existing behaviour (do not delete old code)
- Flag ON → show the new behaviour
- Handle loading state to avoid layout shift
- Feature names are kebab-case: e.g. "dark-mode", "new-checkout", "beta-dashboard"
- The flag is auto-created in the dashboard on first evaluation — no manual setup needed

Lifecycle

Lifecycle tracks the state of every feature flag from the moment it is created to the moment it is removed. The goal is to prevent flag debt — old toggles that get forgotten in the codebase long after they served their purpose.

Feature States

Every flag moves through a simple set of states inside the ftureX dashboard:

StateWhat it means
ActiveThe flag is live and being evaluated by your app.
StaleThe flag has not been evaluated for a while. ftureX flags it for review.
ArchivedThe flag has been disabled and marked for cleanup. No longer evaluated.
TipA flag goes Stale automatically when it has not been evaluated within the staleness window you configure (default: 30 days). This is your signal to either re-enable it or clean up the code that uses it.

How to Configure

Lifecycle settings live at the project level in the ftureX dashboard:

  1. Log in to the ftureX dashboard and open your project
  2. Go to Project Settings → Lifecycle
  3. Set your Staleness window — how many days of inactivity before a flag is marked stale
  4. Choose whether you want email notifications when flags go stale
  5. Save your settings
SettingDefaultDescription
Staleness window30 daysDays without an evaluation before a flag is marked stale
Stale notificationsOffSend an email when a flag transitions to Stale
Auto-archive stale flagsOffAutomatically archive flags that have been stale for a set number of additional days
NoteFlags marked as permanent (e.g. kill switches or long-running toggles) are exempt from staleness tracking. You can mark any flag as permanent from its detail page in the dashboard.

GitHub Integration

Connecting ftureX to your GitHub repository lets you link feature flags to branches and pull requests. When a PR is merged, ftureX can automatically mark the associated flag for review — so cleanup happens as part of your normal workflow, not months later.

Step 1 — Connect your repository

  1. In the ftureX dashboard, go to Project Settings → GitHub
  2. Click Connect GitHub and authorise ftureX to access your repositories
  3. Select the repository you want to link
  4. Copy the Webhook Secret that is generated — you will need it in the next step

Step 2 — Add the webhook in GitHub

  1. Go to your GitHub repository → Settings → Webhooks → Add webhook
  2. Fill in the fields as shown below and click Add webhook
github
# In your GitHub repo:
# Settings → Webhooks → Add webhook
Payload URL: https://your-fturex-instance.com/api/github/webhook
Content type: application/json
Secret: (copy from ftureX dashboard → Project Settings → GitHub)
Events: Pull requests, Pushes

Step 3 — Link flags to branches or PRs

Once connected, open any feature flag in the dashboard and you will see a GitHub tab. Type the branch or PR number you want to associate with the flag. From that point on:

  • The flag detail page shows the current status of the linked PR
  • When the PR is merged, ftureX marks the flag as ready for cleanup
  • You receive a notification (if enabled) to remind you to remove the flag from your code
TipYou do not have to link every flag to a PR. Lifecycle tracking works without GitHub too — the GitHub integration just makes the cleanup reminder automatic.

Self-hosted setup

If you are running ftureX on your own servers, add the following environment variables before setting up the webhook:

.env
# .env or appsettings.json on your ftureX server
GITHUB_WEBHOOK_SECRET=your-secret-here
GITHUB_APP_CLIENT_ID=your-app-client-id
GITHUB_APP_CLIENT_SECRET=your-app-client-secret

MCP Server

What is an MCP Server?

MCP stands for Model Context Protocol -- it's a standard that lets AI assistants like Claude talk directly to external tools and services. The ftureX MCP server means you can manage your feature flags just by chatting with an AI agent. No dashboard, no code changes -- just tell it what you want and it happens.

Hosted Endpoint

The MCP server is live at https://api.fturex.com/mcp. You can connect right now without installing or self-hosting anything.

Connecting in Claude Desktop

  1. Open Claude Desktop
  2. Go to Settings → Connectors → Add custom connector
  3. Paste the URL: https://api.fturex.com/mcp
  4. Save and restart Claude Desktop — ftureX will appear as a connected tool

Connecting in Cursor

Add the following to your Cursor MCP config:

json
{
"mcpServers": {
"fturex": {
"type": "http",
"url": "https://api.fturex.com/mcp"
}
}
}
NoteIn Cursor, go to Settings → MCP → Add server, or paste the snippet above into .cursor/mcp.json in your project root, then reload Cursor.

Authentication

After connecting, the MCP server will ask for your ftureX credentials -- either your email and password, or an API token. You only need to authenticate once per session.

What You Can Do

Once connected, you can talk to your AI agent in plain English. For example:

  • “List all features in my production environment”
  • “Enable the new-checkout feature”
  • “Show me which features are currently disabled”
  • “Create a new feature flag called dark-mode”
  • “Toggle the beta-ui feature off”
TipAn npm package for self-hosting the MCP server is coming soon. For now, use the hosted endpoint at https://api.fturex.com/mcp.