Hypertune
Search
⌃K

Feature flags quickstart

Create a new project

Sign up at app.hypertune.com/register and create a new project.

Define your configuration schema

Hypertune uses GraphQL for its schema definition language.
Define a new feature flag called enablePaypal on the Root type:
type Root {
exampleFlag: Boolean!
enablePaypal: Boolean!
}

Define your configuration logic

Switch to the "Logic" tab and select the "Enable Paypal" flag.
Add an "If / Else" expression with a rule that enables the flag if context > user > id is test_id and disables it by default.

Preview your configuration result

Switch to the Preview tab and enter the following query:
query TestQuery {
root {
enablePaypal
}
}
Hypertune uses GraphQL for its query language. In the result panel, you can see just the part of your configuration logic that matches your query.
Now pass the context argument containing the user object in the query:
query TestQuery {
root(
context: {
user: {
id: "test_id"
name: "Test"
}
}
) {
enablePaypal
}
}
Now you can see a more reduced version of your configuration logic, where the "If / Else" expression has been replaced with its result.

Activate your changes

Click "Save and activate" in the navigation bar.

Install the Hypertune SDK and generate code

Open a terminal in the root of your TypeScript project and run:
npm install hypertune
Now add a new file in the root of your project called hypertune.graphql with the following contents:
query InitQuery {
root {
enablePaypal
}
}
This is your SDK initialization query. It determines what configuration logic is downloaded when the SDK initializes or fetches an update. And you get auto-generated code, based on this query, to use the SDK with end-to-end type-safety.
Add another file in the root of your project called hypertune.json with the following contents:
{
"projectId": your_project_id,
"token": "your_token",
}
Set projectId to your project ID from the Settings tab and token to your token.
You can also set outputDirectoryPath to control where Hypertune generates your code and queryFilePath to control where Hypertune should find your SDK initialization query.
If you don't want to commit your token, you can remove it from your hypertune.json and create a .env file in the root of your project with an environment variable:
HYPERTUNE_TOKEN=your_token
If you're using Hypertune on the frontend, you may need to prefix the variable name with REACT_APP_ or NEXT_PUBLIC_ to expose it to the browser.
Then run:
npx hypertune
You now have a generated TypeScript source file which you can use to interact with the SDK.

Use the Hypertune SDK

Add a new file called hypertune.ts with the following contents:
import { initializeHypertune } from "./generated/project_0";
const hypertune = initializeHypertune({});
export default hypertune;
Replace "./generated/project_0" with the path to your generated file.
Now you can import this top-level hypertune singleton and use its auto-generated type-safe methods to access your feature flag.
React
Node.js
Add a new file called useHypertune.ts with the following contents:
import React, { useEffect, useMemo } from "react";
import hypertune from "./hypertune";
export default function useHypertune() {
const [isInitialized, setIsInitialized] = React.useState<boolean>(
hypertune.isInitialized()
);
useEffect(() => {
hypertune.waitForInitialization().then(() => {
setIsInitialized(true);
});
}, []);
return useMemo(
() =>
hypertune
.root({
context: {
user: { id: "test_id", name: "Test", email: "[email protected]" },
},
}),
[]
);
}
Then use the hook in your app:
import useHypertune from "./useHypertune";
export default function App() {
const rootNode = useHypertune();
const enablePaypal = rootNode.enablePaypal({}).get(/* fallback */ false);
return (
<div>Enable Paypal: {String(enablePaypal)}</div>
);
}
import express, { Express } from "express";
import hypertune from "./hypertune";
export default function getApp(): Express {
const app = express();
app.get("/purchase", (req, res, next) => {
const rootNode = hypertune.root({
context: { user: { id: "test_id", name: "Test", email: "[email protected]" } },
});
const enablePaypal = rootNode.enablePaypal({}).get(/* fallback */ false);
if (enablePaypal) {
// Paypal code
}
});
return app;
}
If you're using Hypertune on the frontend and have a Content Security Policy, add the following URLs to the connect-src directive: https://edge.prod.hypertune.com https://gcp.fasthorse.workers.dev
This allows analytics to be sent back to Hypertune so you can see how often different parts of your flag logic are called, e.g. to see how many sessions fall into each targeting rule, as well as analytics for your events, A/B tests and machine learning loops.
When you ran npx hypertune, a snapshot of your configuration logic was saved in the generated file. The SDK instantly initializes from this snapshot first, before fetching the latest configuration logic from the server. So if you try accessing your flag just as your Node server or React app starts up, it'll use the logic in the snapshot if the SDK hasn't had a chance to initialize from the server yet.
Optionally, you can explicitly wait for the SDK to initialize from the server with hypertune.waitForInitialization():
React
Node.JS
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
hypertune.waitForInitialization().then(() => {
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});
app.get("/purchase", async (req, res, next) => {
await hypertune.waitForInitialization();
const rootNode = hypertune.root({
context: { user: { id: "test_id", name: "Test", email: "[email protected]" } },
});
const enablePaypal = rootNode.enablePaypal({}).get(/* fallback */ false);
if (enablePaypal) {
// Paypal code
}
});
If you've turned off buildTimeFallback in your hypertune.json, your generated file won't have a snapshot so the SDK will use your hardcoded fallback values.

That's it

Now you can update the logic for your enablePaypal flag from the Hypertune UI without a code update, build, deployment, app release or service restart.
When you hit "Save and activate", the SDK will download your new logic and use it for the next evaluation.
The Logic tab shows you live counts of how often different parts of your configuration logic are evaluated.
To add another new field, define it in the schema, include it in your SDK initialization query and rerun code generation with npx hypertune.