I built a personal website that isn't a typical website. Instead of using HTML and CSS, it runs entirely inside a terminal user interface (TUI). You can access it in two ways:
- From your browser: www.dreralabs.xyz (which runs in a terminal emulator over WebSocket)
- Directly from your terminal:
ssh www.dreralabs.xyz
In this post, I'll show you how this crazy idea works, the architecture behind it, and the tools that made it possible.
The Idea: Why a Website in the Terminal?
As a Linux and command-line enthusiast, I spend most of my day in a terminal. The idea for Drera Labs came from a question: "What if my personal website was an extension of my favorite work environment?".
I wanted to create something that was:
- Fast and lightweight: Without the overhead of heavy JavaScript frameworks.
- Interactive: Using TUI tools to create a "glamorous" terminal experience.
- Accessible: Available to those who prefer the convenience of the web and those who live in the terminal.
The result is a site where navigation, reading posts, and even submitting forms happen in a shell environment.
How It Works: The Architecture
The project's magic lies in unifying web and SSH access into a single terminal experience. The backend is written in Go and orchestrates everything.
Here's a summary of the architecture:
-
Dual Entry Point:
- An HTTP/WebSocket server (port 8080) serves a minimal HTML page that opens a WebSocket connection.
- An SSH server (port 2221) accepts direct connections from SSH clients.
WebSocket to SSH Proxy:
On the frontend, the browser runs a terminal emulator built with xterm.js. When a client connects via the browser, the Go server doesn't interpret the commands. Instead, it acts as a proxy, opening a connection to its own local SSH server. This is the key trick: every interaction, whether from the web or SSH, is treated as a standard SSH session. This vastly simplifies the logic, as we only need to worry about managing SSH sessions.-
Session Management with Zellij:
For each new connection, the server starts a Zellij session, a modern terminal multiplexer. Zellij is configured with two main files:-
layout.kdl
: Defines the interface structure, splitting the screen into panes for the navigation bar, content area, and status bars. -
config.kdl
: Customizes the theme, shortcuts, and overall behavior of Zellij.
-
-
Navigation with Shell Scripts and
gum
:
Navigation is controlled by a series of shell scripts that communicate through a named pipe (FIFO).- The navigation pane runs a script that uses
gum
, a tool for creating "glamorous" TUIs, to display a menu of options. - When an option is selected, the name of the corresponding script (e.g.,
blog.sh
) is written to the pipe. - The main content pane has a "router" script that continuously reads from the pipe. When it receives a new command, it executes the appropriate script to display the content for that section.
- The navigation pane runs a script that uses
Content Rendering with
glow
:
The pages and blog posts are written in Markdown. To display them beautifully in the terminal, the scripts useglow
, which renders Markdown on the command line with style.
The Tech Stack
- Backend: Go
- Web/WebSocket Server:
gorilla/websocket
- SSH Server:
gliderlabs/ssh
- Web/WebSocket Server:
- Frontend:
- Terminal Emulator: xterm.js
- Terminal UI:
- Multiplexer: Zellij
- TUI Tools:
gum
(for menus, forms, etc.) - Markdown Renderer:
glow
- Scripting Language: Shell (Bash)
- Containerization: Docker and HAProxy
Conclusion
Drera Labs is a fun experiment that explores the boundaries between the web and the terminal. It shows that it's possible to create rich, interactive experiences using only the tools that many of us already love and use every day.
The project is open source, and you can check out the full repository on GitHub: github.com/gustavosbarreto/drera-labs
Feel free to explore, give feedback, or even fork it to create your own version. And the next time you think about building a website, maybe consider building it for the terminal!
Top comments (2)
Similar to my github.com/ccbikai/ssh-ai-chat , but I don't have a web service.
Thanks for sharing, I hadn't seen this before