Score every tweet in your feed. Reply with the right strategy. Sound like yourself.
ReplyGuy is a Chrome extension for X. As you scroll, it scores every tweet on freshness, reply gap, and audience match so you can see which ones are worth engaging with. Click the lightning bolt on any scored tweet, pick one of six named engagement strategies, and get three replies written in your voice.
The backend is a small Vercel serverless app you can self-host in about five minutes.
| ReplyGuy | Generic AI reply tool | |
|---|---|---|
| Scores tweets before you reply | Yes | No |
| Named engagement strategies | Yes (6) | No |
| Writes in your voice | Yes (style profile) | Rarely |
| Rate-guard against account flags | Yes (built-in) | Rarely |
| Self-hostable | Yes | Rarely |
| Open source | Yes | No |
graph LR
A[Scroll feed] --> B[Tweets scored 0-100]
B --> C[Click bolt on hot tweet]
C --> D[Pick a strategy]
D --> E[3 replies in your voice]
E --> F{Good enough?}
F -->|Yes| G[Use Reply]
F -->|Refine| H[Plain-English instruction]
H --> E
Score every tweet gets a 0-100 score as you scroll. Green border means high opportunity. Amber means worth a look. Scores are computed with pure math on visible DOM data using requestIdleCallback, so scrolling stays fast.
Generate click the lightning bolt on any scored tweet. Pick a strategy. Get three replies, each one referencing something specific from the original post.
Personalize paste your best tweets once to generate a style profile. Every reply after that matches your tone, vocabulary, and sentence patterns.
| Factor | Weight | What it measures |
|---|---|---|
| Freshness | 35% | Replies in the first 15-30 minutes get 3-5x the visibility |
| Reply gap | 30% | High views + few replies means less competition, more reach |
| ICP match | 20% | How closely the topic matches your target audience keywords |
| Velocity | 15% | How fast the tweet is gaining traction right now |
The top 10 scored tweets from your session appear in the "Hot Tweets" panel in the sidebar.
Each one drives a different kind of engagement.
| Strategy | When to use |
|---|---|
| Contrarian | The take is popular but you have a specific counter-argument |
| Question | You want to extend the conversation, not end it |
| Story | You have a concrete example that connects to the tweet |
| Agree and Amplify | You agree and can add a stronger angle or evidence |
| Hot Take | You have a bold, defensible opinion worth putting out there |
| Insightful | You know something non-obvious: a data point, a framework, a second-order effect |
Built-in limits keep you well under X's automation detection thresholds.
| Window | Warn | Block |
|---|---|---|
| Between replies | Always | 60 seconds minimum |
| 30 minutes | 8 replies | 12 replies |
| 1 hour | 15 replies | 22 replies |
| 24 hours | 35 replies | 55 replies |
If X shows you the "looks like this might be automated" banner, ReplyGuy backs off for 45 minutes automatically.
git clone https://github.com/yourname/replyguy
cd replyguy/extension
npm install
npm run build- Go to
chrome://extensions - Turn on Developer mode
- Click "Load unpacked" and select
extension/dist - Open x.com
The extension uses the hosted backend by default. To use your own:
VITE_API_BASE=https://your-app.vercel.app npm run buildYou need a Vercel account and a NeonDB database. The free tier of both is enough for personal use.
cd backend
vercel --prodSet these environment variables in Vercel:
| Variable | Value |
|---|---|
LLM_BASE_URL |
URL of any OpenAI-compatible endpoint |
LLM_API_KEY |
API key, or not-needed if not required |
DATABASE_URL |
NeonDB connection string |
Initialize the database:
psql $DATABASE_URL -f backend/migrations/001_add_platform_column.sql{
"tweetText": "Learn to sell. Learn to build.",
"tweetAuthor": "naval",
"strategy": "contrarian",
"styleProfile": "Tone: direct, no filler phrases...",
"threadContext": "Previous tweet in the thread..."
}Returns { replies: string[] } with three replies. styleProfile and threadContext are optional.
Strategies: contrarian question story agree-amplify hot-take insightful
Rate limit: 20 req/min per IP.
{
"originalReply": "The hard part is never the idea.",
"instruction": "make it more specific",
"tweetText": "...",
"tweetAuthor": "..."
}Returns { reply: string }. Rate limit: 30 req/min per IP.
{
"bestTweets": "Your tweet 1\nYour tweet 2...",
"icpDescription": "SaaS founders building in public",
"expertise": "Product and growth"
}Returns { profile: string }. Rate limit: 10 req/min per IP.
/api/streak?userId=abc&tz=America/New_York
Returns current streak, longest streak, total replies, and daily counts.
replyguy/
extension/
src/
features/
platforms/ # Platform adapter registry (X adapter)
rate-guard/ # Rolling-window throttle with auto-backoff
search-leads/ # Search query generator for lead finding
content/ # Content script entry point, observer, injector
shell/ # Side sheet (reply flow, hot tweets, settings)
shared/ # API client, scoped chrome.storage utilities
public/
manifest.json
icons/
backend/
api/ # Vercel routes (one-line re-exports)
src/
reply/ # Generate and tailor handlers
tracking/ # Reply events and streak data
profile/ # Style profile generation
shared/ # Middleware, LLM client, rate limiter
migrations/
# Extension: watch mode
cd extension && npm run dev
# Backend: local serverless
cd backend && vercel devThe extension builds to extension/dist. Load that folder as an unpacked extension in Chrome and reload after each build.
Extension: Chrome MV3, TypeScript, Preact, Vite, Shadow DOM
Backend: Vercel Serverless, Node.js, TypeScript, Zod, NeonDB
Scoring: Pure DOM reads, zero API calls, requestIdleCallback scheduling
Open an issue before starting significant work. Small fixes are welcome directly as pull requests.
MIT