npm package: @j1645/ff-sdk
Description: Feature flag SDK for experiments - lightweight client with React support
Author: dknoller
Latest version: 0.1.0

# ff-sdk

[![npm version](https://badge.fury.io/js/ff-sdk.svg)](https://www.npmjs.com/package/ff-sdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A lightweight feature flag SDK with built-in React support. Evaluate feature flags locally with caching, targeting, and graceful degradation.

## Features

- 🚀 **Lightweight** - Zero runtime dependencies
- ⚡ **Fast** - In-memory caching with TTL
- 🎯 **Targeting** - User and org-based rollouts
- 🔒 **Safe** - Fail-closed on errors
- ⚛️ **React** - Optional React hook included
- 📘 **TypeScript** - Full type definitions

## Installation

```bash
npm install ff-sdk
```

For React projects (optional peer dependency):
```bash
npm install ff-sdk react
```

## Quick Start

### Basic Usage

```typescript
import { FeatureFlagClient } from 'ff-sdk';

const client = new FeatureFlagClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.example.com'
});

// Check if a feature is enabled
const isEnabled = await client.isEnabled('new-feature', { 
  userId: 'user-123',
  orgId: 'org-456' 
});

if (isEnabled) {
  // Show new feature
}
```

### React Hook

```tsx
import { FeatureFlagClient, useFeatureFlag } from 'ff-sdk';

const client = new FeatureFlagClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.example.com'
});

function MyComponent() {
  const { enabled, loading, error } = useFeatureFlag(
    client, 
    'new-feature',
    { userId: currentUser.id }
  );

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return enabled ? <NewFeature /> : <OldFeature />;
}
```

## Configuration

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | **required** | Your API key |
| `baseUrl` | `string` | `https://api.example.com` | API base URL |
| `timeout` | `number` | `5000` | Request timeout (ms) |
| `debug` | `boolean` | `false` | Enable debug logging |

## API Reference

### `FeatureFlagClient`

#### `isEnabled(flagId, context?)`

Check if a feature flag is enabled.

```typescript
const isEnabled = await client.isEnabled('flag-id', {
  userId: 'user-123',
  orgId: 'org-456',
  attributes: { plan: 'pro' }
});
```

#### `getAllFlags()`

Fetch all available flags (for admin use).

```typescript
const flags = await client.getAllFlags();
```

#### `clearCache()`

Clear the in-memory cache.

```typescript
client.clearCache();
```

### `useFeatureFlag(client, flagId, context?)`

React hook for feature flag evaluation.

```typescript
const { enabled, loading, error, refresh } = useFeatureFlag(
  client,
  'flag-id',
  { userId: 'user-123' }
);
```

## Error Handling

The SDK is designed to fail closed - if there's an error (network, API down, etc.), `isEnabled()` returns `false`.

```typescript
const isEnabled = await client.isEnabled('critical-feature');
// If API is down, isEnabled === false (safe default)
```

## Caching

Results are cached in-memory for 60 seconds by default. The cache key includes:
- Flag ID
- User ID
- Org ID

## License

MIT