A Swift package for parsing, encoding, and framing IRC (Internet Relay Chat) messages with modern concurrency support.
NeedleTailIRC is a type-safe IRC protocol layer for the NeedleTail stack. It covers message parsing and encoding (RFC 2812, RFC 1459), IRCv3 message tags, multipart payload chunking, and NIO writer integration. It does not include socket/TLS connection management — you provide the transport and wire encoded lines through your own NIO pipeline or app layer.
- Parse & encode IRC wire format:
NeedleTailIRCParserandNeedleTailIRCEncoder - IRCv3 message tags: Tag parsing, escaping, and round-trip encoding
- Type-safe commands & models:
IRCCommand,NeedleTailChannel,NeedleTailNick, and related types - Multipart framing:
IRCMessageGeneratorandPacketBuilderfor large payload chunking and reassembly - DCC command representation: Encode/decode DCC-related IRC commands (not a full file-transfer client)
- NIO integration:
NeedleTailWriterDelegatefor sending framed messages throughNIOAsyncChannelOutboundWriter - NeedleTail extensions: Custom commands in
Constantsfor blob sync, media, and device workflows
Add NeedleTailIRC to your project using Swift Package Manager:
dependencies: [
.package(url: "https://github.com/needletails/needletail-irc.git", from: "1.0.0")
]import NeedleTailIRC
// Create an IRC message
let message = IRCMessage(
origin: "alice",
command: .privMsg([.channel(NeedleTailChannel("#general")!)], "Hello, world!")
)
// Parse an IRC message string
let parsedMessage = try NeedleTailIRCParser.parseMessage(
":alice!alice@localhost PRIVMSG #general :Hello, world!"
)
// Encode a message to string format (synchronous)
let encodedString = NeedleTailIRCEncoder.encode(value: message)IRCMessageGenerator splits oversized payloads into multipart IRC messages. Reassemble inbound chunks with messageReassembler(ircMessage:).
let generator = IRCMessageGenerator(executor: executor)
let stream = await generator.createMessages(
origin: "alice!user@host",
command: .privMsg([.channel(NeedleTailChannel("#general")!)], largePayload),
logger: NeedleTailLogger()
)
for await message in stream {
let line = NeedleTailIRCEncoder.encode(value: message)
// Write `line` through your NIO outbound writer or socket layer.
}
// On receive:
if let rebuilt = try await generator.messageReassembler(ircMessage: incomingMessage) {
await handleMessage(rebuilt)
}Note: The codec does not enforce the classic 512-byte IRC line limit. Some NeedleTail deployments use larger lines; when talking to standard IRC networks, chunk payloads with
IRCMessageGeneratorand validate wire size in your transport layer.
- Parsing:
NeedleTailIRCParser— raw IRC strings toIRCMessage - Encoding:
NeedleTailIRCEncoder—IRCMessageto wire-format strings - Commands:
IRCCommand— typed representation of IRC commands and numerics - Models: Channels, nicks, tags, permissions, and error types
- Multipart:
IRCMessageGenerator,PacketBuilder,MultipartPacket - Transport hook:
NeedleTailWriterDelegate— bridges message generation to NIO writers
IRCMessage— complete IRC message representationIRCCommand— type-safe IRC command enumNeedleTailChannel— validated channel nameNeedleTailNick— validated nickname (with optional device UUID suffix)IRCTag— IRCv3 message tagIRCMessageGenerator— multipart encode pathNeedleTailWriterDelegate— NIO outbound transport helper
// Join a channel
let joinCommand = IRCCommand.join(
channels: [NeedleTailChannel("#general")!],
keys: nil
)
// Send a message to a channel
let message = IRCMessage(
command: .privMsg([.channel(NeedleTailChannel("#general")!)], "Hello, everyone!")
)
// Set channel modes
let modeCommand = IRCCommand.channelMode(
NeedleTailChannel("#general")!,
addMode: .inviteOnly,
addParameters: nil,
removeMode: nil,
removeParameters: nil
)// Change nickname
let nickCommand = IRCCommand.nick(NeedleTailNick(name: "newNick", deviceId: UUID())!)
// Set user mode
let modeCommand = IRCCommand.mode(
nick: NeedleTailNick(name: "alice", deviceId: UUID())!,
add: [.invisible, .away],
remove: nil
)
// Get user information
let whoisCommand = IRCCommand.whois(server: nil, usermasks: ["alice"])let generator = IRCMessageGenerator(executor: executor)
let stream = await generator.createMessages(
origin: "alice",
command: .privMsg([.channel(NeedleTailChannel("#general")!)], largeMessage),
logger: NeedleTailLogger()
)
for await chunk in stream {
let line = NeedleTailIRCEncoder.encode(value: chunk)
try await writeToTransport(line)
}do {
let message = try NeedleTailIRCParser.parseMessage(rawMessage)
// Process the message
} catch NeedleTailError.invalidIRCChannelName {
print("Invalid channel name")
} catch NeedleTailError.nilNickName {
print("Invalid nickname")
} catch MessageParsingErrors.invalidArguments(let details) {
print("Invalid arguments: \(details)")
} catch MessageParsingErrors.invalidTag {
print("Invalid tag format")
} catch {
print("Unknown parsing error: \(error)")
}Documentation lives in Documentation.docc:
- Getting Started — installation and first messages
- Basic Usage — core concepts and patterns
- Message Format — IRC message structure
- Message Handling — processing messages
- IRC Commands — command reference
- Channels — channel management
- Users — user management and permissions
- Multipart Messages — large message handling
- Transport Layer — NIO writer integration
- Error Handling — error types and strategies
- API Reference — public API overview
- Swift: 6.0+
- Platforms: iOS 18.0+, macOS 15.0+
- Xcode: 15.0+ (for Apple platform development)
NeedleTailIRC pulls in:
swift-nio— NIOCore, NIOConcurrencyHelpersswift-algorithms— algorithm utilitiesswift-async-algorithms— async algorithm supportswift-collections— DequeModuleneedletail-logger— loggingneedletail-algorithms— NeedleTailAsyncSequence and related utilitiesbinary-codable— binary serialization for packet metadata
dependencies: [
.package(url: "https://github.com/needletails/needletail-irc.git", from: "1.0.0")
]- Go to File → Add Package Dependencies
- Enter:
https://github.com/needletails/needletail-irc.git - Select the version you want
- Add to your target
See CONTRIBUTING.md.
MIT — see LICENSE.
- Documentation: Documentation.docc
- Issues: GitHub Issues
- IRC protocol specifications (RFC 2812, RFC 1459)
- IRCv3 extension specifications
- The Swift community