# raganork-md: a multi-session WhatsApp bot framework built on Baileys

> raganork-md is a Node.js framework for running WhatsApp bots on Baileys, with comma-separated session strings, a plugins folder and PM2 process control. It is aimed at self-hosters who accept that the library talks to an unofficial WhatsApp Web API and can get the account behind it banned.

**souravkl11/raganork-md** — A light-weight multi-functional WhatsApp bot framework.

- Repository: https://github.com/souravkl11/raganork-md
- Website: https://raganork.site
- Stars: 1,144 · Forks: 2,197
- Language: JavaScript
- License: GPL-3.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/souravkl11-raganork-md

## What raganork-md is for and who runs it

raganork-md is a Node.js framework for running WhatsApp bots on top of the Baileys library. The README describes it as "A lightweight WhatsApp bot framework with multi-session support and extensive configuration options" and frames it as a complete rewrite of the original Raganork project.

The problem it addresses is operational rather than algorithmic. It exists so that one or more WhatsApp identities stay connected to a server, so that new commands can be added without touching the core, and so that the whole thing can be restarted by a process manager on a machine that may be a VPS or a small cloud container.

The audience is a self-hoster, not an enterprise buyer. There is no hosted tier, no dashboard and no multi-tenant model in the repository layout. What you get is a bot process you own, a set of environment variables, and a plugins directory. The README is explicit about the other side of that bargain: the legal notice says the code "uses unofficial WhatsApp Web API methods and may result in temporary or permanent account bans", and that the software is "provided for educational and research purposes only". Anyone evaluating this has to treat that sentence as a product constraint, not boilerplate.

## Session strings, handler prefixes and the plugin folder

The entry point is index.js, declared as main in package.json, and the start script hands it straight to PM2 under the name raganork-md. config.js sits alongside it as the configuration handler, but the actual values are read from the environment through dotenv, which is why the README tells you to create a .env file in the project root. The repository layout separates plugins/, core/, output/ and temp/, with core/ holding the libraries and plugins/ holding the commands.

Command dispatch works off a handler prefix. The default prefix is a dot, and the sample configuration sets HANDLERS=.,! so a message beginning with either character is treated as a command. The SUDO variable holds a single owner number, 919876543210 in the example, and it is what separates the privileged commands from the public ones. The README lists .list and .ping as open to everyone, and .restart and .shutdown as sudo only.

Sessions are strings rather than an interactive login flow. A single session is written as SESSION=RGNK~d7a5s66, and a multi-session deployment separates several of them with commas. That string is the credential: anyone holding it can drive the bot as that WhatsApp identity. The README does not document how a session is obtained, it points at a separate site for that, so the acquisition step sits outside the repository.

Underneath, the dependency list in package.json tells you what the rest of the machine is made of. Baileys is pinned to 7.0.0-rc14, a release candidate, and sequelize and pg provide the PostgreSQL path while sqlite3 is also present for local storage. node-cache backs the caching the README advertises, and node-cron and node-webpmux handle scheduling and multi-file connections.

## Installing raganork-md and starting the first session

The prerequisites list is short but not optional: Node.js version 20 or higher, Git, FFmpeg, Yarn, PM2, and a PostgreSQL database URL for cloud deployments. The install path is a clone, a dependency install, and a .env file. The global tools come first:

```bash
npm install -g yarn pm2
git clone https://github.com/souravkl11/raganork-md.git
cd raganork-md
```

Then the project dependencies, installed with Yarn because the repository ships a yarn.lock:

```bash
yarn install
```

The configuration file is the part worth reading carefully, because a wrong value here is the usual reason a bot connects and then does nothing. The session string comes first, and for a multi-session setup you list them separated by commas:

```bash
SESSION=RGNK~d7a5s66,RGNK~7ad8cW
```

The rest of the .env file covers the bot identity, the handler prefix, the sudo number, the database and the locale:

```bash
# Bot Configuration
BOT_NAME=Your Bot Name
HANDLERS=.,!
SUDO=919876543210

# Database (Required for cloud platforms)
DATABASE_URL=your_database_url

# Localization
LANGUAGE=en
TZ=Asia/Kolkata
```

Finally the bot runs through PM2, which is what the start script wraps:

```bash
npm start
```

Two operational commands cover the day-to-day cases:

```bash
# Stop bot
pm2 stop raganork-md

# Restart bot
pm2 restart raganork-md
```

What you should see is a PM2 process named raganork-md that stays up. If it exits immediately, the usual suspects are a missing session string, a DATABASE_URL that cannot be reached, or FFmpeg missing from the host, since the media plugins shell out to it.

## Running raganork-md in Docker with a PostgreSQL DATABASE_URL

The repository ships a Dockerfile, and it makes the cloud-versus-VPS distinction concrete. The image is built on node:22-alpine, installs ffmpeg, libwebp-tools, python3, make and g++, clones the main branch, installs Yarn and PM2 globally, and ends on the same npm start command used locally:

```dockerfile
FROM node:22-alpine
RUN apk add --no-cache \
    git \
    ffmpeg \
    libwebp-tools \
    python3 \
    make \
    g++
ADD https://api.github.com/repos/souravkl11/raganork-md/git/refs/heads/main version.json
RUN git clone -b main https://github.com/souravkl11/raganork-md /rgnk
WORKDIR /rgnk
RUN mkdir -p temp
ENV TZ=Asia/Kolkata
RUN npm install -g --force yarn pm2
RUN yarn install
CMD ["npm", "start"]
```

Two details deserve attention. The build tools are there because the sqlite3 native module has to compile inside Alpine, so the image is larger than it needs to be if you only intend to use PostgreSQL. And the ADD line pulls version.json from the GitHub API during the build, so an unauthenticated or rate-limited API call becomes a build failure even when the clone would have succeeded. The version file is fetched but the Dockerfile never reads it.

The README is direct about storage: on Render, Koyeb, Railway and similar platforms you need a DATABASE_URL pointing at PostgreSQL for persistent storage, while VPS deployments can use local file storage. That distinction matters more than it sounds, because ephemeral container filesystems lose session state on every redeploy, and a bot that reconnects as a different identity is a confusing failure to debug.

Note also what the image does not include: your .env file. Configuration is supplied at runtime, not baked into the layer.

## Media, caching and the older dependencies in package.json

The feature list mentions media download, group management tools and session management, and the dependency list is where that work actually happens. fluent-ffmpeg and audio-decode handle audio work, jimp at 0.16.0 handles image manipulation, image-to-pdf turns pictures into documents, browser-id3-writer tags media metadata, and file-type detects formats. There are also network-facing libraries such as axios, cheerio, acrcloud, youtube-sr, google-tts-api and @vitalets/google-translate-api, which suggests the plugins reach outside the bot to fetch or transform content. The repository does not document each plugin's behaviour individually, so the plugin folder is where you read the ground truth.

The dependency ages are a real maintenance signal, and they cut against the rewrite's stated goal of better stability and performance. jimp 0.16.0 and node-cache 5.1.2 are both several years old as major versions. Using an old major version of an image library inside a framework that claims stability work is the kind of thing that turns into a security or compatibility problem rather than a feature request.

The plugins directory is also the extension point where the design is most open-ended and least documented. Nothing in the README explains the plugin interface, the event names, or how a plugin registers a command with the handler, so a new command means reading existing plugin code rather than following a guide. The README does say that "Some files are obfuscated for security reasons and should not be modified", which narrows how much of the tree you can read before changing anything.

## Where raganork-md is the wrong choice

The first limitation is the one the project itself states: the bot uses unofficial WhatsApp Web API methods and may result in temporary or permanent account bans. That is not a remote risk to be monitored, it is a property of the design. Anything customer-facing, anything tied to revenue, and anything where losing the account would be expensive, sits badly on this foundation. The legal notice also states the code is not affiliated with, authorized by, or endorsed by WhatsApp, so there is no support path when the unofficial method changes and breaks.

Second, the delivery model. There are no GitHub releases, so there is no tagged version to pin to and no changelog to read. The version field in package.json reads 6.3.0, but the Dockerfile clones the main branch, which means a redeploy can pull different code from the one you tested. Baileys is itself pinned to 7.0.0-rc14, a release candidate, and Baileys releases have a habit of shifting the underlying protocol, so a bot that worked on one day can stop connecting on the next without anything in raganork-md changing.

Third, the obfuscated files. A framework you cannot read is a framework you cannot fix, and the note in the README makes the boundary explicit rather than leaving it to be discovered later.

The alternative depends on what you actually need. If you want one or two commands on an account you already own, a small script written directly against Baileys 7.0.0-rc14 is a different approach with a different cost profile: you own every line, you avoid the obfuscated files and the plugin conventions, and you give up the group management tooling, the caching layer and the multi-session setup that raganork-md already handles. If the bot is a customer-facing support or notification channel, the official WhatsApp business API differs in kind, because it does not depend on driving a personal web session and therefore does not carry the ban risk the legal notice describes. Neither alternative is free, but both move the failure mode somewhere you can see it.

## Maintenance state and what an upgrade costs you

The project is not archived and the last push was on 2026-09-06, so the code base is being touched on a recent, regular basis. That is the whole of the good news, and it is worth separating from the rest, because a recent push says nothing about release discipline. The repository has no GitHub releases, so there is no published artifact to install and no version history to diff. Upgrading means pulling the main branch and reading the diff yourself.

The dependency pin makes that a recurring chore rather than a one-off. Because the Dockerfile and the git clone in the README both track main, every rebuild is a fresh install of a fresh tree, and the packages underneath it move on their own schedule. A clean upgrade path would need a lockfile check against the installed tree, a rehearsal on a staging session, and a rollback plan, and the project gives you none of those in the repository.

On licensing, package.json declares GPL-3.0-or-later and the README points to the LICENSE file. The practical implication for an operator is narrow: running the bot unmodified as your own deployment is unremarkable, but if you modify it and distribute that modified version to others, the copyleft terms of the GPL attach to the distributed work, and if you build a proprietary service on top of the code you need to understand what you are obliged to publish. That is a question for whoever handles your licensing, not a legal opinion from this article. The project's own framing is that the code is provided for educational and research purposes only, and a GPL licence does not change that.

The combination is a codebase that is alive and cared for, wrapped in a release process that leaves the operator to do the version management by hand.

## Conclusion

raganork-md fits a self-hoster who wants a command bot on a WhatsApp account they already control and is comfortable running a Node process under PM2 with a PostgreSQL database on a cloud container. It does not fit a business that needs guaranteed delivery, a support inbox backed by official APIs, or a team unwilling to accept that the account can be banned. Verify first that you can obtain a session string for the identity you intend to drive, that the plugins in plugins/ behave the way your use case needs once the obfuscated files are in place, and that your hosting platform gives you a persistent DATABASE_URL before you depend on session state surviving a restart.

## FAQ

### How do I install and run raganork-md on my own server?

Clone the repository, run npm install -g yarn pm2 and yarn install, create a .env file in the project root with at least SESSION, BOT_NAME, HANDLERS, SUDO and DATABASE_URL, then start it with npm start, which launches index.js under PM2 as raganork-md. The README also requires Node.js version 20 or higher, Git, FFmpeg and Yarn on the host.

### Does raganork-md need a PostgreSQL database?

A DATABASE_URL pointing at PostgreSQL is required for cloud deployments on platforms such as Render, Koyeb and Railway, because those platforms need persistent storage for session state. The README states that VPS deployments can use local file storage instead. The dependency list also includes sqlite3 for that local path.

### Can I get my WhatsApp account banned by running raganork-md?

The legal notice in the README says the bot uses unofficial WhatsApp Web API methods and may result in temporary or permanent account bans, and that the code is provided for educational and research purposes only. It also states the project is in no way affiliated with, authorized by, or endorsed by WhatsApp.

### How do I add a new command to raganork-md?

The repository layout puts commands in the plugins/ directory alongside core/ libraries, and the README describes an extensive plugin system. It does not document the plugin interface itself, so a new command means reading the existing plugin code for the registration convention. The README also notes that some files are obfuscated for security reasons and should not be modified.

### What licence is raganork-md released under?

package.json declares GPL-3.0-or-later, and the README states "GPL License - See LICENSE file for details". A LICENSE file is present in the repository root.

## Sources

- [Issues](https://github.com/souravkl11/raganork-md/issues)
- [License: GPL-3.0](https://github.com/souravkl11/raganork-md/blob/main/LICENSE)
- [Project website](https://raganork.site)
- [README](https://github.com/souravkl11/raganork-md/blob/main/README.md)
- [souravkl11/raganork-md on GitHub](https://github.com/souravkl11/raganork-md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/souravkl11-raganork-md
