Plugin.Maui.FeatureFlags 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Plugin.Maui.FeatureFlags --version 1.0.1
                    
NuGet\Install-Package Plugin.Maui.FeatureFlags -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Plugin.Maui.FeatureFlags" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Plugin.Maui.FeatureFlags" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Plugin.Maui.FeatureFlags" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Plugin.Maui.FeatureFlags --version 1.0.1
                    
#r "nuget: Plugin.Maui.FeatureFlags, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Plugin.Maui.FeatureFlags@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Plugin.Maui.FeatureFlags&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Plugin.Maui.FeatureFlags&version=1.0.1
                    
Install as a Cake Tool

Plugin.Maui.FeatureFlags

NuGet

A mobile-first feature flag system for .NET MAUI on iOS and Android.

if (FeatureFlags.IsEnabled("new_checkout"))
{
    // ...
}

MAUI-aware targeting, in order:

Remote configuration
      ↓
Device
      ↓
OS / Version
      ↓
Country
      ↓
User
      ↓
Percentage rollout
var enabled = await featureFlags.IsEnabledAsync("new_voip_engine");

Install

Package: https://www.nuget.org/packages/Plugin.Maui.FeatureFlags

dotnet add package Plugin.Maui.FeatureFlags

Target frameworks: net10.0, net10.0-android, net10.0-ios.

Quick start

using Plugin.Maui.FeatureFlags;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .UseMauiFeatureFlags(options =>
            {
                options.Environment = FeatureFlagEnvironment.Production;
                options.RemoteUri = new Uri("https://cdn.example.com/flags.json");
                options.LocalFlags["new_checkout"] = false;
                options.LocalFlags["new_voip_engine"] = true;
            });

        return builder.Build();
    }
}

Resolve IFeatureFlags from dependency injection, or use FeatureFlags.Current.

if (FeatureFlags.IsEnabled("new_checkout"))
{
    // last known snapshot — never blocks on the network
}

var enabled = await FeatureFlags.IsEnabledAsync("new_voip_engine");

What you get

Capability How
Local fallback LocalFlags and LocalDefinitions used when a key is absent remotely.
Remote configuration HTTP JSON snapshot, or a custom IFeatureFlagProvider.
Percentage rollout Sticky 0–99 bucket from userId (else device id). Same user stays in the same bucket.
User targeting Identify(userId), allow lists, and exclude lists.
App-version targeting minAppVersion / maxAppVersion.
Device / OS Device id allow list, iOS / Android, min/max OS version.
Country ISO country from Identify, options, or the device locale.
Kill switches killed: true on a definition, or options.KillSwitches.
Offline cache Last successful snapshot persisted under app data.
Expiration expiresAt turns the flag off after that UTC instant.
Environment Development / Staging / Production (Dev / Stage / Prod aliases).

A flag is on only after every step of the cascade matches and enabled is true.

Remote JSON

{
  "version": 1,
  "environment": "Production",
  "flags": [
    {
      "key": "new_voip_engine",
      "enabled": true,
      "killed": false,
      "expiresAt": "2027-06-01T00:00:00Z",
      "environments": ["Production", "Staging"],
      "platforms": ["iOS", "Android"],
      "minOsVersion": "15.0",
      "countries": ["US", "IN"],
      "userIds": [],
      "excludedUserIds": [],
      "deviceIds": [],
      "minAppVersion": "2.0.0",
      "percentage": 25,
      "description": "New VoIP media engine"
    }
  ]
}

Empty arrays mean “no restriction” for that dimension. percentage is 0–100; omit it to skip rollout.

Host the file on any HTTPS CDN or API. Add headers if you need them:

options.RemoteUri = new Uri("https://cdn.example.com/flags.json");
options.ConfigureRequest = request =>
{
    request.Headers.Authorization =
        new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
};

If-None-Match is sent automatically when the last fetch returned an ETag.

Identify a user

FeatureFlags.Identify("user-42", country: "IN");

var evaluation = FeatureFlags.Evaluate("beta_chat");
evaluation.Enabled;
evaluation.Reason;   // Matched, UserMismatch, NotInRollout, KillSwitch, ...
evaluation.Source;   // Remote, Cache, Local, Override
evaluation.RolloutBucket;

ClearIdentity() falls rollout back to the sticky device id.

Kill switches and QA overrides

options.KillSwitches.Add("legacy_billing");

featureFlags.SetOverride("new_checkout", true); // process-local QA force-on

Overrides win over kill switches so you can still test the on path.

Without the generic host

var flags = FeatureFlags.Create(new FeatureFlagsOptions
{
    Environment = FeatureFlagEnvironment.Staging,
    RemoteUri = new Uri("https://cdn.example.com/flags.json"),
    LocalFlags = { ["new_checkout"] = false }
});

flags.Start();
var enabled = await flags.IsEnabledAsync("new_voip_engine");

Use StaticFeatureFlagProvider when the snapshot is already in memory (tests, demos, embedded JSON).

Platform notes

Android — declare network access if the host app does not already (required for remote refresh):

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

iOS — no extra Info.plist keys. The sticky device id is stored in Preferences (User Defaults).

Android iOS net10.0
Evaluation / cache / rollout Yes Yes Yes (tests)
Device / OS / app context DeviceInfo / AppInfo DeviceInfo / AppInfo Configurable fakes
Country Locale / Identify Locale / Identify Options / Identify
HTTP remote + ETag Yes Yes Yes

Sample

samples/Plugin.Maui.FeatureFlags.Sample shows environment, user, country, kill switch, expiration, and percentage rollout on a live device.

dotnet build src/Plugin.Maui.FeatureFlags/Plugin.Maui.FeatureFlags.csproj
dotnet pack src/Plugin.Maui.FeatureFlags/Plugin.Maui.FeatureFlags.csproj -c Release -o artifacts
dotnet test tests/Plugin.Maui.FeatureFlags.Tests/Plugin.Maui.FeatureFlags.Tests.csproj
dotnet build samples/Plugin.Maui.FeatureFlags.Sample/Plugin.Maui.FeatureFlags.Sample.csproj -f net10.0-android

Pack from source

dotnet pack src/Plugin.Maui.FeatureFlags/Plugin.Maui.FeatureFlags.csproj -c Release -o artifacts

The .nupkg is written to artifacts/Plugin.Maui.FeatureFlags.1.0.0.nupkg.

License

MIT

Support

If this plugin saved you a weekend of native plumbing, consider buying me a coffee. Your support keeps it maintained, documented, and free.

Buy Me A Coffee

This library stays open source. A coffee helps cover time for bug fixes, new features, and docs.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net10.0-android36.0

    • No dependencies.
  • net10.0-ios26.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.8 36 9/3/2026
1.0.7 59 9/2/2026
1.0.6 83 8/30/2026
1.0.5 88 8/30/2026
1.0.4 93 8/29/2026
1.0.3 96 8/28/2026
1.0.2 97 8/28/2026
1.0.1 85 8/28/2026
1.0.0 87 8/28/2026

Initial release. MAUI-aware feature flags with remote configuration, local fallback, percentage rollout, user / device / OS / country / app-version targeting, kill switches, offline cache, expiration, and Dev/Staging/Production environments.