How I Built a Terminal Chat App Over LAN Using Only Bash
Back in college, I loved participating in hackathons and late-night gaming sessions with my friends. But something always bothered me—how hard it was to communicate locally without relying on heavyweight apps like Discord or Slack. These tools were bloated for our needs and, more importantly, required stable internet.
So, one night while everyone else was debugging APIs or building UI components, I decided to scratch my own itch and build a terminal-based LAN chat app using nothing but Bash.
Welcome to term-chat
.
🧠 The Motivation
Why Bash? Why a local chat app? Why not use a ready-made solution?
Because building tools is more fun than using them.
I wanted:
- Something that just works in a local network (no internet dependency)
- No account creation, no GUIs—just open a terminal and type
- Something that I fully understood down to the byte level
- A challenge—how far can I push Bash scripting?
Most terminal chat apps depend on Python, Node.js, or even Electron for cross-platform compatibility. That felt overkill. I wanted something lean, fast, and fully in my control.
So I decided to roll my own HTTP server, message broker, and chat client, entirely in Bash.
🔧 Architecture: Decentralized but Simple
The architecture is peer-server, i.e., one peer starts the server (which can be any machine on the network), and the others connect as clients. No DNS, no NAT traversal, no fancy service discovery.
Here’s a high-level overview:
+-------------+ +-------------+
| Client A | <-----> | Server | <-----> | Client B |
+-------------+ +-------------+
Messages are sent over plain HTTP using netcat
. That’s it.
🌀 Rolling My Own HTTP Server in Bash
This was the most fun part. To accept HTTP requests using just Bash and netcat (nc
), you can do something like this:
while true; do
{
echo -ne "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"
cat messages.log
} | nc -l -p 8080 -q 1
done
But I needed more than that. I needed to handle POST requests, extract payloads, store them in queues, and return new messages to connected clients.
That led to writing my own mini HTTP router in Bash. Here’s a trimmed version of how it processes POST data:
parse_request() {
read method path version
while read line; do
[ "$line" == $'\r' ] && break
done
body=$(cat)
echo "$body" >> messages.log
echo -ne "HTTP/1.1 200 OK\r\n\r\n"
}
No libraries. Just raw file descriptors and the Unix philosophy.
📦 Features (and Why They Matter)
- Zero install dependencies: Any modern Unix system can run it.
- Bash-only: The code reads like an OS experiment, not a chat app.
- Peer discovery via IP: Just type in the IP of the host. Done.
- Persistence: Messages stored in local
.log
files per session. - Portability: Works on Linux, macOS, even WSL with minimal tweaks.
Each of these was intentionally chosen to emphasize simplicity and hackability.
🔐 Security? LOL
This project was built for trusted LAN environments, not public networks. There’s no encryption, no authentication—just raw TCP goodness. If I were to productionize this, I’d consider:
- AES encryption using
gpg
oropenssl
- Session keys and message signing
- Rate-limiting and DoS protection
But honestly? That would take away the charm.
📸 Screenshots (Sort Of)
If you’re imagining a full-blown interface—don’t.
$ bash client.sh 192.168.0.12
[shivam] hey, did you push the code?
[aditya] yeah! just now. check branch `test-lan`.
That’s it. Pure terminal bliss.
💡 What I Learned
- Bash is surprisingly capable when you push it
- HTTP is just text. You don’t need a framework to speak it.
- Simplicity isn’t just a design choice—it’s a philosophy.
- Building your own tools, even reinventing the wheel, teaches you a lot
🚀 Ideas for the Future
- A file-transfer mode (
curl
-compatible?) - Basic encryption (just for the challenge)
- TUI using
dialog
,whiptail
, or evencurses
- Rewrite in POSIX sh for fun
But maybe I won’t. Maybe I’ll just leave it as-is—a product of one night’s caffeine rush and creative joy.
🏁 Final Words
term-chat
isn’t going to replace Slack, Discord, or even IRC. But it doesn’t want to.
It’s a reminder that you can build fun, useful, and technically interesting things with nothing but a terminal and an idea.
Want to see the code? It’s all right here: https://github.com/shivammor/term-chat
Thanks for reading.