netirc - NetIRC 1.1.2

Simple open-source Portable IRC Client Library written in C# targeting .NETStandard 2.0 and .NET Framework 4.6.1

PM> Install-Package NetIRC -Version 1.1.2 -Source https://www.myget.org/F/netirc/api/v3/index.json

Copy to clipboard

> nuget.exe install NetIRC -Version 1.1.2 -Source https://www.myget.org/F/netirc/api/v3/index.json

Copy to clipboard

> dotnet add package NetIRC --version 1.1.2 --source https://www.myget.org/F/netirc/api/v3/index.json

Copy to clipboard
<PackageReference Include="NetIRC" Version="1.1.2" />
Copy to clipboard
source https://www.myget.org/F/netirc/api/v3/index.json

nuget NetIRC  ~> 1.1.2
Copy to clipboard

> choco install NetIRC --version 1.1.2 --source https://www.myget.org/F/netirc/api/v2

Copy to clipboard
Import-Module PowerShellGet
Register-PSRepository -Name "netirc" -SourceLocation "https://www.myget.org/F/netirc/api/v2"
Install-Module -Name "NetIRC" -RequiredVersion "1.1.2" -Repository "netirc" 
Copy to clipboard

Browse the sources in this package using Visual Studio or WinDbg by configuring the following symbol server URL: https://www.myget.org/F/netirc/api/v2/symbolpackage/


NetIRC

Build status Coverage Status NuGet NuGet MyGet

A simple, portable IRC client library for C# targeting .NET Standard 2.0 and .NET Framework 4.6.1.

NetIRC gives you a clean async-first API for building IRC bots, desktop clients, and any other application that needs to talk to an IRC server.


Features

  • Fully async/await API
  • TCP and WebSocket connections out of the box
  • Observable collections for channels, queries, users, and server messages — ready for WPF / MAUI data binding
  • Built-in IRC command messages (JOIN, PART, PRIVMSG, NICK, KICK, QUIT, TOPIC, …)
  • CTCP support (VERSION, TIME, PING, CLIENTINFO, ACTION)
  • Extensible custom message handler system
  • Fluent builder for client configuration

Installing

Via the NuGet Package Manager Console:

Install-Package NetIRC

Via the .NET CLI:

dotnet add package NetIRC

Pre-release builds are available on MyGet.


Quick Start

using NetIRC;
using NetIRC.Messages;

// Build the client
using var client = Client.CreateBuilder()
    .WithNick("MyBot", "My IRC Bot")
    .WithServer("irc.libera.chat", 6667)
    .Build();

// Called once the server confirms registration (001 Welcome)
client.RegistrationCompleted += async (sender, e) =>
{
    if (sender is Client c)
        await c.SendAsync(new JoinMessage("#mychannel"));
};

// Called for every channel message
client.Channels.CollectionChanged += (s, e) =>
{
    foreach (Channel ch in e.NewItems ?? Array.Empty<object>())
    {
        ch.Messages.CollectionChanged += (ms, me) =>
        {
            foreach (ChannelMessage msg in me.NewItems ?? Array.Empty<object>())
                Console.WriteLine($"[{ch.Name}] <{msg.User.Nick}> {msg.Text}");
        };
    }
};

await client.ConnectAsync();
await Task.Delay(Timeout.Infinite); // keep alive

A fully commented, runnable example is in samples/NetIRC.ConsoleCli.


Core Concepts

Client

Client is the entry point. Create one via the fluent builder:

var client = Client.CreateBuilder()
    .WithNick("MyNick", "My Real Name")   // sets the IRC nick and USER real name
    .WithServer("irc.libera.chat", 6667)  // host and port
    .WithPassword("serverpassword")        // optional: server password (PASS command)
    .Build();

Or directly via constructor if you need fine-grained control over the connection:

var user = new User("MyNick", "My Real Name");
var connection = new TcpClientConnection("irc.libera.chat", 6667);
using var client = new Client(user, connection);

User

Represents an IRC user. Implements INotifyPropertyChanged so the Nick property can be bound directly in WPF/MAUI.

Console.WriteLine(client.User.Nick);

Channel & Query

Type Description
Channel An IRC channel the client has joined. Has an observable Users and Messages collection.
Query A private conversation with another user. Has an observable Messages collection.

Both are created automatically by the library when a JOIN or PRIVMSG (private) is received.

Observable Collections

All collections implement ObservableCollection<T> so you can subscribe to CollectionChanged:

Property Type Contains
client.Channels ChannelCollection Channels you have joined
client.Queries QueryCollection Active private conversations
client.Peers UserCollection All known users
client.ServerMessages ServerMessageCollection Server status / motd lines

Events

Event Signature Fired when
RawDataReceived (Client client, string rawData) Any raw line is received from the server
IRCMessageParsed (Client client, ParsedIRCMessage msg) A raw line has been parsed into a structured message
RegistrationCompleted (object sender, EventArgs e) Server sends 001 (Welcome) — safe to join channels
CtcpReceived (Client client, CtcpEventArgs ctcp) A CTCP request or reply is received
client.RawDataReceived += (c, raw) => Console.WriteLine(raw);

client.IRCMessageParsed += (c, msg) =>
{
    if (msg.IRCCommand == IRCCommand.TOPIC)
        Console.WriteLine($"Topic on {msg.Parameters[0]}: {msg.Trailing}");
};

Sending Messages

Use SendAsync with any IClientMessage implementation:

await client.SendAsync(new JoinMessage("#channel"));
await client.SendAsync(new PartMessage("#channel", "Goodbye!"));
await client.SendAsync(new PrivMsgMessage("#channel", "Hello, world!"));
await client.SendAsync(new NickMessage("NewNick"));
await client.SendAsync(new TopicMessage("#channel", "New topic here"));
await client.SendAsync(new KickMessage("#channel", "SomeUser", "Reason"));
await client.SendAsync(new QuitMessage("Leaving"));

For raw protocol strings:

await client.SendRaw("MODE #channel +m\r\n");

Built-in Message Types

Class IRC Command Direction
JoinMessage JOIN Client → Server
PartMessage PART Client → Server
PrivMsgMessage PRIVMSG Both
NickMessage NICK Both
TopicMessage TOPIC Both
KickMessage KICK Both
QuitMessage QUIT Both
NoticeMessage NOTICE Server → Client
ModeMessage MODE Server → Client
PingMessage / PongMessage PING / PONG Both (auto-handled)
PassMessage PASS Client → Server
UserMessage USER Client → Server

Custom Message Handlers

Implement a custom handler by deriving from CustomMessageHandler<TMessage> and decorating it with [Command]:

using NetIRC.Messages;

[Command(IRCCommand.PRIVMSG)]
public class PrivMsgHandler : CustomMessageHandler<PrivMsgMessage>
{
    public override Task HandleAsync(Client client, PrivMsgMessage message)
    {
        Console.WriteLine($"<{message.From}> {message.Message}");
        return Task.CompletedTask;
    }
}

Register it on the client:

// Register a specific handler type
client.RegisterCustomMessageHandler<PrivMsgHandler>();

// Or auto-discover all handlers in an assembly
client.RegisterCustomMessageHandlers(typeof(Program).Assembly);

CTCP Support

The following CTCP commands are handled automatically:

Command Behaviour
VERSION Replies with NetIRC
TIME Replies with the current local time
PING Echoes the timestamp back
CLIENTINFO Lists supported CTCP commands
ACTION Raises CtcpReceived

Subscribe to CtcpReceived to handle additional or custom CTCP messages:

client.CtcpReceived += (c, ctcp) =>
{
    Console.WriteLine($"CTCP {ctcp.Command} from {ctcp.Nick}");
};

Connection Types

TcpClientConnection (default)

Standard IRC over plain TCP. Used by the builder by default.

var connection = new TcpClientConnection("irc.libera.chat", 6667);

WebSocketClientConnection

For IRC servers that expose a WebSocket endpoint (e.g. KiwiIRC gateway):

var connection = new WebSocketClientConnection(new Uri("wss://irc.example.com/socket"));
using var client = new Client(user, connection);

WPF / UI Thread Dispatcher

If you are building a WPF or WinForms application, observable collection changes must happen on the UI thread. Pass the dispatcher before connecting:

// WPF
client.SetDispatcherInvoker(action => Application.Current.Dispatcher.Invoke(action));

Projects Built with NetIRC

Feel free to open a pull request to add your project to this list.


Contributing

Contributions are welcome! Open an issue to discuss a bug or feature, then submit a pull request.

  1. Fork the repo and create a branch from master
  2. Make your changes and add / update tests under tests/NetIRC.Tests
  3. Ensure dotnet test passes
  4. Open a pull request with a clear description

1.1.2

Fix ci.yml Fix build Update tests project to .NET 10 Update GH actions Upgrade project: fix parser/connection bugs and rewrite documentation (#11) Make use of non-generic TaskCompletionSource Use builder in Client connection tests Use builder and enable stopping the app with Ctrl+C Create a simple client builder Simpler implementation when slicing big messages Implement recommended disposable pattern

1.1.2-preview.2

Split PrivMsg UTF-8 messages every ~400 bytes Update packages and .NET version Use .NET 6 in workflows Update sample Console client to .NET 6 Use latest C# version

1.1.2-preview.1

Split PrivMsg if the length is close to the limit Move \r\n tot a constant VS 2022 Nick validation Update CtcpCommands.cs

1.1.1

Make sure reconnecting doesn't throw an exception Create new TcpClient instance when connecting Use random ports in TcpClientConnection tests Add IRC clients built with NetIRC

1.1.0-preview.3

Trim trailing

1.1.0-preview.2

Use PackageReleaseNotes instead of PackageDescription

1.1.0-preview.1

Update release.yml Add release notes to NuGet package Setting dispatcher invoker action to null should throw Test IComparer implementation in ChannelUserComparer Fixes sending PrivMsg with no spaces and starting with colon Set DispatcherInvoker in constructor Added channel user comparer for sorting Enable setting a dispatcher invoker method Refactor ServerMessage tests and add Timestamp test Rename Date to Timestamp in messages Handle some numeric replies and add to server messages (tag: v1.1.0-alpha) Fix version Renamed events (BREAKING CHANGE) Add basic CTCP handling Fix test for IRCMessage not implementing IClientMessage Test validation of custom message handler registration Fix package description Small refactoring and added WebSocketClientConnection Moved collections to Collections folder Don't build on windows, it's too slow Hey, that's some more tests... Some more tests Remove unnecessary null coalescing operator Use private setters in IRCMessage properties Make Comment immutable Added more tests and refactored a few others Micro performance improvement Add CreatedDate to IRCMessage Add property to identity a Channel Notice Add ModeMessage for MODE command Add ability to send array of channels to PartMessage Remove unused messages for now Add ability to send array of channels or dictionary to JoinMessage Add Kick message and handler Small refactoring Channel GetUser Add channel user with no status Regular dispose Disable test parallelization for now Stop TCP listeners Sample: move classes to their own files Small refactor and tests Add Client connection tests Remove unnecessary lines from csproj

1.0.0

Refactoring pre-1.0 (#9) Add coverage status badge Fix token Set coverallsapp version Add code coverage Fix push condition Add os matrix Fix launching Console client from VS Code Ignore CI build for changes in .vscode folder Update README.md Added GitHub Workflows. Some cleanup (#8) Version 0.1.2 Update dotnet-steps.yml Update NetIRC.ConsoleCli.csproj Use .NET Core 3.1.x Update Azure Pipeline images Update test project target framework and packages Tests are fixed Update a new dispose pattern Use SafeFireAndForget when running data receiver Add ConfigureAwait(false) since we don't care what thread we return to Add null/empty check (#5) Generate version (#2) Set up CI with Azure Pipelines (#1) Update Codecov badge No colors Update README.md Update Build.ps1 Allow sending PASS to the server Update to .NET Core 2.1 Updating Github username Even more tests :) More tests Wait for DataReceived to be trigger before disposing server connection Refactoring TcpClientConnection tests Updated timeout for disconnect test. Appveyor is driving me crazy!! :P Added more tests Not using INotifyPropertyChanged in Query yet Handle nick change Updated the disconnect test to go through the entire pipeline Added test for user leaving channel and refactored client tests Added missing tests for the EventHub - RegistrationCompleted event - Nick event Use ManualResetEvent when only a flag is needed Fix deployment to MyGet Added NuGet badge

0.1.1

Version 0.1.1 Trying to achieve 100% coverage in TcpClientConnection Hmm.. Am I talking to the git repo? \o/ Yeahh, let's see! Apparently same tests take too long to execute in Appveyor Added on more TcpClientConnection test and refactored a couple of others - Using ManualResetEvent to make sure the event is triggered and make sure we don't block for more time than it's necessary Refactored RunDataReceiver Refactored some tests and added on more for TcpClientConnection class Enable executing CodeCoverage.ps1 locally Ignore OpenCover and coverage xml Ignore OpenCover Changed license to MIT Add .vscode configs Disable gcov Converting CodeCoverage.cmd to a PowerShell script Update README.md Started writing some test to the TcpClientConnection class Restore code coverage Updated README.md Some changes in the CI/CD pipeline Update README.md Fixing code coverage Get code coverage results for NetIRC.csproj Fix typo Code Coverage FTW! Added more documentation in classes, methods, events and properties Renamed Users to Peers in the Client class Update appveyor.yml Update README Update folder structure Update project information Started writing some documentation Cleaning up some tests xUnit: Show method name only in test runners Change build configuration in appveyor Added appveyor.yml Fix version Added script to modify the version of the package Update project description Removed appveyor.yml until I configure it properly Updated to .NET Core 1.1 Trying to fix CI Added appveyor.yml Added Query and QueryCollection classes plus some cleanups Added Channel OnMessageReceived event PART and QUIT messages Modeling users and channels. Parsing and processing RPL_NAMREPLY messages JOIN Message Connection Connected and Disconnected events Separating server and client messages Removed unused code Created messages and events to registration numeric replies Treating the trailing as a parameter, cause that's what it is :) It just happens to be the last one NOTICE message Minor changes and cleanups USER message NICK message implementation Refactoring a couple of tests Created ServerMessage class that represents both server and client messages and can trigger events of the EventHub when the message is received from the server. An IRCMessage alone is just ment to be client messages, for example, the PONG message. Sending messages in a more object oriented way :) PrivMsg message, Ping and Pong commands Passing the client as the sender in IRC message event handlers Created an Event Hub to provide events for messages and commands Some more refactorings Update README.md More simplification Simplifying the TcpClientConnection class Updated README.md Converted it into a Portable library targeting .NETStandard 1.3 Using C# 6 getter-only auto-properties Temp icon Created Base IRC EventArgs Updated console client using the new OnPrivMsgReceived event Created event OnPrivMsgReceived Using IRCCommand Enum instead of comparing string Parsing numeric reply Enum Parsing IRC command Enum Bot checks only direct messages Implemented a very simple IRC Bot to execute commands received Parsing IRC prefix Nice IRCMessage ToString override Flush after writing to the stream Simplified irc message parsing Created event OnIRCMessageReceived Parsing more complete data with trailing Parsing data with two parameters Parsing a command with single parameter Started the raw data parser Added RFC and other documentation Fixed exception after disposing the TCP socket Added basic console client functionality Send NICK and USER when connected Responding PING messages OnRawDataReceived event and unit tests Added Moq Nuget package Added tests project Base client and TCP connection Initial commit

  • .NETFramework 4.6.1
    • System.Memory (>= 4.5.4)
  • .NETStandard 2.0
    • System.Memory (>= 4.5.4)
  • .NETFramework 4.6.1: 4.6.1.0
  • .NETStandard 2.0: 2.0.0.0

Owners

Fredi Machado

Authors

Fredi Machado

Project URL

https://github.com/fredimachado/NetIRC

License

MIT

Tags

irc

Info

4199 total downloads
19 downloads for version 1.1.2
Download (57.62 KB)
Download symbols (31.14 KB)
Found on the current feed only

Package history

Version Size Last updated Downloads Mirrored?
1.1.3-preview.0.7 55.43 KB Fri, 03 Apr 2026 02:45:36 GMT 15
1.1.3-preview.0.6 55.38 KB Fri, 03 Apr 2026 02:07:23 GMT 14
1.1.2 57.62 KB Thu, 02 Apr 2026 11:26:27 GMT 19
1.1.2-preview.2.11 54.58 KB Thu, 02 Apr 2026 11:05:03 GMT 13
1.1.2-preview.2.10 54.57 KB Thu, 02 Apr 2026 10:57:28 GMT 7
1.1.2-preview.2.6 53.04 KB Mon, 07 Mar 2022 11:16:46 GMT 96
1.1.2-preview.2.5 53.05 KB Thu, 17 Feb 2022 13:17:12 GMT 86
1.1.2-preview.2.4 53.04 KB Thu, 17 Feb 2022 13:04:42 GMT 80
1.1.2-preview.2 55.17 KB Thu, 10 Feb 2022 14:59:36 GMT 90
1.1.2-preview.1.5 52.21 KB Thu, 10 Feb 2022 14:59:06 GMT 82
1.1.2-preview.1.4 51.88 KB Tue, 08 Feb 2022 13:57:06 GMT 98
1.1.2-preview.1.1 51.88 KB Tue, 08 Feb 2022 12:17:38 GMT 84
1.1.2-preview.1 54.82 KB Tue, 08 Feb 2022 11:21:22 GMT 86
1.1.2-preview.0.5 51.94 KB Tue, 08 Feb 2022 11:18:30 GMT 98
1.1.1 52.4 KB Sat, 05 Feb 2022 05:03:47 GMT 93
1.1.0 46.38 KB Mon, 29 Mar 2021 14:36:33 GMT 96
1.1.0-preview.3.4 49.64 KB Sat, 05 Feb 2022 04:51:43 GMT 88
1.1.0-preview.3 52.36 KB Sun, 04 Apr 2021 15:23:24 GMT 85
1.1.0-preview.2 52.34 KB Sun, 04 Apr 2021 14:28:57 GMT 87
1.1.0-preview.1 54.97 KB Sun, 04 Apr 2021 14:22:26 GMT 97
1.1.0-alpha.10 49.49 KB Sun, 04 Apr 2021 14:15:13 GMT 86
1.1.0-alpha.9 49.53 KB Sun, 04 Apr 2021 13:37:21 GMT 97
1.1.0-alpha.8 49.55 KB Sun, 04 Apr 2021 13:29:17 GMT 107
1.1.0-alpha.6 49.52 KB Sun, 04 Apr 2021 08:01:36 GMT 86
1.1.0-alpha.3 47.29 KB Tue, 30 Mar 2021 14:12:12 GMT 103
1.1.0-alpha.1 47.27 KB Tue, 30 Mar 2021 13:00:18 GMT 98
1.1.0-alpha 46.42 KB Mon, 29 Mar 2021 14:38:41 GMT 90
1.0.1-alpha.0.32 46.42 KB Mon, 29 Mar 2021 14:24:10 GMT 100
1.0.1-alpha.0.30 44.08 KB Fri, 26 Mar 2021 13:23:00 GMT 88
1.0.1-alpha.0.29 44.08 KB Fri, 26 Mar 2021 13:14:28 GMT 97
1.0.1-alpha.0.28 44.07 KB Fri, 26 Mar 2021 12:45:04 GMT 92
1.0.1-alpha.0.25 41.14 KB Thu, 25 Mar 2021 11:57:13 GMT 87
1.0.1-alpha.0.23 41.15 KB Thu, 25 Mar 2021 11:47:38 GMT 98
1.0.1-alpha.0.22 41.15 KB Thu, 25 Mar 2021 11:24:37 GMT 82
1.0.1-alpha.0.21 41.18 KB Thu, 25 Mar 2021 09:03:39 GMT 93
1.0.1-alpha.0.19 40.89 KB Thu, 25 Mar 2021 08:32:59 GMT 98
1.0.1-alpha.0.6 40.36 KB Wed, 24 Mar 2021 14:31:08 GMT 91
1.0.0 40.54 KB Wed, 24 Mar 2021 11:04:56 GMT 99
1.0.0-alpha.1.2 40.59 KB Wed, 24 Mar 2021 10:53:19 GMT 99
1.0.0-alpha.1 40.59 KB Wed, 24 Mar 2021 10:47:03 GMT 81
0.1.2 26.87 KB Sun, 21 Mar 2021 09:12:24 GMT 84
0.1.2-alpha.0.54 40.62 KB Wed, 24 Mar 2021 10:41:15 GMT 94
0.1.2-alpha.0.45 40.6 KB Wed, 24 Mar 2021 11:02:06 GMT 93
0.1.2-alpha.0.43 36.69 KB Sun, 21 Mar 2021 14:13:58 GMT 95
0.1.2-alpha.0.40 36.68 KB Sun, 21 Mar 2021 13:49:39 GMT 87
0.1.2-alpha.0.39 36.69 KB Sun, 21 Mar 2021 13:40:16 GMT 99
0.1.2-alpha.0.38 36.69 KB Sun, 21 Mar 2021 13:10:25 GMT 93
0.1.2-alpha.0.35 36.7 KB Sun, 21 Mar 2021 12:56:49 GMT 82
0.1.1 18.63 KB Fri, 01 Feb 2019 11:27:56 GMT 103
0.1.1-20-PR-3 18.87 KB Fri, 01 Feb 2019 11:30:52 GMT 83