Skip to content

Development Guide


Project Structure

arthas/
├── arthas-client/ # Frontend (React + TypeScript)
│ ├── index.html # HTML entry point
│ ├── package.json # Dependency management
│ ├── vite.config.ts # Vite build configuration
│ ├── tsconfig.json # TypeScript configuration
│ ├── tailwind.config.js # Tailwind CSS configuration
│ ├── postcss.config.js # PostCSS configuration
│ ├── .env.development # Development environment variables
│ └── src/
│ ├── main.tsx # React entry point
│ ├── App.tsx # Root component + ErrorBoundary
│ ├── crypto/ # E2EE encryption layer
│ ├── network/ # WebSocket network layer
│ ├── stores/ # Zustand state management
│ ├── pages/ # Page components
│ ├── components/ # UI components
│ └── styles/ # Global styles
├── arthas-server/ # Backend (Go)
│ ├── go.mod # Go module definition
│ ├── go.sum # Dependency lock file
│ ├── Dockerfile # Docker build
│ ├── cmd/server/main.go # Server entry point
│ └── internal/
│ ├── room/ # Room management
│ └── network/ # Network layer
├── docs/ # Project documentation
└── official_doc/ # Official documentation

Development Environment Setup

Prerequisites

Terminal window
# Go 1.22+
go version
# Node.js 18+
node --version
# npm 9+
npm --version

Backend Development

Terminal window
cd arthas-server
# Download dependencies
go mod tidy
# Run with hot reload (requires air)
# go install github.com/cosmtrek/air@latest
# air
# Or run directly
go run cmd/server/main.go
# Run tests
go test ./...
# Build
go build -o server ./cmd/server
# Lint
go vet ./...

Frontend Development

Terminal window
cd arthas-client
# Install dependencies
npm install
# Start development server (HMR)
npm run dev
# Type checking
npx tsc --noEmit
# Build for production
npm run build
# Preview production build
npm run preview

Code Architecture Details

Backend Core Modules

Hub (internal/network/hub.go)

The connection management center, responsible for:

  • Registering/unregistering WebSocket connections
  • Message routing (dispatching to handlers based on message type)
  • Disconnect handling (automatically leaving rooms)
type Hub struct {
roomManager *room.RoomManager
clients map[*Client]bool
register chan *Client
unregister chan *Client
mu sync.RWMutex
}

Client (internal/network/client.go)

Abstraction for a single WebSocket connection:

  • readPump() — goroutine for reading messages
  • writePump() — goroutine for sending messages + heartbeat
  • Send(data []byte) — non-blocking send
  • IsRateLimited() — sliding window rate limiting

RoomManager (internal/room/manager.go)

Room lifecycle management:

  • CreateRoom(roomId) — create a room
  • GetRoom(roomId) — find a room
  • RemoveRoom(roomId) — destroy a room

Room (internal/room/room.go)

Member management for a single room:

  • AddMember(member) — add a member
  • RemoveMember(id) — remove a member
  • Broadcast(senderId, data) — broadcast message (excluding sender)

Frontend Core Modules

Encryption Layer (src/crypto/)

FileResponsibility
keys.tsKey generation, import, export
encrypt.tsAES-GCM encryption
decrypt.tsAES-GCM decryption
shareKey.tsShare code encoding/decoding
utils.tsbase64url utility functions

Network Layer (src/network/)

FileResponsibility
protocol.tsMessage type constants and TypeScript interfaces
websocket.tsWebSocket connection management, reconnection, MessagePack encoding/decoding

State Management (src/stores/chatStore.ts)

Zustand store integrating the encryption and network layers:

  • Connection state management
  • Room operations (create/join/leave)
  • Message sending (encryption) and receiving (decryption)
  • Typing indicator management
  • Rate limiting

Adding New Features

Adding a New Message Type

  1. Backend — Add constants and data structures in internal/network/protocol.go
  2. Backend — Add handler in internal/network/hub.go
  3. Frontend — Add constants and interfaces in src/network/protocol.ts
  4. Frontend — Add case in handleServerMessage in src/stores/chatStore.ts

Adding a New UI Component

  1. Create src/components/YourComponent.tsx
  2. Import it in ChatRoom.tsx or Home.tsx
  3. Get required state from chatStore

Testing

Backend Tests

Terminal window
cd arthas-server
# Run all tests
go test ./...
# With verbose output
go test -v ./...
# Run tests for a specific package
go test -v ./internal/room/...
# Race condition detection
go test -race ./...

Frontend Type Checking

Terminal window
cd arthas-client
# TypeScript type checking
npx tsc --noEmit

Manual Integration Testing

  1. Start the backend and frontend
  2. Open two browser windows
  3. Window A creates a room, copy the share code
  4. Window B joins using the share code
  5. Send messages in both directions, verify encryption/decryption works
  6. Check server logs for no plaintext

Code Style

Go

  • Follow standard Go formatting (gofmt)
  • Use go vet for linting
  • Comments in Chinese (consistent with the project)
  • Error handling without panic

TypeScript

  • Strict mode (strict: true)
  • Use function components + Hooks
  • State management via Zustand
  • Styling with Tailwind CSS classes

Dependencies

Backend Dependencies

PackageVersionPurpose
gorilla/websocketv1.5.3WebSocket server
vmihailenco/msgpack/v5v5.4.1MessagePack serialization
matoous/go-nanoid/v2v2.1.0Room ID generation
google/uuidv1.6.0Client ID generation

Frontend Dependencies

PackageVersionPurpose
react^18.3.1UI framework
react-dom^18.3.1DOM rendering
zustand^5.0.3State management
@msgpack/msgpack^3.0.0MessagePack encoding/decoding

Production Deployment

Backend Deployment (HF Spaces)

The backend is deployed as a Docker container to Hugging Face Spaces.

Prerequisites

  1. Register a Hugging Face account
  2. Create an Access Token (Settings → Tokens, select Write permission)
  3. Create a Space: https://huggingface.co/new-space
    • SDK: Docker
    • Hardware: CPU Basic (free)
    • Visibility: Public (Private URLs require authentication, frontend cannot connect)

One-Click Deploy Script

Terminal window
# Execute from project root
.\official_doc\scripts\deploy-hf-space.ps1
# Customize username and Space name
.\official_doc\scripts\deploy-hf-space.ps1 -HfUsername "your-username" -SpaceName "arthas-server"

The script will prompt for your HF username and Token for authentication.

Manual Deployment Steps

Terminal window
# 1. Copy arthas-server to a temporary directory
$tmp = "$env:TEMP\hf-deploy"
Copy-Item -Recurse arthas-server $tmp
cd $tmp
# 2. Clean build artifacts
Remove-Item -Force *.exe, *.test -ErrorAction SilentlyContinue
# 3. Initialize git and commit
git init
git add -A
git commit -m "deploy: arthas production server"
# 4. Push to HF Space
git remote add space https://huggingface.co/spaces/your-username/arthas-server
git push space master:main --force
# 5. Clean up
cd ..
Remove-Item -Recurse -Force $tmp

Important Files

  • arthas-server/Dockerfile — Multi-stage build, final image < 30MB
  • arthas-server/README.md — Contains HF Space required YAML front matter (sdk: docker)
  • arthas-server/.dockerignore — Excludes unnecessary files to speed up builds

Verification

After the build completes (approximately 2-3 minutes), visit:

https://your-username-arthas-server.hf.space/ping

A pong response indicates successful deployment.

Environment Variable Configuration

Set in Space Settings → Repository secrets:

VariableValueDescription
ALLOWED_ORIGINShttps://your-frontend.vercel.appAllowed frontend domains (comma-separated for multiple)

Restart the Space after setting for changes to take effect.


Frontend Deployment (Vercel)

The frontend is deployed to Vercel, selecting the arthas-client subdirectory from the GitHub monorepo.

Steps

  1. Push the entire arthas project to GitHub
  2. Visit vercel.com/new, import the GitHub repository
  3. Configure:
    • Root Directory: arthas-client
    • Framework Preset: Vite
    • Environment Variables: VITE_WS_URL = wss://your-username-arthas-server.hf.space/ws
  4. Click Deploy

Verification

After deployment, open the domain assigned by Vercel and check the browser Network panel to confirm the WebSocket connection uses wss://.


Keep-Alive Configuration (cron-job.org)

HF Spaces free tier goes to sleep when there is no traffic. Configure scheduled health checks to keep it active:

  1. Register at cron-job.org
  2. Create a job:
    • URL: https://your-username-arthas-server.hf.space/ping
    • Interval: Every 10 minutes
    • Timeout: 30 seconds
    • Failure retry: 1 time

Post-Deployment Verification Checklist

#Verification ItemMethodExpected Result
1Health checkVisit /ping200 + “pong”
2WSS connectionBrowser Network panelWebSocket uses wss://
3Cross-network chatTwo devices create/join roomMessages encrypt/decrypt normally
4No plaintext in logsCheck HF Space logsNo message content
5CORS blockingConnect from unauthorized domainReturns 403

Next Steps