Glim is a drop-in guidance companion for Next.js apps: a small glowing character that lives in your product, answers end-user questions in a streamed speech bubble, and flies to and points at the exact UI elements it references. Install one npm package, mount one provider and one route handler, and your product can teach itself to users — grounding is a live DOM snapshot, so guidance survives redesigns. Optional guides make key journeys deterministic, and client tools let the model call into your app code.
- Node >= 20
- pnpm
- An Anthropic API key
1. Install
pnpm add @glim-sdk/next2. Mount the provider once in your root layout
// app/layout.tsx
import { GlimProvider } from '@glim-sdk/next'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<GlimProvider>{children}</GlimProvider>
</body>
</html>
)
}GlimProvider also takes: endpoint (default /api/glim), theme (CSS custom properties, e.g. { '--glim-hue': '45' }), enabled (default true — master switch, false shows no UI on any route), allowedRoutes (restrict Glim to specific pages — omit to allow every route), and character (swap the default orb).
Most apps don't want Glim on every page — a settings page or marketing footer usually doesn't need it. Use allowedRoutes instead of conditionally rendering <GlimProvider> yourself:
<GlimProvider allowedRoutes={['/', '/dashboard', '/settings']}>{children}</GlimProvider>A route matches its own pathname or anything nested under it (/settings matches /settings/billing, not /settings-legacy). Anywhere in the tree, useGlim().active tells you whether Glim is actually live on the current page — handy for hiding a "Show me how" button on pages it doesn't cover:
const { active, startGuide } = useGlim()
if (!active) return null3. Add the route handler
// app/api/glim/route.ts
import { createGlimHandler } from '@glim-sdk/next/server'
import { publishListingGuide } from './guides'
export const POST = createGlimHandler({
apiKey: process.env.ANTHROPIC_API_KEY,
model: 'claude-sonnet-5', // default
persona: 'warm, brief, lowercase', // optional brand voice override
knowledge: './docs', // optional markdown folder
guides: [publishListingGuide],
})- Origin. The handler compares the request's
Originheader host against its own host (a missingOriginis treated as same-origin). SetallowedOrigins: ['https://app.example.com']explicitly in production — especially behind a TLS-terminating proxy or CDN, where the request URL host can differ from the public origin. - The endpoint drives your API key. Any same-origin end user can send questions through this route and spend against the configured Anthropic key. That spend is bounded by the built-in
maxTokens,maxLoops, and request-body size caps, but the route is not authenticated — add your own auth/rate limiting if you need per-user limits.
4. (Optional) Define a guide
Guides are playbooks, not selector recordings — the model follows the steps semantically and improvises when the user deviates.
// app/api/glim/guides.ts
import { defineGuide, point, waitFor, say } from '@glim-sdk/next/server'
export const publishListingGuide = defineGuide({
id: 'publish-listing',
when: 'user asks how to publish or make a listing live',
steps: [
point('the Publish button on the draft listing', 'hit publish right here'),
waitFor({ click: true }),
say('nice — your place is live!'),
],
})Let your coding agent do the integration: copy CLAUDE.md into your project (or paste its raw URL into the chat) and say "add Glim to this app." It contains the exact provider/route-handler wiring, guide-authoring rules, and verification checklist agents need to get it right first try:
https://raw.githubusercontent.com/mannasdev/glim/main/CLAUDE.md
The repo ships with "Harbor", a fake vacation-rental dashboard, in examples/demo.
pnpm install
pnpm --filter harbor-demo devOpen http://localhost:3000 and ask the glim "how do i publish?". Set GLIM_FIXTURE=1 to run against a canned fixture model instead of the live Anthropic API:
GLIM_FIXTURE=1 pnpm --filter harbor-demo devUnit and integration tests (vitest, jsdom):
pnpm --filter @glim-sdk/next testEnd-to-end tests (Playwright drives Harbor against the fixture model — no API key needed):
npx playwright install chromium
pnpm e2e