This repository houses the Cloudflare Workers Starter Kit which provides a quickstart for users who would like to use Optimizely Feature Experimentation and Optimizely Full Stack (legacy) with Cloudflare Workers.
Optimizely Feature Experimentation is an A/B testing and feature management tool for product development teams that enables you to experiment at every step. Using Optimizely Feature Experimentation allows for every feature on your roadmap to be an opportunity to discover hidden insights. Learn more at Optimizely.com, or see the developer documentation.
Optimizely Rollouts is free feature flags for development teams. You can easily roll out and roll back features in any application without code deploys, mitigating risk for every feature on your roadmap.
Get up and running in under 2 minutes:
# 1. Clone the template (replace vX.Y.Z with the latest release tag from https://github.com/optimizely/cloudflare-worker-template/releases)
git clone --branch vX.Y.Z --depth 1 https://github.com/optimizely/cloudflare-worker-template.git my-project
cd my-project
# 2. Install dependencies
npm install
# 3. Set your Optimizely SDK key (get it from Settings > Environments in your Optimizely dashboard)
cp .env.example .env
# Edit .env and add your SDK key
# 4. Start local development server
npm run dev
# 5. Visit http://localhost:8787 to see your worker in action!For detailed setup instructions, see the Get Started section below.
- Modern ES Modules: Uses ES module syntax for better tree-shaking and modern JavaScript features
- Optimizely SDK v6: Latest version of the Optimizely JavaScript SDK
- Cloudflare Cache Integration: Automatic datafile caching using Cloudflare's edge cache
- Development Tools: Integrated Biome for linting/formatting, Miniflare for local development
- Cookie-based User Persistence: Automatic user ID generation and persistence
Refer to the Optimizely Cloudflare Workers Starter Kit documentation for detailed instructions about using this starter kit.
System Requirements:
- Node.js 18.x or higher (20.x or 22.x recommended)
- npm 9.x or higher
Accounts & Tools:
-
Optimizely Account: If you don't have an account, register for a free account.
-
Cloudflare Account with Workers: Visit the Cloudflare Workers product page to sign up.
-
Wrangler CLI: Install via npm:
npm install -g wrangler
Or see the Cloudflare Wrangler CLI documentation for other installation methods.
-
Clone a specific tagged version of this template to create your project.
# Clone the template (replace vX.Y.Z with the latest release tag from https://github.com/optimizely/cloudflare-worker-template/releases) git clone --branch vX.Y.Z --depth 1 https://github.com/optimizely/cloudflare-worker-template.git my-project cd my-project
Note: Replace
my-projectwith your desired project name andvX.Y.Zwith your desired release version. -
Install node packages.
npm install
-
Configure your Optimizely SDK Key:
First, get your SDK key from the Optimizely dashboard:
- Log into your Optimizely account
- Navigate to Settings → Environments
- Copy your SDK key from the desired environment (it looks like:
AbCdEf12345GhIjKlMnOp)
Then set your SDK key using one of these methods:
Option A: Using Wrangler Secrets (Recommended for production)
wrangler secret put OPTIMIZELY_SDK_KEYOption B: Using wrangler.jsonc for development
Edit
wrangler.jsoncand replaceYOUR_SDK_KEYwith your actual SDK key:Option C: Using .env file for local development
cp .env.example .env # Edit .env and add your SDK keyOPTIMIZELY_SDK_KEY=your_sdk_key OPTIMIZELY_DATAFILE_CACHE_TTL_SECONDS=300 # Optional: cache TTL in seconds (default: 300)
-
Configure Cloudflare Account ID (required for deployment):
Add your
account_idtowrangler.jsonc:# Find your account ID wrangler whoamiThen edit
wrangler.jsonc:{ "name": "optimizely-cloudflare-worker", "account_id": "your_account_id_here", // Add this line // ... rest of config }Note: You can skip this step for local development. The CLI will prompt you when needed.
├── src/
│ ├── index.js # Main worker entry point
│ ├── optimizely_helper.js # Optimizely SDK integration utilities
│ └── request_handler.js # Cloudflare-specific HTTP request handler
├── test/
│ ├── index.test.js # Tests for main worker
│ ├── optimizely_helper.test.js # Tests for Optimizely helper functions
│ ├── request_handler.test.js # Tests for request handler
│ ├── setup.js # Test environment setup
│ └── test-utils.js # Shared test utilities and mocks
├── .env.example # Environment variable template
├── biome.jsonc # Biome configuration for linting/formatting
├── package.json # Node.js dependencies and scripts
├── vitest.config.js # Vitest testing framework configuration
└── wrangler.jsonc # Cloudflare Workers configuration
The Optimizely starter kit for Cloudflare Workers embeds and extends our Javascript SDK. For a guide to getting started with our platform more generally, you can reference our Javascript Quickstart developer documentation.
Note: This starter kit makes use of the "Universal" version of our Javascript SDK which explicitly excludes the datafile manager and event processor features for better performance. The datafile is fetched and cached using Cloudflare's cache API, and event dispatching is handled through the provided platform-specific
getOptimizelyClient()helper.
This template includes modern development tools for a better developer experience:
- Biome: Fast formatter and linter for JavaScript
- Miniflare: Local development server that simulates Cloudflare Workers
- Vitest: Fast unit testing framework
Available development commands:
npm run dev # Start local development server
npm run format # Format code with Biome
npm run lint # Lint code with Biome
npm run test # Run tests with Vitest
npm run build # Build and validate (dry-run deploy)Sample code is included in src/index.js that shows examples of initializing and using the Optimizely JavaScript (Node) SDK interface for performing common functions such as creating user context, adding a notification listener, and making decisions based on the created user context.
Additional platform-specific code is included in src/optimizely_helper.js which provides workarounds for otherwise common features of the Optimizely SDK, including:
- Datafile Caching: Automatic fetching and caching of the Optimizely datafile using Cloudflare's cache API
- Client Management: Efficient client initialization and datafile updates
- Event Dispatching: Optional event dispatching to Optimizely's logging backend
-
Configure your feature flags: Update the
YOUR_FLAG_HEREplaceholder insrc/index.jswith your actual flag keys from the Optimizely dashboard. -
Test and debug the worker locally.
npm run dev
-
Deploy the worker on Cloudflare.
wrangler deploy -
Optionally, tail the logs for debugging when accessing worker deployed on Cloudflare.
wrangler tail -f pretty
This template uses Cloudflare's cache API to provide performant caching for the Optimizely Datafile. The datafile is automatically fetched from Optimizely's CDN and cached for 5 minutes by default (configurable via the OPTIMIZELY_DATAFILE_CACHE_TTL_SECONDS environment variable), with Cloudflare edge caching providing additional performance benefits.
Cache Configuration:
- Default TTL: 5 minutes (300 seconds)
- Configurable via:
OPTIMIZELY_DATAFILE_CACHE_TTL_SECONDSenvironment variable - Example values:
300(5 minutes),600(10 minutes),1800(30 minutes) - Behavior: If the datafile fetch fails, the cached datafile will continue to be used (stale-while-revalidate pattern)
Out of the box, Optimizely's Feature Experimentation SDKs require a user-provided identifier to be passed in at runtime to drive experiment and feature flag decisions. This example generates a unique ID using crypto.randomUUID(), stores it in a cookie, and reuses it to make the decisions sticky. Alternatively, you can use an existing unique identifier available within your application and pass it in as the value for the OPTIMIZELY_USER_ID cookie.
For more information on how Optimizely Feature Experimentation SDKs assign users to feature flags and experiments, see the documentation on how bucketing works.
For more information about Cloudflare Workers, you may visit the following resources:
- Cloudflare Workers
- Cloudflare Workers documentation
- Cloudflare Workers tutorials
- Cloudflare Workers with Optimizely documentation
Problem: "OPTIMIZELY_SDK_KEY environment variable is required" error
Solution: Ensure you've set your SDK key using one of the methods in step 3:
- Check that your
.envfile exists and containsOPTIMIZELY_SDK_KEY=your_key - Or verify
wrangler.jsonchas the SDK key in thevarssection - For production deployments, run:
wrangler secret put OPTIMIZELY_SDK_KEY
Problem: "Failed to fetch datafile" error
Solution: This usually means:
- Your SDK key is incorrect or doesn't match an active Optimizely project
- Network connectivity issues (check your internet connection)
- The Optimizely CDN is temporarily unavailable (the worker will use cached data if available)
Problem: "Account ID not found" when deploying
Solution:
# Find your account ID
wrangler whoami
# Add it to wrangler.jsonc under "account_id"Problem: Local dev server won't start
Solution:
- Ensure you're using Node.js 18+ (
node --version) - Check if port 8787 is already in use
- Try
npm run dev -- --port 8788to use a different port
Problem: Feature flags not working as expected
Solution:
- Verify your flag key matches exactly (case-sensitive)
- Check that the flag is enabled in your Optimizely project
- Ensure the environment SDK key matches the environment where the flag is configured
- Check browser console/worker logs for decision details
Need more help?
- Check the Optimizely Developer Docs
- Visit the Optimizely Community
- Open an issue on GitHub
Please see CONTRIBUTING.
-
Flutter - https://github.com/optimizely/optimizely-flutter-sdk
-
JavaScript - https://github.com/optimizely/javascript-sdk
-
Akamai EdgeWorkers - https://github.com/optimizely/akamai-edgeworker-starter-kit
-
AWS Lambda@Edge - https://github.com/optimizely/aws-lambda-at-edge-starter-kit
-
Fastly Compute@Edge - https://github.com/optimizely/fastly-compute-starter-kit
-
Vercel Functions - https://github.com/optimizely/vercel-examples/tree/main/edge-functions/feature-flag-optimizely
{ "vars": { "OPTIMIZELY_SDK_KEY": "YOUR_SDK_KEY", "OPTIMIZELY_DATAFILE_CACHE_TTL_SECONDS": "300" // Optional: cache TTL in seconds (default: 300) } }