Open-source project
diwenne/openreply avatar
diwenne/openreply

OpenReply: a self-hosted ManyChat alternative for Instagram comment-to-DM

The open-source Manychat alternative

2,321 stars886 forksTypeScriptMIT

At a glance

What is it?
OpenReply turns a keyword comment on an Instagram post, reel or Story into a private reply, running on your own Postgres, Redis and worker. It is MIT-licensed software, not a service, and the setup cost is real.
Who is it for?
Adopt OpenReply if you already run Postgres, Redis and a long-lived Node process, or if you run comment-to-DM campaigns for clients and want the queue, logs and inbox in your own database. Do not adopt it if you want a sign-up link: openreply.diwen.dev is a dashboard demo, and no account there will send a DM.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 17, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The subscription OpenReply removes, and who ends up paying it instead

Comment-to-DM is a narrow feature. A commenter types a keyword, and a bot sends them the link in a private message. Most tools that offer it bundle it into a monthly plan. OpenReply's README states the motivation plainly: the workflow should be software you can inspect, modify and host yourself. The repository is MIT-licensed and the dashboard is a Next.js app, so the feature is not the product.

The audience is specific. You are running campaigns on Instagram professional accounts, you already have somewhere to run a Node process and a database, and you would rather own the queue and the logs than rent them. The multi-account and workspace features (owner, admin, member roles with invite links) suggest agencies running this for clients. If you are a solo creator with no server, the trade is different: you replace a subscription with a deployment you have to keep alive.

The README is direct about the boundary. OpenReply is built on Meta's official Instagram private replies. It does not scrape, it does not automate a browser, and it never asks for an Instagram password. Instagram's policies, permissions, messaging windows and rate limits still apply. That sentence is the honest scope of the project.

Webhook in, queue out: how the two processes divide the work

The architecture is two processes against one Postgres and one Redis. The web app receives the webhook and serves the dashboard. A separate worker does the sending. The README gives the reason: the send has to survive rate limits and retries, so it cannot live inside a request handler.

The flow is short. A comment, DM or Story reply arrives at your instance through a connection provider, either your own Meta app or Zernio. OpenReply checks the text against your active campaigns. On a match it queues a job. The worker sends the private reply, and the public reply if you enabled one.

BullMQ and ioredis are in the dependency list, which is the queue layer, and Prisma with the pg adapter is the database layer. The worker entry point is worker/dm-worker.ts, run through tsx. That detail matters for deployment: the Dockerfile comments say the worker runs raw TypeScript, not a bundled output, so it needs the generated Prisma client, the source tree under lib/ and worker/, and tsconfig.json for the @/* path alias. The same file notes that stripping node_modules or tsconfig.json out of the final image is what breaks the worker with MODULE_NOT_FOUND.

Rate limiting is per account. The README says OpenReply stays under Meta's documented cap of 750 private replies per hour and queues the overflow rather than dropping it. That is a design choice with a visible consequence: a burst of comments produces a backlog, not an error, so the dashboard has to show you the backlog.

Running OpenReply locally: two terminals, Postgres and Redis

The README's local path assumes Docker for the backing services and Node for the app. Clone, install, copy the environment file, then start Postgres and Redis with the compose file in the repository root.

bash
git clone https://github.com/diwenne/openreply.git
cd openreply
npm install
cp .env.example .env      # then fill in the values, see docs/setup.md
docker-compose up -d      # starts Postgres and Redis

The compose file defines postgres:16 on port 5432 with database openreply, user postgres and password postgres, and redis:7-alpine on port 6379. Both have healthchecks. Then generate the Prisma client and apply migrations, and start the two processes in separate terminals.

bash
npm run db:generate
npm run db:migrate
npm run dev               # web app on http://localhost:3000
npm run worker            # in a second terminal, this sends the DMs

The README is explicit that this is always two processes, and that if comments arrive and no DM does, the worker is the first thing to check. Before any of it works you have to fill in .env: NEXTAUTH_URL, NEXTAUTH_SECRET, CRON_SECRET and an ENCRYPTION_KEY, the DATABASE_URL and REDIS_URL, email settings for magic-link sign-in, and the Meta values META_GRAPH_API_VERSION, INSTAGRAM_APP_ID, INSTAGRAM_APP_SECRET, FACEBOOK_APP_SECRET and WEBHOOK_VERIFY_TOKEN. The example file also documents ALLOWED_EMAILS, which restricts who can request a magic link. Without it, anyone who reaches your public URL gets their own workspace. Set it.

The first real use is a campaign: connect an Instagram Business or Creator account in Settings, create a campaign with a keyword, and test a keyword comment from another account. The README recommends testing from a second account rather than your own, and it also filters self-comments, since Meta rejects DMing yourself.

The follow gate fails open, and other places OpenReply will not save you

The follow gate is the most interesting feature and the best place to see the project's judgment. If you enable it, the DM asks the commenter to follow and tap a button. On tap, OpenReply checks Meta's is_user_follow_business flag and only sends the link once they follow, re-prompting until then. The README states it fails open, sending the link anyway, when Instagram does not return follow status, so a real follower is never trapped. That is the right call for a marketing tool, and it also means the gate is not a guarantee. Anyone who can produce a missing follow status gets the link.

The harder limits come from Meta, not from OpenReply. Private replies are subject to messaging windows, permissions and rate limits. The inbox reads and replies inside Meta's 24-hour messaging window, so a conversation older than that is not something the dashboard can rescue. Story replies are handled as DMs, which is why the DM trigger covers them, and the README notes that if you use your own Meta app you must subscribe to the messages webhook field for that to work. Zernio registers webhooks automatically.

Deployment has its own failure mode. The Dockerfile notes that nothing runs the /api/cron routes off Vercel, so a non-Vercel deployment needs the cron container, which calls those routes with wget. The image installs wget for exactly that reason. A deployment that skips the scheduler will look healthy and quietly stop doing scheduled work.

OpenReply is also the wrong tool if your Instagram account is not professional. Private replies come from the official API, and the README asks for an Instagram Business or Creator account. And if you wanted a hosted product, this is not one: the README says openreply.diwen.dev is a demo of the dashboard, that creating an account there will never send a DM, and that there is no hosted plan to upgrade to.

ManyChat versus OpenReply: the difference is who operates the queue

ManyChat is the obvious comparison, and the README frames the project as an open-source alternative to it. The difference is not the feature list, it is the operational model. ManyChat is a hosted service: you sign up, connect an account and pay a recurring fee, and the vendor runs the workers, the queue and the message log. OpenReply is the same workflow as software you deploy, which means you own the Postgres rows, the BullMQ queue in Redis, and the DM logs, and you also own the pager when the worker dies.

That trade shows up in small places. OpenReply's README lists no seat limits and no plan caps, because there is no plan. Hosting and optional provider costs are separate. A ManyChat plan bundles support and uptime; a self-hosted instance bundles neither.

There is a second path inside OpenReply that is worth naming because it changes the comparison. You can connect Instagram through Zernio, a paid provider that the README describes as a sponsor and an optional way to avoid creating and reviewing your own Meta app. OpenReply still runs your campaigns, queues, logs and inbox on your infrastructure. So the honest picture is: ManyChat is one vendor for everything, while OpenReply is your infrastructure plus either your own Meta app review or a paid connection provider. The README says to check Zernio's feature limits before choosing, which implies the provider path is not feature-identical to the direct Meta path.

Maintenance, upgrades and what the MIT licence does and does not cover

The repository is not archived, and the last push was on 2026-09-14. That is recent, but there are no releases retrieved for this project, and package.json still carries version 0.1.0. Treat it as software you track from the main branch rather than from tagged versions. There is no documented upgrade path in the README beyond npm run db:migrate, and the README does not document rollback, so a migration you apply is one you should be prepared to reason about yourself.

Upgrade cost is mostly the worker contract. The Dockerfile explains that the worker runs raw TypeScript and depends on the Prisma client, the lib/ and worker/ source trees, and tsconfig.json for the @/* alias. Any change to that layout, or a decision to try a slimmer standalone image, breaks the send path rather than the dashboard. Next.js 16, React 19 and Prisma 7 are all major-version dependencies, so a routine dependency bump is a real piece of work, not a patch.

Licensing is MIT, which permits commercial use, modification and self-hosting. The README points out that hosting and optional provider costs are separate, so the licence does not make the running of it free. This is not legal advice, and the parts that are not MIT are the third-party services you connect: Meta's platform terms and Zernio's terms govern those relationships, not the repository's LICENSE file.

Editorial conclusion

Adopt OpenReply if you already run Postgres, Redis and a long-lived Node process, or if you run comment-to-DM campaigns for clients and want the queue, logs and inbox in your own database. Do not adopt it if you want a sign-up link: openreply.diwen.dev is a dashboard demo, and no account there will send a DM. Before you commit, confirm three things: that you can keep a worker process always on, that you have an Instagram Business or Creator account plus either a Meta app of your own or a Zernio connection, and that your commenters accept Meta's private-reply rules, because OpenReply does not bypass them.

Frequently asked questions

How do I install OpenReply?

Clone the repository, run npm install, copy .env.example to .env and fill in the values, then start Postgres and Redis with docker-compose up -d. Run npm run db:generate and npm run db:migrate, then keep two processes running: npm run dev for the app and npm run worker for the DMs. The README points to docs/setup.md for the full walkthrough.

How much does OpenReply cost?

The software is free and MIT-licensed, with no seat limits or plan caps. The README states that hosting and optional provider costs are separate, so you pay for your own infrastructure and for Zernio if you choose that connection path instead of your own Meta app.

Is OpenReply open-source?

Yes. The repository is MIT-licensed, and the README describes it as free software running on your own infrastructure. It is not a session-replay tool; it handles Instagram comment-to-DM automation through Meta's official private replies.

Official sources

  1. diwenne/openreply on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes