Two lines of code to give your LLM eyes.
One attribute. Zero prompt engineering. It knows exactly what the user sees.
Quick Start · Why · How it works · Works with · Features · Packages · Docs · Live Demo
npm install @askable-ui/react
import { Askable, useAskable } from '@askable-ui/react';
function Dashboard({ kpi }) {
const { promptContext } = useAskable();
// promptContext: "User is focused on: metric=revenue, value=$2.3M, delta=+12%"
return (
<Askable meta={{ metric: kpi.name, value: kpi.value, delta: kpi.delta }}>
<KPICard data={kpi} />
</Askable>
);
}
That's it. promptContext updates automatically as the user interacts. Pass it to any LLM.
AI copilots ask users to describe what they're looking at. That's friction — and it's imprecise.
askable-ui solves this with one HTML attribute. Mark any element with data-askable, and the library tracks user focus and serializes it into a prompt-ready string. The model gets the user's exact visual context — not a guess, the real thing.
No page scraping. No DOM serialization. No prompt bloat. Lightweight and zero-dependency.
1. Annotate — same data that renders your chart feeds the AI
<Askable meta={{ metric: 'revenue', value: '$2.3M', delta: '+12%', period: 'Q3' }}>
<RevenueChart data={data} />
</Askable>
2. Observe — automatic, zero config
const { ctx, promptContext } = useAskable();
// promptContext updates whenever the user clicks, hovers, or focuses
const { ctx: tableCtx } = useAskable({ name: 'table' });
const { ctx: chartCtx } = useAskable({ name: 'chart' });
// named contexts stay isolated for multi-region pages
const { ctx: screenCtx } = useAskable({ viewport: true });
// screenCtx.toViewportContext() serializes currently visible annotated elements
3. Inject — at the AI boundary, one line
const result = await streamText({
model: openai('gpt-4o'),
system: `You are a helpful analytics assistant.\n\n${promptContext}`,
messages,
});
LLM SDKs — OpenAI · Anthropic · Vercel AI SDK · CopilotKit · LangChain · any SDK
Frameworks — React · Vue 3 · Svelte · Vanilla JS · Next.js · Nuxt · SvelteKit
askable-ui is the context layer. It doesn't replace your LLM SDK — it gives it eyes.
window is not definedctx.select(element) pins focus to any element programmaticallyctx.toHistoryContext(n) for multi-turn contextctx.getVisibleElements() / ctx.toViewportContext() for on-screen context<AskableInspector /> or useAskable({ inspector: true }) for a live dev overlay| Package | Version | Use when |
|---|---|---|
@askable-ui/core |
Vanilla JS, custom framework, or as a peer dep | |
@askable-ui/react |
React 18+ | |
@askable-ui/react-native |
React Native (initial press-driven adapter) | |
@askable-ui/vue |
Vue 3 | |
@askable-ui/svelte |
Svelte 4 & 5 |
npm install @askable-ui/react-native
import { Pressable, Text } from 'react-native';
import { Askable, useAskable } from '@askable-ui/react-native';
function RevenueCard() {
const { ctx, promptContext } = useAskable();
return (
<Askable ctx={ctx} meta={{ widget: 'revenue' }} text="Revenue card">
<Pressable>
<Text>Revenue</Text>
</Pressable>
</Askable>
);
}
For a runnable mobile demo, see examples/react-native-expo.
npm install @askable-ui/vue
<script setup>
import { Askable, useAskable } from '@askable-ui/vue';
const { promptContext } = useAskable();
const props = defineProps(['kpi']);
</script>
<template>
<Askable :meta="{ metric: kpi.name, value: kpi.value }">
<KPICard :data="kpi" />
</Askable>
</template>
npm install @askable-ui/svelte
<script>
import { Askable, useAskable } from '@askable-ui/svelte';
const { promptContext } = useAskable();
export let kpi;
</script>
<Askable meta={{ metric: kpi.name, value: kpi.value }}>
<KPICard data={kpi} />
</Askable>
npm install @askable-ui/core
import { createAskableContext } from '@askable-ui/core';
const ctx = createAskableContext();
ctx.observe(document.body);
ctx.on('focus', () => {
console.log(ctx.toPromptContext());
// "User is focused on: — metric: revenue, value: $2.3M"
});
| Guide | |
|---|---|
| Getting started | Install, observe, inject |
| Annotating elements | data-askable, nesting, priority |
| React · Vue · Svelte | Framework guides |
| CopilotKit integration | Context-in-input pattern |
| API reference | Full type docs |
PRs welcome! See CONTRIBUTING.md for setup instructions.
MIT — see LICENSE