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

rushchatbot

v1.7.6

Published

**Version:** 1.7.6

Readme

RushChatbot

Version: 1.7.6

Embeddable hybrid chatbot plugin that combines a click-based FAQ tree with a free-text query engine backed by n8n. Ships as an npm package with a Node.js/Express server and widgets for React, Vue 3, and Vanilla JS.

Features:

  • Click-based FAQ question tree with subquestions
  • Fuzzy + keyword matching against your config
  • n8n webhook fallback for unmatched queries
  • Markdown rendering (bold, lists, headings)
  • Multi-bubble paragraph responses
  • Draggable floating chat button
  • Tagalog (TL) language support
  • Input validation and profanity guardrails
  • Session-based analytics

Table of Contents

  1. Requirements
  2. Installation
  3. Scaffold Config Files
  4. Configure the Chatbot
  5. Build the FAQ Tree
  6. Start the Server
  7. Embed the Widget
  8. Floating Button Behavior
  9. n8n Webhook Setup
  10. n8n Response Formats
  11. Environment Variables
  12. API Reference
  13. Analytics
  14. Troubleshooting

1. Requirements

| Requirement | Version | |---|---| | Node.js | >= 18.0.0 | | npm | >= 9.0.0 | | React (for React widget) | >= 18.0.0 | | Vue (for Vue 3 widget) | >= 3.0.0 | | Vue (for Vue 2 widget) | >= 2.5.17 | | n8n instance | Any hosted or self-hosted |


2. Installation

npm install rushchatbot

3. Scaffold Config Files

Run the init command to generate the required config and questions files in a directory of your choice:

npx rushchatbot init ./chatbot

This creates three files:

chatbot/
├── chatbot.config.json     ← branding, n8n, chat settings
├── questions.json          ← English FAQ tree
└── questions.tl.json       ← Tagalog FAQ tree (optional)

4. Configure the Chatbot

Edit chatbot.config.json with your settings:

{
  "branding": {
    "title": "My Support Bot",
    "subtitle": "How can we help you today?",
    "theme": {
      "primaryColor": "#4F46E5",
      "backgroundColor": "#FFFFFF",
      "userBubbleColor": "#4F46E5",
      "botBubbleColor": "#F3F4F6",
      "textColor": "#111827",
      "fontFamily": "Inter, sans-serif"
    }
  },
  "n8n": {
    "webhookUrl": "https://your-n8n.com/webhook/your-webhook-id",
    "timeoutMs": 55000
  },
  "chat": {
    "welcomeMessage": "Hi! Choose a question below or type your own.",
    "fallbackMessage": "Let me look that up for you...",
    "matchThreshold": 0.4,
    "showPreQuestionsOnStart": true,
    "language": "en",
    "window": {
      "width": 360,
      "height": null
    }
  }
}

Config field reference

| Field | Type | Default | Description | |---|---|---|---| | branding.title | string | — | Chat header title | | branding.subtitle | string | — | Chat header subtitle | | branding.theme.primaryColor | string | #4F46E5 | Header, buttons, user bubble color | | branding.theme.backgroundColor | string | #FFFFFF | Chat window background | | branding.theme.userBubbleColor | string | #4F46E5 | User message bubble color | | branding.theme.botBubbleColor | string | #F3F4F6 | Bot message bubble color | | branding.theme.textColor | string | #111827 | Main text color | | branding.theme.fontFamily | string | Inter, sans-serif | Font stack | | n8n.webhookUrl | string | — | Your n8n POST webhook URL | | n8n.timeoutMs | number | 55000 | n8n request timeout in milliseconds | | chat.welcomeMessage | string | — | First message shown when chat opens | | chat.fallbackMessage | string | — | Shown when an error occurs | | chat.matchThreshold | number | 0.4 | Fuzzy match sensitivity (0–1). Lower = stricter | | chat.showPreQuestionsOnStart | boolean | true | Show FAQ buttons when chat opens | | chat.language | "en" | "tl" | "en" | Language for displaying FAQ questions | | chat.window.width | number | 360 | Desktop chat window width in pixels. Omit or set null to use responsive default (min(360, vw-48)) | | chat.window.height | number | null | Desktop chat window height in pixels. Omit or set null to use responsive default (70vh) |


6. Build the FAQ Tree

Edit questions.json to define your FAQ categories and answers. The structure supports two levels: main questions and subquestions.

[
  {
    "id": "q1",
    "question": "About Our Company",
    "answer": "We are a company that...",
    "subquestions": [
      {
        "id": "q1a",
        "question": "When was the company founded?",
        "answer": "We were founded in 2010.",
        "subquestions": []
      },
      {
        "id": "q1b",
        "question": "What is your mission?",
        "answer": "Our mission is to...",
        "subquestions": []
      }
    ]
  },
  {
    "id": "q2",
    "question": "Contact Information",
    "answer": "You can reach us at [email protected].",
    "subquestions": []
  }
]

Rules

  • Every question must have a unique id
  • subquestions must be an array (use [] if none)
  • answer is shown when the question is clicked directly or matched via text search
  • For Tagalog support, mirror the same structure in questions.tl.json with translated text — keep the same id values

6. Start the Server

Create a server entry file (e.g. server.js or server.ts):

import { createServer } from 'rushchatbot/server'
import path from 'path'

createServer({
  configPath: path.resolve('./chatbot/chatbot.config.json'),
  questionsPath: path.resolve('./chatbot/questions.json'),
  questionsTagalogPath: path.resolve('./chatbot/questions.tl.json'), // optional
  port: 3001,
  corsOrigin: 'https://your-frontend-domain.com', // or '*' for development
}).listen()

Server options

| Option | Type | Default | Description | |---|---|---|---| | configPath | string | — | Required. Absolute path to chatbot.config.json | | questionsPath | string | — | Required. Absolute path to questions.json | | questionsTagalogPath | string | — | Optional. Absolute path to questions.tl.json | | port | number | 3001 | Port to listen on | | corsOrigin | string | string[] | * | Allowed CORS origin(s) |

Start the server:

node server.js

On successful startup you will see:

[RushChatbot] Server running on http://localhost:3001

7. Embed the Widget

RushChatbot ships three separate widget builds. Use the one that matches your frontend stack.


React

Install peer dependencies if not already present:

npm install react react-dom marked

Import and render the widget:

import { ChatWidget } from 'rushchatbot/client'

export default function App() {
  return (
    <div>
      <ChatWidget apiBase="http://localhost:3001/api/chat" />
    </div>
  )
}

The widget renders as a floating draggable button fixed to the bottom-right of the screen. Clicking it opens the chat box above the button.

React widget props

| Prop | Type | Default | Description | |---|---|---|---| | apiBase | string | http://localhost:3001/api/chat | Base URL of the RushChatbot server | | width | number | from config | Chat box width in pixels (desktop only) | | height | number | from config | Chat box height in pixels (desktop only) |


Vue 2

Install peer dependency if not already present:

npm install vue@2

Register and use the component:

<script>
import ChatWidget from 'rushchatbot/vue2'

export default {
  components: { ChatWidget }
}
</script>

<template>
  <ChatWidget api-base="http://localhost:3001/api/chat" />
</template>

Or register it globally in main.js:

import Vue from 'vue'
import App from './App.vue'
import ChatWidget from 'rushchatbot/vue2'

Vue.component('RushChatbot', ChatWidget)
new Vue({ render: h => h(App) }).$mount('#app')

Then use it anywhere:

<template>
  <RushChatbot api-base="http://localhost:3001/api/chat" />
</template>

Vue 2 widget props

| Prop | Type | Default | Description | |---|---|---|---| | api-base | string | http://localhost:3001/api/chat | Base URL of the RushChatbot server | | width | number | — | Chat box width in pixels (omit for fluid) | | height | number | — | Chat box height in pixels (omit for fluid) | | primary-color | string | from config | Override primary/accent color | | bg-color | string | from config | Override background color | | border-radius | number | 16 | Container corner radius in pixels | | show-shadow | boolean | true | Show/hide box shadow | | placeholder | string | Type a message... | Input placeholder text | | send-label | string | Send | Send button label | | hide-input | boolean | false | Hide the text input bar | | hide-end-chat | boolean | false | Hide the "I'm done" end chat button |


Vue 3

Install peer dependency if not already present:

npm install vue

Register and use the component:

<script setup>
import ChatWidget from 'rushchatbot/vue'
</script>

<template>
  <ChatWidget api-base="http://localhost:3001/api/chat" />
</template>

Or register it globally in main.ts:

import { createApp } from 'vue'
import App from './App.vue'
import ChatWidget from 'rushchatbot/vue'

const app = createApp(App)
app.component('RushChatbot', ChatWidget)
app.mount('#app')

Then use it anywhere:

<template>
  <RushChatbot api-base="http://localhost:3001/api/chat" />
</template>

Vue widget props

| Prop | Type | Default | Description | |---|---|---|---| | api-base | string | http://localhost:3001/api/chat | Base URL of the RushChatbot server | | width | number | — | Chat box width in pixels (omit for fluid) | | height | number | — | Chat box height in pixels (omit for fluid) | | primary-color | string | from config | Override primary/accent color | | bg-color | string | from config | Override background color | | border-radius | number | 16 | Container corner radius in pixels | | show-shadow | boolean | true | Show/hide box shadow | | placeholder | string | Type a message... | Input placeholder text | | send-label | string | Send | Send button label | | hide-input | boolean | false | Hide the text input bar | | hide-end-chat | boolean | false | Hide the "I'm done" end chat button |


Vanilla JS (Web Component)

No framework required. The Vanilla build registers a <rush-chatbot> custom element using the Web Components API with Shadow DOM.

Via npm

import 'rushchatbot/vanilla'

Then add the element anywhere in your HTML:

<rush-chatbot api-base="http://localhost:3001/api/chat"></rush-chatbot>

Via CDN / script tag

<script type="module" src="/path/to/rushchatbot/dist/vanilla.es.js"></script>
<!-- or IIFE build for non-module environments -->
<script src="/path/to/rushchatbot/dist/vanilla.iife.js"></script>

<rush-chatbot api-base="http://localhost:3001/api/chat"></rush-chatbot>

Web Component attributes

| Attribute | Type | Default | Description | |---|---|---|---| | api-base | string | http://localhost:3001/api/chat | Base URL of the RushChatbot server | | width | number | — | Chat box width in pixels (omit for fluid) | | height | number | — | Chat box height in pixels (omit for fluid) | | primary-color | string | from config | Override primary/accent color | | bg-color | string | from config | Override background color | | border-radius | number | 16 | Container corner radius in pixels | | show-shadow | boolean | true | Show/hide box shadow | | placeholder | string | Type a message... | Input placeholder text | | send-label | string | Send | Send button label | | hide-input | boolean | false | Hide the text input bar | | hide-end-chat | boolean | false | Hide the "I'm done" end chat button | | auto-open | boolean | false | Auto-open chat on load | | position | bottom-right\|bottom-left | bottom-right | Floating button position |

Attributes can be updated at runtime and the widget will reflect the changes:

document.querySelector('rush-chatbot').setAttribute('api-base', 'https://my-server.com/api/chat')

8. Floating Button Behavior

The chat button is draggable across the entire screen:

  • Drag — click and hold, then move to reposition the button anywhere on screen
  • Click (no drag) — toggles the chat box open or closed
  • Chat box position — always appears directly above the button, clamped to the viewport so it never goes off-screen
  • Close — click the ✕ button inside the chat header, or click the floating button again
  • Works on both desktop (mouse) and mobile (touch)

9. n8n Webhook Setup

When a user types a query that doesn't match any FAQ answer, RushChatbot forwards it to your n8n webhook.

What RushChatbot sends to n8n

{
  "query": "the user's message",
  "sessionId": "sess_abc123"
}

Headers sent:

Content-Type: application/json
x-session-id: sess_abc123

Setting up the webhook in n8n

  1. Create a new workflow in n8n
  2. Add a Webhook trigger node — set method to POST
  3. Copy the webhook URL into chatbot.config.json under n8n.webhookUrl
  4. Add your AI/logic nodes after the webhook trigger
  5. End with a Respond to Webhook node returning one of the supported response formats (see section 11)
  6. Activate the workflow

Session continuity

The sessionId is generated per browser tab (sess_ + timestamp + random suffix). Pass it through your n8n workflow to maintain conversation context with your AI agent.


10. n8n Response Formats

RushChatbot automatically parses all of the following response shapes from n8n:

Single answer

[{ "output": "Your answer text here" }]
[{ "answer": "Your answer text here" }]
[{ "text": "Your answer text here" }]

Multiple bubbles (paragraphs)

Return a paragraphs array to render each item as a separate chat bubble with a short delay between them:

[{
  "paragraphs": [
    "First part of the response.",
    "Second part with **bold** and lists.",
    "Third bubble with a follow-up question."
  ]
}]

Markdown support

All responses are rendered as Markdown. Supported formatting:

| Syntax | Renders as | |---|---| | **bold** | bold | | # Heading | Large heading | | - item | Bullet list | | 1. item | Numbered list | | [link](url) | Hyperlink | | \n (newline) | Line break |


11. Environment Variables

| Variable | Required | Description | |---|---|---| | PORT | No | Override the server port (default: 3001) |

Setting the port

PORT=4000 node server.js

12. API Reference

All endpoints are mounted under /api/chat.

GET /api/chat/config

Returns branding and chat settings. Safe to call from the frontend — never exposes n8n credentials or license key.

Response:

{
  "branding": { "title": "...", "subtitle": "...", "theme": { } },
  "chat": { "welcomeMessage": "...", "language": "en", "window": { "width": 360, "height": null } }
}

GET /api/chat/questions

Returns the FAQ question tree in the configured language.

Response:

[
  {
    "id": "q1",
    "question": "About Our Company",
    "answer": "...",
    "subquestions": []
  }
]

GET /api/chat/query?query=your+question&sessionId=sess_abc

Forwards the query directly to n8n, bypassing FAQ matching. Useful for testing your n8n workflow from the browser.

Query params:

| Param | Required | Description | |---|---|---| | query | Yes | The user's question | | sessionId | No | Session identifier |

Response:

{ "answer": "...", "source": "n8n" }

or

{ "paragraphs": ["...", "..."], "source": "n8n" }

POST /api/chat/query

Main query endpoint. Runs the full pipeline: input validation → guardrails → FAQ matching → n8n fallback.

Request body:

{
  "query": "How do I apply for membership?",
  "sessionId": "sess_abc123"
}

Response (FAQ match):

{
  "answer": "You can apply by...",
  "source": "config",
  "matchedQuestion": "How do I apply for membership?",
  "matchedKeywords": ["apply", "membership"],
  "score": 87
}

Response (n8n fallback):

{ "answer": "...", "source": "n8n" }

Response (validation/guardrail blocked):

{ "answer": "Please rephrase your question...", "source": "validation" }

POST /api/chat/click

Tracks when a user clicks a pre-built FAQ question.

Request body:

{
  "questionId": "q1a",
  "sessionId": "sess_abc123"
}

Response:

{ "ok": true }

GET /api/chat/analytics

Returns the full analytics log.

Response:

[
  {
    "sessionId": "sess_abc123",
    "questionId": "q1a",
    "timestamp": "2025-01-01T10:00:00.000Z",
    "type": "click"
  }
]

Analytics types:

| Type | Description | |---|---| | click | User clicked a pre-built FAQ question | | match | User query matched a FAQ answer | | n8n | Query was forwarded to n8n | | error | Validation, guardrail, or server error |


13. Analytics

Analytics are written to analytics.json in the same directory as your chatbot.config.json. Each entry records:

  • sessionId — browser session (resets on new tab)
  • questionId — the matched question ID, or n8n / error / guardrail
  • timestamp — ISO 8601 UTC
  • type — click, match, n8n, or error

You can query the log at any time via GET /api/chat/analytics or read the file directly.


14. Troubleshooting

[RushChatbot] configPath not found

  • Use path.resolve() to ensure the path is absolute
  • Verify the file exists at the specified location

Chat widget shows nothing / blank

  • Check the browser console for CORS errors
  • Ensure corsOrigin in createServer() includes your frontend's origin
  • Confirm the server is running and reachable at the apiBase URL

n8n not responding / timeout

  • Increase n8n.timeoutMs in chatbot.config.json (default is 55000ms)
  • Test the webhook directly: GET http://localhost:3001/api/chat/query?query=hello
  • Check your n8n workflow is activated (not just saved)

Port already in use

kill $(lsof -ti :3001)

Queries always fall through to n8n (no FAQ matches)

  • Lower chat.matchThreshold in config (e.g. 0.3)
  • Ensure your questions.json answers contain keywords that appear in user queries
  • Check that question id values are unique across the entire tree