An interactive resume/portfolio accessible via SSH, built with Go and Charm libraries. Present your professional information in a beautiful terminal UI with a file-tree navigation system that users can access by simply SSH-ing to your server.
- 📂 File-Tree Navigation - Organize your content in a familiar directory structure with support for nested folders.
- 📄 Split-View Interface - Clean split-pane layout with a sidebar for navigation and a main viewport for content.
- 🎨 Markdown Support - Write content in markdown with syntax highlighting via Glamour.
- ⌨️ Keyboard Navigation - Intuitive vim-like keybindings for browsing and reading.
- 🔐 SSH Server - Self-hosted SSH server with automatic host key generation.
Connect to see it in action:
ssh resume.fullydisfunctional.com- Go 1.25.3 or later
- SSH client (for testing)
# Clone the repository
git clone https://github.com/vinayakankugoyal/sshresume.git
cd sshresume
# Install dependencies
make install
# Build the binary
make buildThe binary will be available at bin/sshresume.
make build-linux-amd64The binary will be available at bin/linux/amd64/sshresume.
# Run with default settings (localhost:23234)
./bin/sshresume
# Or use make
make run
# Development mode with go run
make dev./bin/sshresume [options]
Options:
-host string
address to bind to (default "localhost")
-port string
port to bind to (default "23234")
-dir string
path to content directory (default "./")The application is configured by pointing it to a directory containing your markdown files using the -dir flag.
The UI will automatically generate a navigation tree based on the directory structure.
- Directories become expandable nodes in the sidebar.
- Markdown files (
.md) become selectable items. - Hidden files/folders (starting with
.) are ignored. - Items are sorted with directories first, then files alphabetically.
Example Structure:
content/
├── 01-About.md
├── 02-Experience/
│ ├── Job1.md
│ └── Job2.md
├── 03-Projects/
│ ├── ProjectA.md
│ └── ProjectB.md
└── 04-Contact.md
To run with this structure:
./bin/sshresume -dir ./content| Key | Action |
|---|---|
Tab |
Toggle focus between Sidebar and Content |
q / Ctrl+C |
Quit |
| Key | Action |
|---|---|
j / ↓ |
Move cursor down |
k / ↑ |
Move cursor up |
Enter / Space |
Expand directory / Open file |
| Key | Action |
|---|---|
j / ↓ |
Scroll down |
k / ↑ |
Scroll up |
d / u |
Page down / Page up |
# Format code
make fmt
# Run linter (requires golangci-lint)
make lint
# Clean build artifacts
make cleanOn first run, the server will generate an SSH host key at .ssh/id_ed25519 if it doesn't exist. This key is used to identify your SSH server.
- Build the binary for your target platform.
- Copy the binary and your content folder to your server.
- Run the binary with appropriate host and port settings, pointing it to your content folder.
- Configure your firewall to allow traffic on the SSH port.
[Unit]
Description=SSH Resume Server
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/sshresume
ExecStart=/path/to/sshresume/bin/sshresume -host 0.0.0.0 -port 23234 -dir /path/to/content
Restart=on-failure
[Install]
WantedBy=multi-user.target- Go
- Bubble Tea - TUI framework
- Glamour - Markdown rendering
- Lipgloss - Styling
- Wish - SSH server
- Bubbles - TUI components
This project is open source and available under the MIT License.
Vinayak Goyal
- Email: vinayaklovespizza@gmail.com
- GitHub: github.com/vinayakankugoyal
- LinkedIn: linkedin.com/in/vinayakgoyal