npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mathewk21/ai-chat-form

v0.2.26

Published

Schema-driven conversational AI chat form widget for React.

Readme

@mathewk21/ai-chat-form

Schema-driven conversational AI form widget for React — field-by-field chat flows with premium welcome and completion screens.

Install

npm install @mathewk21/ai-chat-form framer-motion

Import styles once in your app entry (Tailwind/PostCSS must process screens.css):

import "@mathewk21/ai-chat-form";

Configure PostCSS with the package Tailwind config:

// postcss.config.cjs
module.exports = {
  plugins: {
    tailwindcss: { config: "./node_modules/@mathewk21/ai-chat-form/tailwind.config.cjs" },
    autoprefixer: {}
  }
};

Quick start

import { AIChatForm, createChatForm } from "@mathewk21/ai-chat-form";

const form = createChatForm({
  id: "signup",
  title: "Sign up",
  fields: [
    { id: "name", type: "text", label: "What's your name?", required: true },
    { id: "email", type: "email", label: "Email?", required: true }
  ]
});

export function SignupFlow() {
  return (
    <AIChatForm
      form={form}
      theme="minimal"
      onComplete={(result) => console.log(result.values)}
    />
  );
}

Welcome Screen

Show a cinematic onboarding screen before the conversation starts.

Schema configuration

const schema = {
  id: "onboarding",
  title: "Acme AI",
  welcomeScreen: {
    title: "Welcome to Acme AI Assistant",
    subtitle: "Let's get your setup completed",
    description: "This AI assistant will guide you through a few quick questions.",
    logo: "/logo.png",
    estimatedTime: "2 minutes",
    layout: "centered", // centered | split | fullscreen
    animation: "stagger", // fade | slide | stagger | none
    progressPreview: true,
    features: [
      { icon: "✦", title: "AI-guided", description: "Natural conversation" }
    ],
    trustIndicators: ["SOC 2 aligned", "GDPR friendly"],
    privacyNotice: "Your data is encrypted and never sold.",
    primaryAction: { label: "Get Started" },
    secondaryAction: { label: "Learn more", href: "https://acme.ai", variant: "ghost" }
  },
  fields: [/* ... */]
};

Standalone widget

import { WelcomeScreen } from "@mathewk21/ai-chat-form";

<WelcomeScreen
  title="Welcome to Acme AI Assistant"
  subtitle="Let's get your setup completed"
  description="This AI assistant will guide you through a few quick questions."
  logo="/logo.png"
  estimatedTime="2 minutes"
  primaryAction={{ label: "Get Started", onClick: startFlow }}
/>

Props override on AIChatForm

<AIChatForm
  form={form}
  welcomeScreen={{ estimatedTime: "3 minutes", themeColor: "#6366f1" }}
  onAnalytics={(event) => analytics.track(event.type, event)}
/>

Completion Screen

Celebrate submission with a polished thank-you experience.

Schema configuration

completionScreen: {
  title: "You're all set!",
  description: "Thanks for completing the setup.",
  confetti: true,
  animation: "celebrate",
  nextSteps: [
    { label: "Explore dashboard", done: true },
    { label: "Invite your team" }
  ],
  primaryAction: { label: "Visit Website", href: "https://acme.ai" },
  secondaryAction: { label: "Start Again", variant: "secondary" },
  emailConfirmationNotice: "Check your inbox for a confirmation email."
}

Standalone widget

import { CompletionScreen } from "@mathewk21/ai-chat-form";

<CompletionScreen
  title="You're all set!"
  description="Thanks for completing the setup."
  logo="/logo.png"
  websiteUrl="https://acme.ai"
  primaryAction={{ label: "Visit Website", href: "https://acme.ai" }}
  secondaryAction={{ label: "Start Again", onClick: restartFlow }}
  confetti
/>

Customization

Custom renderers

<AIChatForm
  form={form}
  renderWelcomeScreen={(props) => <MyWelcome {...props} />}
  renderCompletionScreen={(props) => <MyCompletion {...props} />}
/>

Register screen widgets

import { registerScreenWidget, WelcomeScreen } from "@mathewk21/ai-chat-form";

registerScreenWidget("welcome", MyBrandedWelcome);
// Falls back to built-in WelcomeScreen if not registered

Slots

<WelcomeScreen
  {...config}
  slots={{
    footer: <p>Need help? [email protected]</p>,
    beforeCta: <TrustBadge />
  }}
/>

Theme inheritance

Screens inherit --acf-* tokens from the active AIChatForm theme (minimal, glass, dark, neon, enterprise). Override accent per screen:

welcomeScreen={{ themeColor: "#0ea5e9" }}

Dark mode

Use theme="dark" on AIChatForm — welcome and completion screens automatically adapt via CSS variables.

Analytics hooks

onAnalytics={(event) => {
  switch (event.type) {
    case "welcome_view":
    case "welcome_primary_click":
    case "completion_view":
    case "completion_restart":
      // track event
      break;
  }
}}

Multi-step welcome slides

welcomeScreen: {
  title: "Welcome",
  slides: [
    { title: "Meet your AI", description: "Personalized guidance" },
    { title: "Stay secure", description: "Enterprise-grade privacy" },
    { title: "Ready?", description: "Let's begin" }
  ],
  primaryAction: { label: "Get Started" }
}

AI Generated Follow-Ups

Add adaptive questions that are generated from prior answers, form metadata, and developer instructions.

Full working example: packages/demo/src/pages/aiChatForms/aiFollowUpFullShowcaseForm.ts — welcome screen, static fields, recursive LLM follow-ups, ranked options, conditional follow-up, completion screen. In the demo app, pick ★ Full AI Follow-Up Showcase.

Schema field

{
  id: "ai_admissions",
  type: "ai_generated_follow_up",
  label: "Personalized follow-up",
  followUp: {
    ai: {
      instructions: "Focus on university admissions. Keep questions short and friendly.",
      domainContext: "Study abroad counseling",
      temperature: 0.6,
      allowedInputTypes: ["multiselect", "select", "textarea", "date"]
    },
    inputMode: "auto", // or "manual" + forcedInputType
    flow: { mode: "recursive", maxFollowUps: 2 },
    options: {
      mode: "ai_ranked_static",
      maxVisible: 5,
      options: [{ label: "Australia" }, { label: "Canada" }, { label: "UK" }]
    },
    memory: { includePriorAnswers: true, includeConversation: true },
    safety: { minConfidence: 0.7, fallbackQuestion: "What else should we know?" }
  }
}

LLM via marketplace execute API (chatbot SDK)

When VITE_DEMO_API_KEY (or executeApiKey) is set, follow-ups call the same /api/v1/execute/{model}/ endpoint as @mathewk21/chatbot, with heuristic fallback on failure.

import { createChatForm } from "@mathewk21/ai-chat-form";

const form = createChatForm(schema, {
  followUp: {
    executeApiKey: process.env.VITE_DEMO_API_KEY,
    modelId: "deepseek-v32-non-thinking-mode",
    externalEmail: "[email protected]"
  }
});

Model selection

Form-level default (all follow-up fields):

followUp: { modelId: "gpt-4o" }

Per-field override:

{
  type: "ai_generated_follow_up",
  followUp: {
    ai: { modelId: "claude-3-5-sonnet", instructions: "…" }
  }
}

Load models from the gateway catalog (same as chatbot):

import { AIFollowUpModelSelect, fetchFollowUpLlmModels } from "@mathewk21/ai-chat-form";

const models = await fetchFollowUpLlmModels({ apiKey: process.env.VITE_DEMO_API_KEY });

<AIFollowUpModelSelect
  value={modelId}
  onChange={setModelId}
  executeApiKey={apiKey}
  models={models}
/>

Custom orchestration

import {
  createChatForm,
  createExecuteFollowUpProvider,
  heuristicFollowUpProvider
} from "@mathewk21/ai-chat-form";

const form = createChatForm(schema, {
  followUp: {
    orchestrator: {
      provider: createExecuteFollowUpProvider({ apiKey: "aom_live_…" }),
      fallbackProvider: heuristicFollowUpProvider,
      cache: true,
      maxRetries: 1
    },
    sessionMetadata: { plan: "pro" },
    userProfile: { locale: "en-AU" }
  }
});

Generated response shape

{
  id: "fu_abc123",
  generated_question: "Which countries are you most interested in studying in?",
  generated_input_type: "multiselect",
  resolved_field_type: "multiselect",
  suggested_options: [{ label: "Australia" }, { label: "Canada" }],
  ai_reasoning_metadata: {
    based_on_answers: ["study_level"],
    confidence: 0.92,
    ranking_method: "semantic_similarity",
    provider: "heuristic"
  },
  round: 0,
  createdAt: "2026-05-27T12:00:00.000Z"
}

Events

<AIChatForm
  form={form}
  onFollowUpGenerated={({ fieldId, snapshot }) => {
    console.log(fieldId, snapshot.ai_reasoning_metadata);
  }}
/>

Demo templates: University Admissions, Recruitment, Lead Qualification, Healthcare Intake, Sales Discovery, and Smart Onboarding (see packages/demo).

Loading & Thinking UI Presets

Configure how the assistant appears while thinking, validating, generating follow-ups, and more.

import { AIChatForm, createChatForm } from "@mathewk21/ai-chat-form";

const form = createChatForm({
  id: "onboarding",
  title: "Onboarding",
  loadingPresence: {
    preset: "premium_saas",
    stateVariants: {
      searching_options: {
        display: "shape",
        shape: { kind: "gradient_orb", animation: "shimmer" }
      },
      processing_upload: {
        display: "avatar",
        avatar: { animation: "pulse" },
        text: { staticText: "Securing your upload…" }
      }
    }
  },
  fields: [/* … */]
});

| Mode | Description | |------|-------------| | avatar | Avatar + pulse/glow/breathing + typing dots + status text | | shape | Abstract shapes (circle, blob, hexagon, orb) with GPU-friendly CSS animations | | media | GIF, SVG, or MP4 loop for branded mascots |

Built-in presets: minimal, corporate, futuristic, friendly_assistant, glass_ai, neon, calm, playful, premium_saas, cyberpunk, robot_assistant (bundled GIF avatar while thinking; default out of the box).

Use AIChatLoadingPresenceBuilder for a visual editor with live preview and saved custom presets (localStorage).

API reference

| Export | Description | |--------|-------------| | WelcomeScreen | Standalone welcome widget | | CompletionScreen | Standalone completion widget | | registerScreenWidget | Replace built-in screen widgets | | getScreenWidget | Resolve registered screen component | | AIChatWelcomeScreenConfig | Welcome screen schema type | | AIChatCompletionScreenConfig | Completion screen schema type | | AIChatLoadingPresence | Standalone loading/thinking indicator | | AIChatLoadingPresenceBuilder | Visual preset editor | | AI_CHAT_LOADING_PRESETS | Built-in preset configs |

See TypeScript types for the full configuration surface (social links, calendar embed, submission recap, custom markdown, layouts, animations, and more).