---
title: "Build an adaptive experience with Jev | Snowplow Signals"
description: "The fastest way to build a real-time adaptive experience with Jev. Signals hands it what this visitor is doing, in 6ms. One state, one question, one render."
source: https://signals.snowplow.io/lp/adaptive-experiences
---

Adaptive experiences with Jev

# Build an adaptive experience in minutes.

Jev answers a typed question in a fraction of a second. Signals gives it the state that question needs: what this visitor is doing right now, read in 6ms. One prompt to your coding agent adds the SDK, reads the context, asks the question and renders the answer.

* **6ms** p50 read, in-region
* **1** prompt to your coding agent
* **Free** tier, no card

## Start free

5M events a month · unlimited attributes · no card 

Work email Continue

A work address, please. We cannot provision on a personal domain.

Or [talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=adaptive-experiences).

[ Try it on yourself ↓ ](#live-panel) 

Below is your own visit to this page, computed by Signals as you read.

### Signals, about you 

connecting 

See live events firing as you browse this page on the left; what Signals computed about you on the right, refreshed every few seconds.

Implement this

this page · events 0 writes 

Product Solutions Developers Pricing Start free 

Start free Engineer 

this panel

the rest of the page

nothing sent yet

write 

attribute store · your session no read yet 

reading\_now 

pages\_last\_5\_min 

seconds\_since\_last\_action 

sections\_read 

seconds\_engaged 

pricing\_views 

menus\_explored 

features\_wanted 

cta\_clicks 

arrived\_from 

waiting for the first computed value… 

Your first events are in flight through a real Snowplow pipeline. Attributes appear as the stream computes them, usually within a few seconds.

hand it to your agent one prompt 

Add the Signals MCP server to Claude Code, Cursor or any MCP client, then run this. The agent adds the SDK, defines the attribute and wires the read into your own app.

$ npx plugins add snowplow/skills

> Use the Snowplow MCP server and Signals skill, then help me plan and implement a use case. Make sure everything is tested and works as intended.

Copy the prompt[How to connect the MCP server](https://docs.snowplow.io/docs/llms-support/snowplow-mcp/) 

or 

write it yourself three steps 

01 Track the event once, in your app 

trackPageView(); // browser tracker, already on this page

02 Define the attribute once, in Signals 

Attribute(name="pages_last_5_min", events=["page_view"],
  aggregation="category_count", property="page_urlpath",
  period=timedelta(minutes=5))

03 Read it back every request 

await signals.getServiceAttributes({
  name: "signals_site_session_service",
  attribute_key: "domain_sessionid",
  identifier: "…", // your session id, once set
});

Why the state has to keep up

## Jev made the decision fast. The state it runs on has to be as fast. 

Before 

### A pipeline before the first render

A model that answers in a fraction of a second, fed a state object from last night or a lookup that takes longer than the answer. Everything it should know about this visitor sits in a pipeline you have not built, so the speed you adopted it for is spent before the call.

`still wiring the pipeline` 

With Signals 

### The state, already shaped for the call

Add a Snowplow SDK and events flow in. Name the activity the decision needs and Signals returns it as JSON, current as of this click, from the code that renders the page.

`getAgenticContext()` 

Result 

### Working on your own traffic in minutes

One prompt to your coding agent adds the SDK, defines the context and writes the Jev call, and the typed question runs against a real visitor minutes later. What you ship is the part that was always yours, the question and what each answer renders.

`state = { route, cart, session }` 

What you build with it

## Things to build once the state is live. 

Each is one typed question on every render. The interesting part is deciding what each answer should show, and that part is yours.

### A page that composes itself

Which panel leads, which proof shows, whether the button says start or talk, picked against what this visitor compared and skipped on this visit. Generative UI with a state that describes the person in front of it.

`choice: which panel leads?` 

### A flow that adapts mid-session

An onboarding that skips what they already did. A checkout that shows the reassurance the moment hesitation shows. Neither waits for anything computed overnight.

`noul: has this visitor stalled?` 

### Copy that matches the moment

One typed choice picks the message for a first-time browser, a returning comparer or someone stuck on a failed search. Same components, different answer, decided in the render.

`choice: first visit, comparing or stuck?` 

### Change it and watch it

The question and its answers are a few lines in your code. Change a bucket, reload, click around your own site and watch the page pick differently.

`edit, reload, click around` 

How it works

## Three calls, or one prompt. 

Signals does the knowing. Jev does the deciding. Your code does the rendering. The one-liner at the bottom of this page teaches your coding agent all three. Describe what the page should do and it writes the code.

1. 01 **Collect.** Add a Snowplow SDK to your app and behavioral events start flowing in, validated on the way.
2. 02 **Read.** One call returns what this visitor has been doing as JSON, <1s after the event, in 6ms p50.
3. 03 **Ask.** Pass it as the state on your Jev call, ask the typed question, render what the answer says.

Signals → your app 6ms p50 

name storefront\_session 

format json 

events last 30 this session 

compared\_this\_visit 2 

seconds\_on\_page 47 

Trigger hesitation\_visible delivered to your app 

Questions

## Before you try it

### How fast is it to get running?

Add the one-liner at the bottom of this page to your coding agent and paste the prompt beside it. The agent adds the SDK, defines the context and writes the Jev call against your own code. You should see the context updating against your own traffic in the first session on the free tier.

### Does this only work with Jev?

No. The context comes back as JSON over the REST API, the Node.js or Python SDK, or the MCP server, and as a plain string in narrative form. Anything that takes a state object or a prompt can read it. Jev is the model this page is written for because a typed question on every render is what it is built to answer.

### Does Signals decide what to render?

No. Signals computes what the visitor is doing and hands it over. Which components render, which offer fires and which flow runs is the model's answer and your code's call.

### Do I need an event stream already?

No. Collection is part of Signals. Add a Snowplow SDK to your web, mobile or server app and events start flowing in. If you already run Snowplow, Signals reads the pipeline you have.

### Where does it run?

Managed SaaS, or a private deployment in your own AWS or GCP account. Same architecture either way, so what you try is what you run.

### What does the free tier include?

The full product against your own traffic, up to 5 million events a month, with no card and no sales call. You should see an attribute updating against your own traffic in the first session.

## Make your next render adaptive in minutes.

Paste the one-liner and the prompt below into your coding agent. The panel at the top of this page is the first call it will write, running against you.

[Start free](https://signals.snowplow.io/start?lp=adaptive-experiences) [Talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=adaptive-experiences) 

The real engine · no card · no sales call 

Paste this into your coding agent 

$ `npx plugins add snowplow/skills` Copy Copied 

Then: Add Snowplow Signals to this app. Find the render where we would change what a visitor sees, define an agentic context for what they have been doing this session, read it as JSON and pass it as the state on a Jev typed question. Render what the answer says.
