# Node.js quickstart

## 1. Install `hypertune`

Once you have a Node.js application ready, install Hypertune's JavaScript SDK:

{% tabs %}
{% tab title="npm" %}

```bash
npm install hypertune
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add hypertune
```

{% endtab %}

{% tab title="pnpm" %}

```bash
pnpm add hypertune
```

{% endtab %}
{% endtabs %}

## 2. Set environment variables

Define the following environment variables in your `.env` file:

{% code title=".env" %}

```bash
HYPERTUNE_TOKEN=token
HYPERTUNE_OUTPUT_DIRECTORY_PATH=src/generated
```

{% endcode %}

Replace `token` with your main project token which you can find in the Settings tab of your project.

## 3. Generate the client

Generate a type-safe client to access your flags by running:

{% tabs %}
{% tab title="npm" %}

```bash
npx hypertune
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn hypertune
```

{% endtab %}

{% tab title="pnpm" %}

```bash
pnpm hypertune
```

{% endtab %}
{% endtabs %}

## 4. Use the client

Install the `dotenv` package or ensure you have another way to load environment variables:

{% tabs %}
{% tab title="npm" %}

```bash
npm install dotenv
npm install -D @types/dotenv
```

{% endtab %}

{% tab title="yarn" %}

```bash
yarn add dotenv
yarn add -D @types/dotenv
```

{% endtab %}

{% tab title="pnpm" %}

```bash
pnpm add dotenv
pnpm add -D @types/dotenv
```

{% endtab %}
{% endtabs %}

Add a new file called `loadEnv.ts` that loads environment variables with `dotenv`:

{% code title="src/lib/loadEnv.ts" %}

```typescript
import * as dotenv from 'dotenv'

dotenv.config()
```

{% endcode %}

Add a new file called `getHypertune.ts` that exports a `getHypertune` function:

{% code title="src/lib/getHypertune.ts" %}

```typescript
import { createSource } from '../generated/hypertune'

const hypertuneSource = createSource({
  token: process.env.HYPERTUNE_TOKEN!,
})

export default async function getHypertune() {
  // Get flag updates in serverless environments
  // await hypertuneSource.initIfNeeded();

  return hypertuneSource.root({
    args: {
      context: {
        environment:
          process.env.NODE_ENV === 'development'
            ? 'development'
            : 'production',
        user: {
          id: 'e23cc9a8-0287-40aa-8500-6802df91e56a',
          name: 'Example User',
          email: 'user@example.com',
        },
      },
    },
  })
}
```

{% endcode %}

To access flags, use the `getHypertune` function:

{% code title="src/index.ts" %}

```typescript
import './lib/loadEnv'
import express from 'express'
import getHypertune from './lib/getHypertune'

const app = express()
const port = 3000

app.get('/', async (req, res) => {
  const hypertune = await getHypertune()

  const exampleFlag = hypertune.exampleFlag({ fallback: false })

  res.json({ exampleFlag })
})

app.listen(port, () => {
  console.log(`Server is listening on port ${port}`)
})
```

{% endcode %}

## 5. (Optional) Include a build-time snapshot

To improve reliability, you can include a snapshot of your flag logic in the generated client at build time. The SDK will instantly initialize from the snapshot first before fetching the latest flag logic from [Hypertune Edge](https://docs.hypertune.com/concepts/hypertune-edge).

Add the following environment variable to your `.env` file:

```bash
HYPERTUNE_INCLUDE_INIT_DATA=true
```

Then regenerate the client.

You can keep the snapshot fresh by setting up a [webhook](https://docs.hypertune.com/integrations/webhooks) to regenerate the client on every Hypertune commit. In this case, you don't need to initialize from Hypertune Edge at all, eliminating network latency and bandwidth, improving both performance and efficiency.

## Next steps

Now you can update the logic for `exampleFlag` from the Hypertune UI without updating your code or waiting for a new build, deployment, or service restart.

To add a new flag, create it in the Hypertune UI then regenerate the client.
