Co-authored by
Hayden Bleaselnext-forge
Michal BockHypertune
Miraan TabrezHypertune

Hypertune is the most flexible platform for feature flags, A/B testing, analytics and app configuration. Built with full end-to-end type-safety, Git version control and local, synchronous, in-memory flag evaluation. Optimized for TypeScript, React and Next.js.

Here’s how to switch your next-forge project to use Hypertune for feature flags!

1. Create a new Hypertune project

Go to Hypertune and create a new project using the next-forge template. Then go to the Settings page of your project and copy the main token.

2. Update the environment variables

Update the environment variables across the project. For example:

apps/app/.env
// Add this:
NEXT_PUBLIC_HYPERTUNE_TOKEN=""

Add a .env file to the feature-flags package with the following contents:

packages/feature-flags/.env
NEXT_PUBLIC_HYPERTUNE_TOKEN=""
HYPERTUNE_FRAMEWORK=nextApp
HYPERTUNE_OUTPUT_DIRECTORY_PATH=generated
HYPERTUNE_PLATFORM=vercel
HYPERTUNE_GET_HYPERTUNE_IMPORT_PATH=../lib/getHypertune

3. Update the keys.ts file in the feature-flags package

Use the NEXT_PUBLIC_HYPERTUNE_TOKEN environment variable in the call to createEnv:

packages/feature-flags/keys.ts
import { createEnv } from '@t3-oss/env-nextjs';
import { z } from 'zod';

export const keys = () =>
  createEnv({
    client: {
      NEXT_PUBLIC_HYPERTUNE_TOKEN: z.string().min(1),
    },
    server: {
      FLAGS_SECRET: z.string().min(1).optional(),
    },
    runtimeEnv: {
      FLAGS_SECRET: process.env.FLAGS_SECRET,
      NEXT_PUBLIC_HYPERTUNE_TOKEN: process.env.NEXT_PUBLIC_HYPERTUNE_TOKEN,
    },
  });

4. Swap out the required dependencies

First, delete the create-flag.ts file.

Then, uninstall the existing dependencies from the feature-flags package:

Terminal
pnpm remove @repo/analytics --filter @repo/feature-flags

Then, install the new dependencies:

Terminal
pnpm add hypertune server-only --filter @repo/feature-flags

5. Set up Hypertune code generation

Add analyze and build scripts to the package.json file for the feature-flags package, which both execute the hypertune command:

packages/feature-flags/package.json
{
  "scripts": {
    "analyze": "hypertune",
    "build": "hypertune"
  }
}

Then run code generation with the following command:

Terminal
pnpm build --filter @repo/feature-flags 

This will generate the following files:

packages/feature-flags/generated/hypertune.ts
packages/feature-flags/generated/hypertune.react.tsx
packages/feature-flags/generated/hypertune.vercel.tsx

6. Set up Hypertune client instance

Add a getHypertune.ts file in the feature-flags package which defines a getHypertune function that returns an initialized instance of the Hypertune SDK on the server:

packages/feature-flags/lib/getHypertune.ts
import 'server-only';
import { auth } from '@repo/auth/server';
import { unstable_noStore as noStore } from 'next/cache';
import type { ReadonlyHeaders } from 'next/dist/server/web/spec-extension/adapters/headers';
import type { ReadonlyRequestCookies } from 'next/dist/server/web/spec-extension/adapters/request-cookies';
import { createSource } from '../generated/hypertune';
import { getVercelOverride } from '../generated/hypertune.vercel';
import { keys } from '../keys';

const hypertuneSource = createSource({
  token: keys().NEXT_PUBLIC_HYPERTUNE_TOKEN,
});

export default async function getHypertune(params?: {
  headers?: ReadonlyHeaders;
  cookies?: ReadonlyRequestCookies;
}) {
  noStore();
  await hypertuneSource.initIfNeeded(); // Check for flag updates

  const { userId, orgId, sessionId } = await auth();

  // Respect flag overrides set by the Vercel Toolbar
  hypertuneSource.setOverride(await getVercelOverride());

  return hypertuneSource.root({
    args: {
      context: {
        environment: process.env.NODE_ENV,
        user: { id: userId ?? '', sessionId: sessionId ?? '' },
        org: { id: orgId ?? '' },
      },
    },
  });
}

7. Update index.ts

Hypertune automatically generates feature flag functions that use the @vercel/flags package. To export them the same way as before, update the index.ts file to export everything from the generated/hypertune.vercel.ts file:

packages/feature-flags/index.ts
export * from "./generated/hypertune.vercel.tsx"

Hypertune adds a Flag suffix to all these generated feature flag functions, so you will need to update flag usages with this, e.g. showBetaFeature => showBetaFeatureFlag.

8. Add more feature flags

To add more feature flags, create them in the Hypertune UI and then re-run code generation. They will be automatically added to your generated files.