Too loud?

Keyboard shortcuts

Anywhere on the site, while you are not typing.

M
Sounds on or off
E
Copy my email
T
Day or night
S
Change the season
D
Developer mode
?
These shortcuts
Esc
Close what is open

  • side project
  • 2024 to 2025
  • npm package
  • React
  • Solo

10xAnswers is a React chat widget you drop into a site: pass it a persona prompt and a backend URL, and it answers questions about you or your product.

I built it alone and published it to npm, where it has 12,493 downloads across 55 releases. It renders markdown with highlighted code, lets you edit a question, and is themed through about 20 CSS variables, while a hosted Express proxy keeps the model key on the server.

The 10xAnswers playground: install, customize and see the chat component in action.
npm i 10xanswers
The configurator beside the live widget answering a question with highlighted code.
configure it, ask it
The 10xanswers package page on npm, with its versions and weekly downloads.
on npm
Type
side project
Role
Solo
When
Dec 2024 to May 2025, maintained since
Stack
React, Recoil, Vite, Express, Gemini
Links
10x-answers.vercel.appnpm

What I built

  • The component

    A draggable React chat widget: markdown, highlighted code, editable questions, themed with about 20 CSS variables.

  • Published on npm

    12,493 downloads across 55 releases, as ES and UMD builds behind an exports map.

    How it works
  • The hosted proxy

    The model key stays on the server; input validated, size capped, clean 400, 413, 429 and 502 answers.

    How it works
  • A playground that writes the code

    A 15-field configurator that turns your choices into the snippet to paste.

  • A TypeScript port

    For Plura AI as plura-chatbot, where I'm the largest contributor.

How it fits together

Your siteany React app<ChatBot />npm i 10xanswersHosted proxyExpress · validatesGeminiflash-lite-latestpersona + URLkey stays heredirect mode, your keyanswers: 200 · 400 · 413 · 429 · 502
The key stays on a server: the widget talks to a small proxy that checks the request, caps it, and answers with a plain status code.

Kept alive

In September 2026 I found that a junk dependency had made the published package uninstallable for everyone, and shipped 1.1.17 to fix it.

The hosted backend was calling a retired model. It now uses an always-current alias and answers like an API: 400 for a malformed request, 413 over the prompt cap, 429 when the model is rate limited, 502 when it fails.

10xAnswers-BE · api/index.js

app.post("/", async (req, res) => {  const prompt = req.body?.contents?.[0]?.parts?.[0]?.text  if (typeof prompt !== "string" || !prompt.trim()) {    return res.status(400).json({ message: /* shape */ })  }  if (prompt.length > MAX_PROMPT_CHARS) {    return res.status(413).json({ message: /* limit */ })  }  try {    // History arrives inside the prompt from the client,    // so this function stays stateless and conversations    // from different sites never mix.    const result = await model.generateContent(prompt)    const text = result.response.text()    res.json({      candidates: [{ content: { parts: [{ text }] } }],    })  } catch (err) {    const status = err?.status === 429 ? 429 : 502    res.status(status).json({ message: /* try again */ })  }})
Stateless on purpose: history travels with each question, so two sites using the same backend never share a conversation.

On npm

12,493 downloads so far, across 55 releases.

0

downloads, all time

55

releases

5,874

last year

1

advisory

The advisory is mine too. Recoil 0.7.7 breaks on React 19 internals, so the readme says so, with the downgrade path.

The npm counter: it counts once, on first sight, then holds.

Next. Version 2: streaming, React 19, provider adapters and a voice mode, as the interface of an agent on this site.