A blazingly fast terminal-based chat application demonstrating seamless Foreign Function Interface (FFI) between Go and Swift using C ABI compatibility.
tcat is a test project exploring the powerful combination of Go's concurrency primitives and Swift's expressive syntax through C ABI interoperability. This project showcases:
- Go Backend: Handles TCP networking, goroutines, channels, and atomic operations
- Swift Frontend: Implements application logic, terminal UI, and user interactions
- C ABI Bridge: Enables zero-cost abstractions between both languages
โ ๏ธ Note: This is an experimental/educational project. Authentication is not yet implemented. Do not use in production environments.
- ๐จ Twitch-Style Colorized Chat: Each user gets a unique, consistent color
- โก Real-time Messaging: Powered by Go's goroutines and TCP stack
- ๐ฅ๏ธ Beautiful TUI: ANSI-based terminal UI with proper scrolling and window resize handling
- ๐ฌ Blinking Cursor: Visual feedback for input readiness
- ๐ Concurrent Architecture: Multiple clients can connect simultaneously
- ๐ญ System Notifications: Join/leave messages in subtle gray
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Swift Application Layer โ
โ โข Terminal UI (ANSI escape codes) โ
โ โข Input handling & message formatting โ
โ โข User interaction logic โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ C ABI FFI
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Go Runtime Layer (libgolang) โ
โ โข TCP networking (Listen, Connect, Accept, Read, Write) โ
โ โข Goroutines (TaskLaunch, TaskLaunchVoid) โ
โ โข Channels (ChannelCreate, Send, Recv) โ
โ โข Atomic operations (CompareAndSwap, Load, Store) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-
Swift Static SDK (musl-based for Linux)
- Download from: https://www.swift.org/install
- Set
SWIFT_STATIC_SDKenvironment variable to your SDK path
export SWIFT_STATIC_SDK=~/.swiftpm/swift-sdks/swift-6.0.3-RELEASE_static-linux-0.0.1.artifactbundle/swift-6.0.3-RELEASE_static-linux-0.0.1/swift-linux-musl/musl-1.2.5.sdk/x86_64
-
Custom Go Compiler (musl-patched)
- A patched Go compiler compiled against musl is required
- Place in
bin/musl-go - Note: Standard Go has a bug with
-buildmode=c-archivewhen compiled with musl-gcc
-
Standard Build Tools
makegccormusl-gcc
# Clone the repository
git clone https://github.com/jelius-sama/tcat.git
cd tcat
# Build everything (Go library + Swift binary)
make
# The binary will be at: bin/tcatmake clean
make./bin/tcat -s -p 6969Or use the default port (6969):
./bin/tcat -s./bin/tcat -c -p 6969Multiple clients can connect simultaneously to the same server.
Usage:
tcat [mode] [options]
Modes:
-s, --server Start in server mode
-c, --client Start in client mode
-h, --help Show help message
Options:
-p, --port <port> Specify port (default: 6969)
Examples:
tcat -s -p 9000 Start server on port 9000
tcat -c -p 9000 Connect to server on port 9000
tcat --help Show this help
| Key | Action |
|---|---|
| Type normally | Enter text |
Enter |
Send message |
Backspace |
Delete character |
Ctrl+C |
Exit client |
.
โโโ bin/
โ โโโ musl-go # Patched Go compiler
โ โโโ tcat # Compiled binary
โโโ libgolang/
โ โโโ golang.go # Go runtime exports
โ โโโ go.mod
โ โโโ libgolang.a # Compiled Go static library
โ โโโ libgolang.h # Generated C headers
โ โโโ module.modulemap # Swift module map
โโโ Source/
โ โโโ main.swift # Entry point & CLI parsing
โ โโโ server.swift # Server logic
โ โโโ client.swift # Client logic & TUI
โ โโโ shared.swift # Shared constants
โ โโโ ctypes.swift # C type aliases
โ โโโ extension.swift # Swift extensions
โโโ Makefile # Build configuration
The project uses C ABI as the common ground between Go and Swift:
- Go Side: Functions are exported with
//exportdirective and compiled to a static archive with-buildmode=c-archive - C Headers: Go generates C-compatible headers automatically
- Swift Side: Imports the C headers and calls functions directly with zero overhead
- Server: Each client connection runs in its own goroutine via
TaskLaunchVoid - Client: Two concurrent tasks:
- Goroutine 1: Reads messages from server
- Goroutine 2: Blinks cursor for UI feedback
- Main thread: Handles user input
- Uses Go's
sync/atomicprimitives exported to Swift - SpinLock implementation with
AtomicCompareAndSwapInt32 - Thread-safe message queue with proper locking
- Pure Go
netpackage for TCP operations - Connection handles stored in Go-side maps
- Zero-copy byte slices passed between languages using
unsafe.Pointer
The terminal UI features:
- Chat Area: Scrolling message history with color-coded usernames
- Separator Line: Visual boundary between chat and input
- Input Line: Shows username + current input + blinking cursor
- Dynamic Resizing: Adapts to terminal window size changes (SIGWINCH)
Colors are assigned deterministically based on username hash, ensuring consistency across reconnects.
- โ No authentication or encryption
- โ No message persistence
- โ No private messaging
- โ No rate limiting or spam protection
- Add TLS/SSL encryption
- Implement user authentication
- Add private messaging support
- Message history/logging
- Configurable color themes
- Emoji support
- File transfer capability
- Multiple chat rooms
This is an experimental project for learning purposes. Feel free to fork and experiment!
MIT โ See LICENSE
Jelius Basumatary โ Systems & App Developer in Practice
- Go team for excellent
cgoand concurrency primitives - Terminal emulator developers for ANSI standard support
Built with โค๏ธ using Go and Swift