Skip to content

Term-chat; A bash-based LAN chat application

Published on
Written by Shivam Mor

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 or openssl
  • 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 even curses
  • 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.

Check Out Other Pages

Happening now
See what I am recently up to
Now Page
Happening now
Work Experience
See full working experience I have
Now Page
Work Experience
Read Notes
Read my notes about what I've learned
Now Page
Read Notes
View Resume
Interested in my resume? view my resume
Now Page
View Resume