This repository houses the Fastly Compute@Edge Starter Kit which provides a quickstart for users who would like to use Optimizely Feature Experimentation and Optimizely Full Stack (legacy) with Fastly Compute@Edge.
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 a few minutes:
# 1. Initialize a project from this template using the Fastly CLI
# (replace vX.Y.Z with the latest release tag from
# https://github.com/optimizely/fastly-compute-starter-kit/releases)
fastly compute init --from https://github.com/optimizely/fastly-compute-starter-kit
cd my-project
# 2. Install dependencies
npm install
# 3. Set your Optimizely SDK key (get it from Settings > Environments in
# your Optimizely dashboard). For local development, edit the sdk_key
# value under [local_server.config_stores.optimizely.contents] in fastly.toml.
# 4. Start the local development server
npm run serve
# 5. Visit the printed local URL (default http://127.0.0.1:7676) to see it in action.For detailed setup instructions, see the Get Started section below.
- Optimizely SDK v6: Latest version of the Optimizely JavaScript SDK (Universal build).
- Modern js-compute toolchain: Builds directly to WebAssembly with
@fastly/js-compute3.x, no bundler required. - Fastly edge datafile caching: Datafile fetched through a Fastly backend and cached with
CacheOverride(stale-while-revalidate). - Externalized configuration: SDK key and cache TTL read from a Fastly Config Store, not hardcoded.
- Graceful degradation: The service still returns a response even if Optimizely initialization fails.
- Cookie-based user persistence: Automatic user ID generation with
crypto.randomUUID()and cookie persistence for sticky bucketing. - Development tools: Biome for linting/formatting and Vitest for unit tests.
Refer to the Optimizely Fastly Compute@Edge Starter Kit documentation for detailed instructions about using this starter kit.
System Requirements:
- Node.js 22.x or higher (required by the dev toolchain, e.g.
cookiev2 and Vitest 4) - npm 9.x or higher
Accounts & Tools:
-
Optimizely Account: If you don't have an account, register for a free account.
-
Fastly Compute account: Sign up for Fastly and enable Compute.
-
Fastly CLI: Install it by following the Fastly CLI installation guide. The CLI bundles the local test runtime (Viceroy) used by
fastly compute serve.
-
Initialize a project from this template using the Fastly CLI.
fastly compute init --from https://github.com/optimizely/fastly-compute-starter-kit cd my-projectFollow the wizard and provide the service name, description, and any other requested information.
-
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 it using one of these methods:
Option A: Local development (fastly.toml)
Edit the
optimizelyConfig Store contents infastly.tomland replaceYOUR_SDK_KEY_HERE:[local_server.config_stores] [local_server.config_stores.optimizely] format = "inline-toml" [local_server.config_stores.optimizely.contents] sdk_key = "YOUR_SDK_KEY_HERE" datafile_ttl_seconds = "300"
Option B: Deployed service (Config Store)
The
[setup.config_stores]block infastly.tomlprovisions theoptimizelyConfig Store the first time you runfastly compute publish; the CLI prompts you for thesdk_keyvalue. You can also manage the entry directly with the CLI:fastly config-store-entry update --store-id <id> --key sdk_key --value <your_sdk_key>
├── src/
│ ├── index.js # Main entry point (fetch event handler)
│ ├── optimizely_helper.js # Optimizely SDK integration + datafile caching
│ └── request_handler.js # Fastly-specific SDK request handler
├── test/
│ ├── index.test.js # Tests for the entry handler
│ ├── optimizely_helper.test.js # Tests for the Optimizely helper
│ ├── request_handler.test.js # Tests for the request handler
│ ├── setup.js # Test environment setup (Fastly global mocks)
│ ├── test-utils.js # Shared test utilities and mocks
│ └── mocks/ # Mocks for Fastly runtime modules
├── biome.jsonc # Biome configuration for linting/formatting
├── fastly.toml # Fastly Compute service configuration
├── package.json # Node.js dependencies and scripts
└── vitest.config.js # Vitest testing framework configuration
The Optimizely starter kit for Fastly Compute 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 uses the "Universal" build of our JavaScript SDK, which excludes the polling datafile manager and batch event processor for better edge performance. The datafile is fetched from Optimizely's CDN and cached at the Fastly edge via
CacheOverride, and events are dispatched through a Fastly backend using the platform-specific request handler insrc/request_handler.js.
This template includes modern development tools:
- Biome: Fast formatter and linter for JavaScript
- Vitest: Fast unit testing framework
- Fastly CLI + Viceroy: Local development server that simulates Fastly Compute
Available commands:
npm run serve # Build and serve locally with the Fastly CLI (Viceroy)
npm run build # Compile src/index.js to a WebAssembly module (bin/main.wasm)
npm run deploy # Build and deploy to Fastly
npm run format # Format code with Biome
npm run lint # Lint and auto-fix code with Biome
npm run test # Run unit tests with VitestSample code is included in src/index.js that shows examples of initializing and using the Optimizely JavaScript SDK for common functions such as creating a user context and making decisions.
Additional platform-specific code is included in src/optimizely_helper.js and src/request_handler.js, which provide:
- Datafile Caching: Fetching and caching the Optimizely datafile through a Fastly backend with
CacheOverride. - Client Management: Per-request client creation with module-scope datafile reuse and stale fallback.
- Event Dispatching: Event forwarding to Optimizely's logging backend.
To customize:
-
Configure your feature flags: Update the
YOUR_FLAG_HEREplaceholder insrc/index.jswith your actual flag key from the Optimizely dashboard. -
Test and debug locally.
npm run serve
-
Build and publish to Fastly.
fastly compute publish
-
Monitor logs for decision results.
fastly log-tail
This template caches the Optimizely Datafile at the Fastly edge using CacheOverride. The datafile is fetched from Optimizely's CDN through the optlycdn backend and cached for 5 minutes by default.
Cache Configuration:
- Default TTL: 5 minutes (300 seconds)
- Configurable via: the
datafile_ttl_secondskey in theoptimizelyConfig Store - Example values:
300(5 minutes),600(10 minutes),1800(30 minutes) - Behavior: A stale-while-revalidate window and a module-scope fallback keep the last known datafile in use if a refresh fetch fails.
Out of the box, Optimizely's Feature Experimentation SDKs require a user-provided identifier 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 decisions sticky. Alternatively, you can use an existing unique identifier from 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.
This starter kit routes the Optimizely SDK's external calls through Fastly Compute's fetch against registered backends declared in fastly.toml (optlycdn for the datafile CDN and optlylogx for event logging). Backends must be named in fastly.toml and referenced by name in each request.
For more information about Fastly Compute, you may visit the following resources:
- Fastly Compute documentation
- JavaScript on Fastly Compute
- Fastly Compute@Edge with Optimizely documentation
Ensure the optimizely Config Store exists. For local development, confirm the [local_server.config_stores.optimizely] block is present in fastly.toml. For a deployed service, run fastly compute publish so the [setup.config_stores] block provisions it.
Set the sdk_key value in the optimizely Config Store (see step 3 of Install the Starter Kit). Confirm it matches an active Optimizely project environment.
This usually means the SDK key is incorrect, does not match an active project, or the Optimizely CDN is temporarily unavailable. When a cached datafile is available it continues to be used (stale fallback).
- 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.
- Run
fastly log-tailto inspect decision output.
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
-
Cloudflare Workers - https://github.com/optimizely/cloudflare-worker-template
-
Vercel Functions - https://github.com/optimizely/vercel-examples/tree/main/edge-functions/feature-flag-optimizely