https://github.com/cod-e-codes/marchat
Terminal-based group chat app with real-time WebSocket messaging, file sharing, themes, and admin tools β built with Go and Bubble Tea.
https://github.com/cod-e-codes/marchat
bubble-tea chat chat-app file-sharing go golang real-time self-hosted terminal tui websocket
Last synced: 5 months ago
JSON representation
Terminal-based group chat app with real-time WebSocket messaging, file sharing, themes, and admin tools β built with Go and Bubble Tea.
- Host: GitHub
- URL: https://github.com/cod-e-codes/marchat
- Owner: Cod-e-Codes
- License: mit
- Created: 2025-07-16T15:48:32.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-07-26T21:48:31.000Z (5 months ago)
- Last Synced: 2025-07-27T01:20:19.271Z (5 months ago)
- Topics: bubble-tea, chat, chat-app, file-sharing, go, golang, real-time, self-hosted, terminal, tui, websocket
- Language: Go
- Homepage: https://github.com/Cod-e-Codes/marchat
- Size: 222 KB
- Stars: 33
- Watchers: 1
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# marchat π§
[](https://github.com/Cod-e-Codes/marchat/actions/workflows/go.yml)
[](LICENSE)
[](https://github.com/Cod-e-Codes/marchat)
[](https://go.dev/dl/)
[](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/)
## Table of Contents
- [Beta Release](#beta-release)
- [Features](#features)
- [Quick Start](#quick-start)
- [Usage](#usage)
- [Project Structure](#project-structure)
- [Admin Mode](#admin-mode-privileged-commands--security)
- [Security](#security)
- [Tech Stack](#tech-stack)
- [Troubleshooting](#troubleshooting)
- [Contributing & Feedback](#contributing--feedback)
- [What's Next](#whats-next)
- [License](#license)
---
## What is this?
`marchat` is a minimalist terminal-based group chat app designed for real-time, distraction-free conversations. Whether you're pair programming, self-hosting a LAN party, or just chatting from two terminals, it's lightweight, hackable, and built for fun.
## Why marchat?
Built for father-son coding sessions, marchat is about sharing the joy of hacking, learning, and chatting in a terminal. It's a fun, retro-inspired project for anyone who loves the command line, real-time collaboration, or just wants a simple, self-hosted chat.
---
## Beta Release
`marchat` is currently in a pre-release phase with version `v0.1.0-beta.2`. This is the second public beta release, featuring prebuilt binaries for Linux, Windows, and macOS (amd64 only). The release includes both `marchat-server` and `marchat-client` executables, allowing you to test the application without building from source. This release includes clipboard support and bug fixes from `v0.1.0-beta.1`.
> [!IMPORTANT]
> This is a beta release intended for early testing and feedback. While stable for general use, some features may change or be refined before the first stable release. Please share your feedback in [GitHub Discussions](https://github.com/Cod-e-Codes/marchat/discussions), or report bugs on the [GitHub Issues page](https://github.com/Cod-e-Codes/marchat/issues).
### Installing the Beta Release
1. **Download the binaries**:
- Visit the [v0.1.0-beta.2 release page](https://github.com/Cod-e-Codes/marchat/releases/tag/v0.1.0-beta.2).
- Download the appropriate archive for your platform (Linux, Windows, or macOS, amd64 only).
- Extract the archive to a directory of your choice.
2. **Run the server**:
```sh
./marchat-server
```
- Optionally, start the server with admin privileges:
```sh
./marchat-server --admin YourName --admin-key your-admin-key
```
3. **Run the client**:
```sh
# Linux/macOS
./marchat-client --username Cody --theme patriot --server ws://localhost:9090/ws
# Windows
marchat-client.exe --username Cody --theme patriot --server ws://localhost:9090/ws
```
- Alternatively, use a `config.json` file (see [Quick Start](#quick-start) for details).
> [!NOTE]
> For the beta release, we recommend using the prebuilt binaries (`marchat-server` and `marchat-client`) instead of building from source. The binaries are standalone and include all dependencies.
> [!TIP]
> To provide feedback on the beta release, share your thoughts in [GitHub Discussions](https://github.com/Cod-e-Codes/marchat/discussions). Found a bug? Create an issue on the [GitHub Issues page](https://github.com/Cod-e-Codes/marchat/issues) with your platform details and steps to reproduce. Check the [Full Changelog](https://github.com/Cod-e-Codes/marchat/commits/v0.1.0-beta.2) for details on what's included in this release.
---
## Features
- **Terminal UI (TUI):** Beautiful, scrollable chat using [Bubble Tea](https://github.com/charmbracelet/bubbletea)
- **Real-time WebSocket Chat:** Fast, robust, and cross-platform server/client
- **Themes:** Choose from `patriot`, `retro`, or `modern` for a unique look
- **Small File Sharing (<1MB):** Instantly send and receive small files with `:sendfile ` and save them with `:savefile `
- **Emoji Support:** Auto-converts common ASCII emoji (e.g., `:)`, `:(`, `:D`, `<3`, `:P`) to Unicode
- **Live User List:** See whoβs online in a fixed-width, styled panel (up to 20 users shown)
- **@Mention Highlighting:** Messages with `@username` highlight for all users in the chat
- **Clipboard Support:** Copy (`Ctrl+C`), paste (`Ctrl+V`), cut (`Ctrl+X`), and select all (`Ctrl+A`) in the textarea
- **Admin Mode:** Privileged commands (like `:cleardb`) for authenticated admins only
- **Message Cap:**
- Only the last 100 messages are kept in memory for client performance
- The server database automatically caps messages at 1000; oldest messages are deleted to make room for new ones
- **Configurable:** Set username, server URL, and theme via config file or flags
- **Graceful Shutdown:** Clean exit and robust connection handling (ping/pong heartbeat)
- **ASCII Art Banner:** Server displays a beautiful banner with connection info on startup
---
## Prerequisites
- Install [Go 1.24+](https://go.dev/dl/) if you havenβt already (only needed if building from source)
- *(Check with `go version` in your terminal)*
- (Optional, for remote access) Download [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/) (`cloudflared.exe` on Windows)
- (Optional, for clipboard support on Linux) Install `xclip` or `xsel` for `github.com/atotto/clipboard` functionality
## Quick Start
> [!NOTE]
> You can configure marchat via flags or a `config.json`. Flags override config file values. For the beta release, use the prebuilt binaries as described in [Beta Release](#beta-release).
### 1. Clone the repo (if building from source)
```sh
git clone https://github.com/Cod-e-Codes/marchat.git
cd marchat
```
### 2. Install Go dependencies (if building from source)
```sh
go mod tidy
```
### 3. Build the project (if building from source)
```sh
go build ./...
```
### 4. Create a server config file (REQUIRED)
Create `server_config.json` in the project root:
```json
{
"port": 9090,
"admins": ["Cody", "Crystal"],
"admin_key": "your-admin-key"
}
```
> [!NOTE]
> The server now requires a config file. Command-line flags are deprecated and will be removed in a future release.
### 5. Run the server (port 9090, WebSocket)
Using the prebuilt binary:
```sh
./marchat-server
```
Or, if building from source:
```sh
go run cmd/server/main.go
```
> [!TIP]
> You can override config values with flags, but this is deprecated and will be removed. Always prefer the config file.
### 6. (Optional) Create a config file
Create `config.json` in the project root:
```json
{
"username": "Cody",
"server_url": "ws://localhost:9090/ws",
"theme": "patriot",
"twenty_four_hour": true
}
```
> [!NOTE]
> If no `config.json` is found, the client uses default values. Specify a custom config path with `--config`.
### 7. Run the client
Using the prebuilt binary:
```sh
# Linux/macOS
./marchat-client --username Cody --theme patriot --server ws://localhost:9090/ws
# Windows
marchat-client.exe --username Cody --theme patriot --server ws://localhost:9090/ws
```
Or, if building from source:
```sh
go run client/main.go --username Cody --theme patriot --server ws://localhost:9090/ws
```
Or with a config file:
```sh
./marchat-client --config config.json
```
> [!IMPORTANT]
> Ensure the server URL uses `ws://` for local development or `wss://` for production (secure WebSocket).
---
## Remote Access (Optional)
If you want to make your marchat server accessible from outside your local network (e.g., to chat with friends remotely), use [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
### 1. Download cloudflared
- [Get cloudflared for your OS](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/)
### 2. Start a tunnel to your local server
```sh
cloudflared tunnel --url http://localhost:9090
```
> [!TIP]
> Cloudflare provides a public `https://` URL. Convert it to `wss://.../ws` for the client (e.g., `https://bold-forest-cat.trycloudflare.com` becomes `wss://bold-forest-cat.trycloudflare.com/ws`).
### 3. Update your client config
```sh
./marchat-client --username Cody --admin --admin-key your-admin-key --server wss://bold-forest-cat.trycloudflare.com/ws
```
> [!NOTE]
> Temporary tunnels donβt require a Cloudflare account. For persistent tunnels, see the [Cloudflare Tunnel docs](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/).
---
## Usage
Interact with marchat using the following commands and features:
- **Send messages**: Type and press `Enter`.
- **File sharing**:
- Send files (<1MB): `:sendfile `
- Save received files: `:savefile `
- If a file with the same name exists, a numeric suffix will be added (e.g., `file[1]`, `file[2]`, etc.). The actual saved filename will be shown in the UI.
- **Emoji support**: Auto-converts ASCII emoticons to Unicode (`:)`, `:(`, `:D`, `<3`, `:P`).
- **Mentions**: Use `@username` to highlight a user (full message highlighted).
- **Clipboard operations**:
- Copy text: `Ctrl+C` (copies textarea content to clipboard)
- Paste text: `Ctrl+V` (appends clipboard content to textarea)
- Cut text: `Ctrl+X` (copies textarea content to clipboard and clears textarea)
- Select all: `Ctrl+A` (copies all textarea content to clipboard)
- **Scroll**: Use Up/Down arrows or mouse to navigate chat history.
- **Commands**:
- `:theme `: Switch theme (`patriot`, `retro`, `modern`; persists in config).
- `:time`: Toggle 12/24-hour timestamp format (persists in config).
- `:clear`: Clear local chat buffer (client-side only, does not affect others).
- `:cleardb`: Wipe entire server database (admin only).
- **User list**: Displays up to 20 online users, with a styled `+N more` indicator for additional users.
- **ASCII art banner**: Shows connection info on server startup (disable via config or flag).
- **Quit**: Press `Esc` to exit.
- **Clipboard shortcuts**: `[Ctrl+C]` Copy, `[Ctrl+V]` Paste, `[Ctrl+X]` Cut, `[Ctrl+A]` Select All (copies all to clipboard).
> [!CAUTION]
> The `:cleardb` command permanently deletes all messages in the server database. Use with caution, as this action cannot be undone.
> [!NOTE]
> File transfers are limited to 1MB to ensure performance. Larger files should be shared via other methods.
---
## Project Structure
```
marchat/
βββ client/ # TUI client (Bubble Tea)
β βββ main.go
β βββ config/
β βββ config.go
βββ cmd/server/ # Server entrypoint
β βββ main.go
βββ server/ # Server logic (DB, handlers, WebSocket)
β βββ db.go
β βββ handlers.go
β βββ client.go
β βββ hub.go
β βββ schema.sql
βββ shared/ # Shared types
β βββ types.go
βββ config.json # Example or user config file (see Quick Start)
βββ go.mod
βββ go.sum
βββ README.md
```
Modular architecture: client, server logic, and shared types are separated for clarity and maintainability.
---
## Admin Mode: Privileged Commands & Security
> [!IMPORTANT]
> Admin commands like `:cleardb` require the `--admin` flag and a matching `--admin-key`. Only users listed as admins on the server can authenticate.
**Server Config (server_config.json):**
```json
{
"port": 9090,
"admins": ["Cody", "Crystal"],
"admin_key": "your-admin-key"
}
```
**To connect as admin:**
```sh
./marchat-client --username Cody --admin --server wss://localhost:9090/ws
# (admin_key will be read from config or env)
```
> [!WARNING]
> Do not use the default admin key (`changeme`) in production. Change it immediately to prevent unauthorized access.
- Admin usernames are case-insensitive.
- The admin key is sent only during the WebSocket handshake.
- All admin actions use WebSocket (no HTTP endpoints).
---
## Security
> [!WARNING]
> For production deployments:
> - Change the default admin key (`changeme`) to a secure value.
> - Use `wss://` for secure WebSocket connections.
> - Ensure firewall rules allow your chosen port (default: 9090).
> - Consider a reverse proxy (e.g., nginx) for added security.
---
## Tech Stack
- [Go](https://golang.org/) 1.24+
- [Bubble Tea](https://github.com/charmbracelet/bubbletea) (TUI)
- [Lipgloss](https://github.com/charmbracelet/lipgloss) (styling)
- [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite) (pure Go SQLite, no C compiler required)
- [Gorilla WebSocket](https://github.com/gorilla/websocket) (real-time messaging)
- [atotto/clipboard](https://github.com/atotto/clipboard) (clipboard operations for copy, paste, cut, and select all)
**Platform Support**: Runs on Linux, macOS, and Windows terminals supporting ANSI escape sequences. Clipboard functionality on Linux requires `xclip` or `xsel`.
---
## Troubleshooting
- **Panic: `close of closed channel`**
- Fixed: The client now guards against double-close of internal channels.
- **Client fails to connect with `http://` URL**
- Use a WebSocket URL: `ws://localhost:9090/ws` or `wss://...` for remote.
- **Mentions not highlighted**
- Use `@username` exactly (word boundary, not substring).
- **User list not updating**
- Ensure server and client are both up to date and using compatible protocols.
- **Messages not showing or chat not updating**
- Check your WebSocket connection and server logs for errors.
- **Old messages missing from chat history**
- The server database only keeps the most recent 1000 messages.
- **Too many users in user list**
- Only up to 20 users are shown, with a styled `+N more` indicator.
- **Clipboard operations not working**
- Ensure `xclip` or `xsel` is installed on Linux for `github.com/atotto/clipboard`.
- Verify the textarea is focused when using `Ctrl+C`, `Ctrl+V`, `Ctrl+X`, or `Ctrl+A`.
- **Firewall/Port**: Ensure port 9090 is open for remote connections.
- **Admin commands**
- Ensure `--admin` and `--admin-key` match server settings.
> [!TIP]
> When reporting bugs, include your version or commit hash for faster resolution. For beta release issues, specify that you're using `v0.1.0-beta.2`.
---
## Contributing & Feedback
We welcome all contributions to marchat! Here's how to get involved:
### Where to Post
- **GitHub Issues** - For bugs and problems:
- Crashes and error messages
- Unexpected behavior
- Performance problems
- Security concerns
- Always include your OS, version, and steps to reproduce
- **GitHub Discussions** - For ideas and questions:
- Feature requests and suggestions
- Questions about setup or usage
- Share your experience
- Show off your customizations
- General feedback and ideas
> [!TIP]
> Not sure where to post? Start a discussion! We can always convert it to an issue if needed.
### Contributing Code
See [CONTRIBUTING.md](CONTRIBUTING.md) for:
- Code style guidelines
- Pull request process
- Development setup
- Build and test instructions
### Code of Conduct
We follow a [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a welcoming community for all. Please read it before participating.
> [!IMPORTANT]
> Please keep all interactions respectful, constructive, and on-topic. It helps improve the project for everyone.
---
## Automation
- **Dependency Updates:** marchat uses [Dependabot](https://github.com/dependabot) to automatically check for and propose updates to Go module dependencies.
- **Continuous Integration:** All pushes and pull requests are checked by [GitHub Actions](https://github.com/Cod-e-Codes/marchat/actions) for build, test, and linting. Please ensure your PR passes CI before requesting review.
---
## What's Next
marchat is under active development. Near-term priorities include:
- Unifying and stabilizing configuration across the client and server
- Expanding notification support (e.g., native system alerts, VS Code integration)
- Laying the groundwork for a plugin and extensibility system
Long-term goals are still evolving. Community input is welcome.
---
## License
This project is licensed under the [MIT License](LICENSE).