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

astro-chat

v0.1.0

Published

Streaming AI chat widget + API handler for Astro (OpenAI-compatible chat completions).

Readme

astro-chat

Streaming AI chat widget and API helper for Astro sites. Uses an OpenAI-compatible POST /chat/completions endpoint (default base URL https://api.x.ai/v1).

Install

npm install astro-chat

Peer dependencies: astro ^4 || ^5 || ^6, zod ^4.

Icons default to Bootstrap Icons (bi bi-*). No extra icon library is required. Add the stylesheet once (many templates already ship it):

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css"
/>

Icons (Bootstrap by default)

  • Omit icons → the widget uses built-in defaults (bi bi-chat-dots-fill, bi bi-x-lg, bi bi-send-fill, bi bi-building).
  • Customize with stringsicons={{ launcher: 'bi bi-chat-heart-fill', ... }}. Any name from the Bootstrap Icons site works.
  • Autocomplete / curated list → import CHAT_BOOTSTRAP_ICON_SUGGESTIONS (readonly list of common chat UI classes) or CHAT_BOOTSTRAP_ICON_DEFAULTS (the same defaults the widget uses) from astro-chat:
import {
  CHAT_BOOTSTRAP_ICON_DEFAULTS,
  CHAT_BOOTSTRAP_ICON_SUGGESTIONS,
  type ChatBootstrapIconSuggestion,
} from 'astro-chat';

// Spread defaults, override one key:
const icons = { ...CHAT_BOOTSTRAP_ICON_DEFAULTS, launcher: 'bi bi-stars' };

// Optional: type a variable as a curated suggestion (IDE autocomplete):
const glyph: ChatBootstrapIconSuggestion = 'bi bi-chat-dots-fill';

CHAT_BOOTSTRAP_ICON_SUGGESTIONS is not the full Bootstrap catalog—browse the site for every bi bi-* glyph.

Optional: Lucide or other Astro components

If you npm i @lucide/astro (or use your own .astro icon), you can pass component references on icons or use named slots for full prop control. This package does not depend on Lucide.

| Approach | How | |----------|-----| | icons + component | icons={{ close: CloseIcon }} — pass CloseIcon, not <CloseIcon /> (frontmatter isn’t JSX). | | Named slot | <CloseIcon slot="close-icon" size={20} /> in the template. |

If you pass both a slot and icons for the same control, the slot wins. launcher.iconClass overrides icons.launcher only (string or component).

Custom icons (Astro slots)

Optional named slots replace the icons fallback for that control:

| Slot | Replaces | |------|----------| | launcher-icon | Floating trigger icon (when launcher.mode is icon or both) | | close-icon | Header close button | | send-icon | Send button | | avatar-fallback | Header placeholder when assistantAvatarUrl is missing |

With Bootstrap only, you can still use slots to drop custom markup (e.g. inline SVG). If a slot is empty, the widget uses icons, then the built-in Bootstrap defaults.

Screenshots

Add preview images under assets/ in this package (for example assets/chat-widget.png). Reference them from this README for npm/GitHub, e.g. ![Chat widget](assets/chat-widget.png).

Environment

| Variable | Required | Description | |----------|----------|-------------| | LLM_API_KEY | Yes | Bearer token for the chat API | | LLM_MODEL | Yes | Model id | | LLM_API_BASE_URL | No | Override base URL (no trailing slash); default is xAI |

API route

Create src/pages/api/chat.ts (or .js). Disable prerendering so the route runs on the server:

import type { APIRoute } from 'astro';
import { chatPost, type ChatbotSiteConfig } from 'astro-chat';
import { loadConfig } from '../lib/loadConfig'; // your project

export const prerender = false;

function getEnv(key: string): string | undefined {
  const v = import.meta.env[key];
  return typeof v === 'string' && v.length > 0 ? v : undefined;
}

export const POST: APIRoute = async ({ request }) => {
  return chatPost(request, {
    loadConfig: () => loadConfig() as ChatbotSiteConfig,
    getEnv,
  });
};

Your loaded config must match ChatbotSiteConfig (see astro-chat/types): sections for hero, about, services, process, cta, faq, contact, testimonials, trustIndicators, plus optional chatbot with enabled, businessContext, welcomeMessage.

Widget

In a layout or page:

---
import ChatWidget from 'astro-chat/components/ChatWidget.astro';
import { CHAT_BOOTSTRAP_ICON_DEFAULTS } from 'astro-chat';
import { loadConfig } from '../lib/loadConfig';

const config = loadConfig();

const suggestionQueries = [
  'What services do you offer?',
  'How can I contact you?',
  'How does your process work?',
];
---

{config.chatbot?.enabled && (
  <ChatWidget
    headerLine1="Online"
    headerLine2={config.businessName}
    welcomeMessage={config.chatbot.welcomeMessage ?? 'Hi! How can I help you today?'}
    suggestionQueries={suggestionQueries}
    actionLinks={[
      { title: 'Contact us', url: '#contact-section', primary: true },
      { title: 'FAQ', url: '#faq-section' },
      { title: 'Book a call', url: '/book' },
    ]}
    assistantAvatarUrl={config.images?.logo?.dark ?? config.images?.logo?.light}
    apiPath="/api/chat"
    icons={{
      ...CHAT_BOOTSTRAP_ICON_DEFAULTS,
      launcher: 'bi bi-chat-heart-fill',
    }}
    launcher={{
      mode: 'both',
      text: 'Help',
      button: { borderRadius: '12px' },
      buttonHover: { filter: 'brightness(1.12)' },
    }}
    styles={{
      header: { title: { fontSize: '1.05rem' }, subtitle: { fontSize: '0.7rem' } },
      body: { userMessage: { backgroundColor: '#1e3a5f' } },
    }}
  />
)}

Use camelCase CSS keys in each block (fontSize, backgroundColor, padding, borderRadius, …). Empty strings are ignored when you use helpers like blockToInline yourself; the widget skips empty values when applying styles.

For config-driven suggestion pills (e.g. FAQ questions from your site config), you can still use buildChatbotSuggestionQueries from astro-chat/context instead of a hardcoded array.

Props

| Prop | Description | |------|-------------| | headerLine1 | Small header line (e.g. status: “Online”). | | headerLine2 | Main header title (e.g. business name). | | welcomeMessage | First assistant message when the panel opens. | | suggestionQueries | string[] — quick-send chip labels (shown before link chips). | | actionLinks | Optional { title, url, primary? }[]. Outline chips by default; set primary: true on one link for the accent CTA (e.g. contact). | | assistantAvatarUrl | Optional image URL for the header avatar. | | apiPath | POST endpoint for SSE chat. Default /api/chat. | | class | Extra classes on the root element (merged with astro-chat-root). | | style | Extra root styles (string or object), merged with internal theme CSS variables from styles / launcher. | | styles | Nested partials: header.title, header.subtitle (alias subTitle), body.chatBotContainer, body.messagesArea, body.assistantMessage, body.userMessage (alias userMessageContainer), footer.pills, footer.footerInput, footer.footerSendButton, teaser, launcherWrap. Assistant/user bubbles use CSS variables on the root (any camelCase keys you set are forwarded). | | icons | { launcher?, close?, send?, avatarFallback? } — usually bi bi-* strings (see CHAT_BOOTSTRAP_ICON_* exports). Optional Astro icon components if you add Lucide, etc. launcher.iconClass wins over icons.launcher. | | (slots) | launcher-icon, close-icon, send-icon, avatar-fallback — overrides icons for that control when slot content is present. | | launcher | mode: 'icon' | 'text' | 'both'; text; iconClass (overrides icons.launcher); ariaLabel; button / buttonHover (base + hover, mapped to --astro-chat-launcher-* vars); icon / label inline blocks for the icon and label. |

The default skin still reads your site tokens (--color-accent, --color-primary, --font-body, …). Override via styles, launcher, root style, or global CSS on .astro-chat-root.

apiPath defaults to /api/chat if omitted.

Exports

  • astro-chatchatPost, context builders, validation schema, types
  • astro-chat/apichatPost only
  • astro-chat/contextbuildChatbotSiteKnowledge, buildChatbotSuggestionQueries, buildChatbotSystemPrompt
  • astro-chat/types — config types
  • astro-chat/validationchatRequestSchema
  • astro-chat/chat-widget-stylesresolveChatWidgetAppearance, blockToInline, etc.
  • astro-chat/bootstrap-iconsCHAT_BOOTSTRAP_ICON_DEFAULTS, CHAT_BOOTSTRAP_ICON_SUGGESTIONS
  • astro-chat/components/ChatWidget.astro — UI component

Before publishing (maintainers)

  1. Name — Confirm astro-chat is still available on the registry (npm view astro-chat), or switch to a scoped name (@your-org/astro-chat) and set "name" + "publishConfig.access" accordingly.
  2. Repository — Replace your-org/brick-frontend-templates in package.jsonrepository.url with the real repo; keep "directory": "astro-chat" if this package lives in a monorepo subfolder.
  3. Copyright — Update the year or holder in LICENSE if needed.
  4. Dry runnpm pack --dry-run and skim the file list (only src, components, assets, README.md, LICENSE should ship).
  5. Releasenpm run typecheck (also runs automatically via prepublishOnly), then npm publish.

This package ships TypeScript and .astro sources; consumers need Astro (and a bundler that compiles dependencies, which Astro/Vite does by default).

License

MIT — see LICENSE.