Exploring the roots and future of Internet Relay Chat

Atheme vs Anope: Choosing IRC Services for Your Network

I've deployed both Atheme and Anope on networks ranging from 30 users to several thousand. My first encounter with IRC services was Anope 1.6 on an UnrealIRCd network back in 2003 — it crashed every few weeks and the database format was arcane. Both projects have come a long way since then. The question I get most from people starting new networks is simple: which one should I pick? The answer depends on factors most guides don't mention.

Why IRC Services Matter

IRC by itself has no concept of accounts. The protocol knows about nicknames, but anyone can use any nickname that isn't currently taken. There's no authentication, no password, no persistent identity. Services fill that gap.

NickServ lets users register and protect their nicknames. ChanServ manages channel ownership, access lists, and settings that persist through netsplits and restarts. OperServ gives network operators tools for managing the network. MemoServ handles offline messaging. BotServ provides channel bots. HostServ manages virtual hosts.

Without services, running a network beyond a handful of friends is chaotic. Channel takeovers happen during netsplits. Users impersonate each other. Bans don't stick because there's nothing tying a nick to a persistent identity. Services are the layer that makes IRC usable as a community platform.

Atheme and Anope are the two major open-source services packages still actively maintained. There are others — HybServ, Epona, IRC Services by Andrew Church — but most are dead or barely maintained. For a new network in 2024, it's Atheme or Anope.

Architecture Differences

Atheme and Anope have fundamentally different architectures, and this matters more than feature checklists.

Atheme is written in C with a heavily modular design. The core is minimal — a service framework that loads modules for everything. NickServ, ChanServ, SASL — all modules. You can load and unload them at runtime without restarting. The design philosophy is Unix-like: small pieces that do one thing.

Anope is written in C++ with an object-oriented architecture. It ships as a more integrated package. Core services (NickServ, ChanServ, OperServ) are built-in, with additional features loaded as modules. The object model makes extending Anope different — you're working with classes and inheritance rather than hooking into function pointers.

# Atheme module loading (atheme.conf)
loadmodule "modules/nickserv/main";
loadmodule "modules/nickserv/register";
loadmodule "modules/nickserv/identify";
loadmodule "modules/nickserv/set";
loadmodule "modules/nickserv/cert";
loadmodule "modules/chanserv/main";
loadmodule "modules/chanserv/register";
loadmodule "modules/chanserv/flags";
loadmodule "modules/saslserv/main";
loadmodule "modules/saslserv/plain";
loadmodule "modules/saslserv/external";
# Anope module loading (services.conf)
module {
    name = "ns_register"
}
module {
    name = "ns_identify"
}
module {
    name = "ns_set"
}
module {
    name = "cs_register"
}
module {
    name = "cs_flags"
}
module {
    name = "m_sasl"
}

The practical difference: Atheme's granularity is finer. You can load exactly the NickServ subcommands you want. In Anope, modules tend to be larger units. Both approaches work. Atheme gives you more control at the cost of a longer configuration file.

Memory footprint differs too. Atheme with a basic configuration uses less RAM than Anope for the same user count. On a network with 5,000 registered nicks, I measured Atheme at around 15 MB resident and Anope at around 25 MB. Not a meaningful difference on modern hardware, but worth noting if you're running on constrained systems.

NickServ and ChanServ Compared

Both handle the basics identically: nick registration, password authentication, channel registration, access lists, and auto-op. The differences are in the details.

Atheme's flags system uses a character-based approach similar to Unix file permissions:

/msg ChanServ FLAGS #mychannel trusteduser +vVoOtsi

# Flags:
# v = can use voice/devoice
# V = auto-voice on join
# o = can use op/deop
# O = auto-op on join
# t = can change topic
# s = can use SET commands
# i = can use INVITE

Anope's access system uses numeric levels by default (like old services) but also supports a flags system via the cs_flags module:

# Anope with access levels (default)
/msg ChanServ ACCESS #mychannel ADD trusteduser 10

# Anope with flags module
/msg ChanServ FLAGS #mychannel trusteduser +voAO

# Level meanings (default Anope):
# 3 = auto-voice
# 5 = auto-halfop + kick
# 10 = auto-op + topic + invite
# 20 = protect + akick management
# 9999 = founder-level

Atheme's flags are more intuitive once you learn them. Anope's numeric levels are simpler for small channels where you just want "this person is an op" without thinking about granular permissions. I prefer Atheme's approach because it maps directly to what the user can do, but I've seen plenty of networks run fine with Anope's levels.

Channel succession — what happens when the founder disappears — is handled differently too. Atheme has a configurable succession policy where the next user on the access list inherits founder privileges after a timeout. Anope requires manual intervention by network staff or the channel expires entirely.

Tip: Whichever services package you choose, document your channel access model clearly for your users. Most nick/channel registration confusion comes from users not understanding the permission model. Put a help page on your network's website.

SASL Authentication

SASL (Simple Authentication and Security Layer) lets users authenticate to services before their connection is fully registered. This is how you identify to NickServ before joining channels, which is necessary if channels require identified users (+R mode).

Both Atheme and Anope support SASL PLAIN and SASL EXTERNAL (client certificate authentication). The implementation quality differs:

Atheme has first-class SASL support. The saslserv module handles it cleanly. SASL EXTERNAL with CertFP (certificate fingerprint) works reliably. The cert module in NickServ manages fingerprint registration:

# User registers their certificate fingerprint
/msg NickServ CERT ADD

# Now they can authenticate via SASL EXTERNAL
# No password transmitted — the TLS client cert handles auth

Anope added SASL support later. It works, but early versions had edge cases with reconnection timing. Modern Anope (2.0+) handles SASL well. The m_sasl module is required:

# In services.conf
module {
    name = "m_sasl"
}

# Users can then use SASL PLAIN or EXTERNAL
# Certificate fingerprints managed via:
/msg NickServ CERT ADD fingerprint_here

If your network enforces authentication before join (which you should, for spam prevention), SASL support in your services is non-negotiable. Both packages handle it adequately now, but Atheme's implementation has been battle-tested longer.

Modules and Extensibility

Writing custom modules differs significantly between the two.

Atheme modules are C code that hooks into the service framework. Here's a skeleton of a custom NickServ command:

/* Minimal Atheme module skeleton */
#include "atheme.h"

static void ns_cmd_example(sourceinfo_t *si, int parc, char *parv[])
{
    command_success_nodata(si, "This is a custom command.");
}

static command_t ns_example = {
    "EXAMPLE", "A custom example command.",
    AC_AUTHENTICATED, 0, ns_cmd_example, { .path = "" }
};

static void mod_init(module_t *const restrict m)
{
    service_named_bind_command("nickserv", &ns_example);
}

static void mod_deinit(module_unload_intent_t intent)
{
    service_named_unbind_command("nickserv", &ns_example);
}

DECLARE_MODULE_V1("custom/ns_example", MODULE_UNLOAD_CAPABILITY_OK,
    mod_init, mod_deinit, PACKAGE_STRING, VENDOR_STRING);

Anope modules use C++ with the Anope API:

/* Minimal Anope module skeleton */
#include "module.h"

class CommandNSExample : public Command
{
public:
    CommandNSExample(Module *creator) : Command(creator, "nickserv/example", 0, 0)
    {
        this->SetDesc("A custom example command");
    }

    void Execute(CommandSource &source, const std::vector ¶ms) override
    {
        source.Reply("This is a custom command.");
    }
};

class NSExample : public Module
{
    CommandNSExample cmd;
public:
    NSExample(const Anope::string &modname, const Anope::string &creator)
        : Module(modname, creator, THIRD), cmd(this)
    {
    }
};

MODULE_INIT(NSExample)

If you know C, Atheme's hook-based system feels natural. If you prefer OOP, Anope's class-based API is cleaner. The third-party module ecosystem is larger for Anope — more people write Anope modules, probably because more networks run Anope.

Database and Storage

Data persistence is where practical differences emerge.

Atheme uses a flat-file database by default (services.db). It's a custom text format. Backups are trivial — copy the file. There's an OpenSDB module for a more structured format, and experimental SQL support exists but isn't widely used in production.

Anope supports multiple backends: flat-file (the default db_flatfile), SQL via db_sql (MySQL/MariaDB/PostgreSQL), and Redis via db_redis. SQL support is mature and well-tested.

# Anope SQL backend configuration
module {
    name = "db_sql"
}
module {
    name = "m_mysql"
}

mysql {
    name     = "mysql/main"
    database = "anope"
    server   = "127.0.0.1"
    username = "anope"
    password = "secure_password_here"
    port     = 3306
}

If you need to query your services database from external applications — a website showing channel statistics, a REST API for user management, or integration with a helpdesk system — Anope's SQL backend is a significant advantage. With Atheme, you'd need to parse the flat-file format or use the XMLRPC module.

Atheme does have XMLRPC and JSON-RPC interfaces that let external applications interact with services over HTTP. This works well for simple integrations but is less flexible than direct SQL access.

Warning: If you use Anope's SQL backend, make sure your database server is reliable. If MySQL goes down, Anope can't save state changes. Regular database backups are mandatory. Test your backup restoration procedure — don't wait for a disaster to find out your backups are corrupt.

Which One Should You Choose

After running both on production networks, here's my honest take:

Choose Atheme if:

  • You want fine-grained module control
  • Your network uses InspIRCd or charybdis/solanum (Atheme's protocol support for these is native)
  • You prefer flags-based channel access
  • You want lower memory usage
  • SASL EXTERNAL with CertFP is a priority
  • You're comfortable with C for custom modules

Choose Anope if:

  • You need SQL database integration
  • Your network runs UnrealIRCd (Anope's UnrealIRCd support is excellent)
  • You want a larger third-party module ecosystem
  • You prefer numeric access levels or want both levels and flags
  • You need BotServ features (channel bots with fantasy commands)
  • You're more comfortable with C++ than C

For a small network (under 500 users), either works fine. Pick the one whose documentation you find clearer. For larger networks, the choice depends more on your IRCd and integration requirements. I've seen both handle thousands of registered nicks without issues.

One practical note: check which services your IRCd's documentation recommends. InspIRCd's docs reference both but give slightly more Anope examples. Charybdis/Solanum networks traditionally use Atheme. UnrealIRCd documentation features Anope prominently. Going with the pairing your IRCd expects means fewer edge cases in the protocol linking.

FAQ

Can I migrate from Atheme to Anope or vice versa?

Yes, but it's not trivial. There are community-written database conversion scripts on GitHub. The main challenge is mapping access models — Atheme's flags don't translate 1:1 to Anope's levels. Plan for manual verification after conversion. Run both in parallel on a test network before cutting over on production.

Do both support IRCv3 features?

Both support SASL and account-tag, which are the most relevant IRCv3 features for services. Atheme has slightly broader IRCv3 support because the Atheme developers were involved in the IRCv3 working group. Anope has been catching up steadily.

What about Anope 1.x vs 2.x?

Anope 1.x is dead. Do not use it. Anope 2.0+ is a complete rewrite with a modern architecture, better protocol support, and active maintenance. If you find a guide referencing Anope 1.x configuration, ignore it — the config format changed entirely.

Is Atheme still actively developed?

Atheme's development pace has slowed compared to its peak years. The project accepts patches and fixes, but major new features are rare. The codebase is mature and stable. For most networks, the current feature set is more than sufficient. If you need features that require active development, Anope may be the safer bet for long-term support.