We've all seen those chatbot widgets on websites.
Whether it's customer support, FAQs, AI assistants, or lead generation, almost every modern website has one.
The problem?
Integrating a chatbot is usually more complicated than it should be.
- You have to create floating widgets.
- Handle UI and animations.
- Manage sessions.
- Make it responsive.
- Configure themes.
- Connect it with your backend.
I wanted something much simpler.
So I built @hey-amanthakur/chat-bot.
Why I Built It
While working on projects, I repeatedly found myself rebuilding the same chatbot UI.
Every project required:
Floating launcher button
Chat window
Message rendering
Responsive design
Theme customization
Backend integration
Instead of copying code between projects, I decided to package everything into a reusable npm library.
β¨ Features
- π Plug-and-play integration
- π¨ Fully customizable appearance
- π± Mobile responsive out of the box
- β‘ Lightweight with minimal setup
- π Connect to any backend or AI model
- π§© Works with React, Next.js, Vue or Vanilla JavaScript
- π¬ Floating chat widget with modern UI
- π Theme support
- π¦ Install from npm in seconds
- π οΈ Developer-friendly API π― Production-ready
Most "AI chatbot" products for small businesses are SaaS platforms: sign up, wait for approval, pay monthly, get locked into their dashboard. I wanted something a developer could just npm install, point at a business's info, and drop into a client's website the same afternoon.
So I built @hey-amanthakur/chat-bot β an embeddable chatbot widget + backend that answers questions using only a business's own services, hours, and FAQs. No database, no dashboard, no vendor lock-in.
The problem
If you build websites for local businesses (dentists, salons, clinics, studios), you've probably been asked for a "chat with us" feature. Your options are usually:
- A generic support-widget SaaS that costs $30-100/mo and doesn't know anything about the business
- Building a custom bot from scratch with a vector DB, embeddings, and a whole backend
- Ignoring it and hoping the contact form is enough
I wanted a middle path: a small server you run yourself (or deploy anywhere), configured with plain JS objects, that any client site can embed with a single
<script>tag.
Quick start
Install it:
npm install @hey-amanthakur/chat-bot
Configure and start the server:
import { ChatBot } from '@hey-amanthakur/chat-bot';
ChatBot.start({
port: 3000,
openrouterKey: 'sk-or-v1-xxxxx',
clients: {
'my-business': {
name: 'My Business',
greeting: 'Hi! How can I help you today?',
services: [
{ name: 'Consultation', price: '$50', description: 'Initial consultation' },
],
hours: [
{ day: 'Monday', open: '9:00 AM', close: '5:00 PM' },
],
faqs: [
{ question: 'Do you accept insurance?', answer: 'Yes, we accept most major plans.' },
],
},
},
});
Drop the widget into the client's HTML:
<script
src="http://localhost:3000/widgets/chat-widget.min.js"
data-client-id="my-business"
data-color="#2563eb"
data-icon="π¦·"
data-header="Talk to us"
data-position="bottom-right"
></script>
That's it β a styled chat bubble shows up, and visitors can ask about pricing, hours, or anything in the FAQ.
Why OpenRouter instead of hardcoding OpenAI
The bot uses OpenRouter under the hood, which means you're not locked into one model. Swap model: 'openai/gpt-4o' for any supported model per client β some clients might be fine on a free/cheap model, others might want something stronger.
Multiple clients on one server
This was important for my use case: I build sites for multiple small businesses, and I didn't want to spin up a separate server for each one. One ChatBot.start() call can serve several clients, each with its own isolated knowledge base and chat context:
ChatBot.start({
port: 3000,
openrouterKey: 'sk-or-v1-xxxxx',
clients: {
'dr-smith-dental': {
name: 'Dr. Smith Dental',
model: 'openai/gpt-4o',
services: [{ name: 'Teeth Cleaning', price: '$120', description: 'Professional cleaning' }],
},
'style-studio-salon': {
name: 'Style Studio Salon',
services: [{ name: 'Haircut', price: '$45', description: 'Professional haircut' }],
},
},
});
Each site just points its widget script at its own data-client-id, and the bot only ever answers using that client's data β it won't leak Dr. Smith's pricing into Style Studio's chat window.
How a message actually flows
- Widget loads β chat bubble renders on the page
- Visitor types a message β
POST /api/chatwithclientId+ message - Server loads that client's config (in-memory, no DB)
- A lightweight lead-detection check runs on the message
- If it looks like a lead (someone asking to book, get a quote, etc.) β the bot nudges toward contact info
- Otherwise β the message goes to OpenRouter along with the client's services/hours/FAQs as context
- The model replies using only that context
- Response renders in the widget with basic formatting ## Security basics, out of the box
Since this thing is meant to be embedded on real client sites, I didn't want to ship it without the obvious guardrails:
- The OpenRouter API key never reaches the browser β it stays server-side
- Rate limiting on every endpoint (20/min for chat, 10/min for lead submission)
- Input validation β 2000 char cap per message, 10KB body limit
- Configurable CORS per deployment via
allowedOrigins## Customizing the widget
The widget itself is just data-* attributes, so you can reskin it per client without touching code:
| Attribute | Default | What it does |
|---|---|---|
data-color |
#2563eb |
Bubble, header, and user message color |
data-icon |
chat bubble SVG | Emoji, image URL, or raw SVG string |
data-header |
Chat with us |
Header title |
data-position |
bottom-right |
Any corner of the screen |
data-greeting |
β | Overrides the configured greeting |
If you'd rather not use a script tag (say, in a React or Vue app), there's also an ES module version:
import ChatWidget from '@hey-amanthakur/chat-bot/widget.esm';
new ChatWidget({
clientId: 'my-business',
apiUrl: 'http://localhost:3000',
primaryColor: '#e11d48',
icon: 'π¬',
headerTitle: 'Support Chat',
position: 'top-right',
});
Tech stack
- Server: NestJS
- Widget: Vanilla TypeScript, bundled with Rollup (no framework dependency for the embed)
- LLM: OpenRouter (model-agnostic)
- Build: Turborepo monorepo
- Tests: 73 unit tests + 15 E2E tests ## Try it
npm install @hey-amanthakur/chat-bot
- π¦ npm package
- π GitHub repo
- π MIT licensed If you build sites for small/local businesses and want a chatbot you can actually own instead of renting from a SaaS, give it a try. Issues, stars, and feedback are all very welcome β this is still early, and I'd love to know what you build with it.
Top comments (0)