Adaptive React UI from a plain-English sentence. Describe a situation, and Adaptif shows the right UI when it's true for the user in front of you.
<When
situation="The user is doing repetitive work that our Bulk Edit tool could automate"
fallback={<StandardToolbar />}
>
<BulkEditSuggestion />
</When>You pass the app state you already have. Jev, TypeSafe AI's decision model, answers from your own server in about 100 ms to a second, and your UI follows. If the answer is slow, unsure, or anything fails, the fallback renders and your app behaves as if Adaptif weren't installed.
In a 72-case offline eval, Jev was right on 60 cases; the best hand-written rule I could write for each question got 45 (83% vs 63%, results and caveats). It's an early project, but the early results are promising. See what's next.
For a full example, see the candle shop.
Use Adaptif when the right UI depends on what a user's behavior adds up to: the pages they visit, what they open, compare, undo, or come back to. A rule can count those events but can't read them, and a one-off LLM call doesn't follow the session or keep your UI from flickering. If an if statement can decide it, use an if statement.
- Guided selling. A shopper opens the scent notes on candles from three different families and keeps going. Offer the scent quiz before they give up. "The shopper seems unsure which scent they would actually enjoy"
- Price-aware carts. A shopper who sorts by price, removes an item, and reads the shipping page sees ways to save. One who reads reviews and picks the large size gets an upgrade offer instead. "How much is price weighing on this shopper's decision?"
- Competitor migration. Show an import guide to trial users whose stated goal and first few pages suggest they're comparing you with a tool they already use. "The user is evaluating this product against a tool they already use"
- Smart paywalls. Offer Pro only when the user's own goal needs a Pro feature, instead of nagging everyone. "The user's stated goal needs something only the Pro plan has"
The first two run in the candle shop.
- You register a question in
adaptif.config.ts. That file is also your server's allowlist: anything not in it is rejected, so nobody can spend your API key on questions you didn't write. - Your server asks the model. The browser sends the question's id and the state you pass to a route on your server. That route holds the API key and calls Jev.
<When>shows the content or the fallback. If the answer is likely enough, the content renders. Otherwise the fallback does.
Nothing is read from the page: the model sees only the state and events you hand it. More in How it works.
The adaptif-setup skill reads your project, helps you write the first question, installs the packages, writes the config and the server route, keeps your current UI as the fallback, and checks the build. It works with Claude Code, Cursor, Codex, GitHub Copilot, and other agents, and never asks for your API key.
npx skills add robiscoding/adaptif --skill adaptif-setupThen ask your agent: Set up Adaptif in this app. More in Agent skills.
Show a gift banner when a shopper's browsing looks like gift shopping. No category rule can tell: a wallet might be for them or for their dad. The mix of what they look at says more. This uses Next.js; for other frameworks see Providers and frameworks.
1. Install. You need React 18.2 or 19 and Next.js 15.1+.
npm install @adaptif/react @adaptif/next2. Register the question. The object key is the question text, and it's what <When situation> refers to. Put these next to your other top-level files, inside src/ if you have one. Both the browser and the server import the config, so keep secrets out of it.
// adaptif.config.ts
import { defineAdaptif } from "@adaptif/react/config";
export interface AppState {
// Names of the products this shopper has viewed this visit, oldest first.
viewedProducts: string[];
}
export const adaptif = defineAdaptif<AppState>()({
situations: {
"The shopper seems to be buying a gift for someone else": {
uses: ["viewedProducts"],
},
},
});// adaptif.ts
import { createAdaptifReact } from "@adaptif/react";
import { adaptif } from "./adaptif.config";
export const { AdaptifProvider, When } = createAdaptifReact(adaptif);3. Add the route and a key. Get a key from the TypeSafe console and put TYPESAFE_API_KEY=… in .env.local, with no NEXT_PUBLIC_ prefix (other providers). The [...path] folder name matters: the browser calls /api/adaptif/evaluate. No key yet? Skip to Try it without a key.
// app/api/adaptif/[...path]/route.ts
import { createAdaptifRoute } from "@adaptif/next";
import { adaptif } from "@/adaptif.config";
export const { POST } = createAdaptifRoute({ config: adaptif });The route reads the key on the first request, so next build works without it.
4. Show the banner. Until an answer arrives, and whenever it isn't likely enough or something fails, the fallback renders. fallback={null} leaves the page as it was.
// app/components/gift-banner.tsx
"use client";
import { AdaptifProvider, When } from "@/adaptif";
export function GiftBanner({ viewedProducts }: { viewedProducts: string[] }) {
return (
<AdaptifProvider state={{ viewedProducts }} endpoint="/api/adaptif">
<When situation="The shopper seems to be buying a gift for someone else" fallback={null}>
<p>Gift wrapping is free on every order this week.</p>
</When>
</AdaptifProvider>
);
}5. Try it. View a men's leather wallet, a kids' puzzle, and a lavender candle, and the banner shows up a second or two after the third. View the same running shoe in three colors and it stays hidden. The banner is asked again each time viewedProducts changes.
Mock is useful for testing, development, or if you just don't have a Jev API key yet.Pass mock instead of endpoint. true shows the child content, false hides it, and nothing is sent to the server:
<AdaptifProvider
state={{ viewedProducts }}
mock={{ "The shopper seems to be buying a gift for someone else": true }}
>A few guides for diving deeper:
- Supply useful state
- Add intents with Match
- Improve timing with events and triggers
- Write good questions and tune thresholds
Going further:
- Add capture: record clicks and form activity on elements you mark
- Measure outcomes: hold out a share of users to check whether the adaptive UI helps
- Production hardening: rate limits, call caps, and what leaves the browser
Reference:
- How it works: what users see while it decides, and why not to call the model yourself
- Examples: the candle shop and the recipe catalog
- Agent skills: set up and tune Adaptif with your coding agent
- Providers, frameworks, and cost
- Architecture
- Does it actually work?
- What's next
Bug reports and PRs are welcome. CONTRIBUTING.md has the dev setup. If you find a security issue, please report it privately through the repo's Security tab instead of a public issue.
