Thank you for your interest in contributing! Here's everything you need to know.
- Node.js ≥ 20
- npm ≥ 9
- Git
- A terminal (macOS, Linux, or Windows with WSL)
# 1. Fork on GitHub, then clone your fork
git clone https://github.com/<your-username>/TermBeam.git
cd TermBeam
# 2. Install dependencies (also sets up pre-commit hooks via Husky)
npm install
# 3. Verify everything works
npm test# Start with auto-generated password (recommended for dev)
npm run dev
# Start with custom options
node bin/termbeam.js --port 8080 --password dev123
# Start with default settings (no password, localhost only)
npm startOpen the printed URL on your phone or browser to test the UI.
termbeam/
├── bin/termbeam.js # CLI entry point (just requires src/server.js)
├── src/
│ ├── server.js # Main orchestrator — wires everything together
│ ├── cli.js # CLI argument parsing, --help, --version
│ ├── auth.js # Authentication, tokens, rate limiting, login page
│ ├── logger.js # Structured logger with configurable levels
│ ├── sessions.js # SessionManager class — PTY lifecycle
│ ├── shells.js # Shell detection (Windows + Unix)
│ ├── routes.js # Express HTTP routes (API + pages)
│ ├── websocket.js # WebSocket connection handling
│ ├── tunnel.js # DevTunnel integration
│ └── version.js # Smart version detection (npm vs dev)
├── public/
│ ├── index.html # Session manager UI (mobile)
│ └── terminal.html # Terminal UI (xterm.js + touch controls)
├── test/
│ ├── auth.test.js # Auth module tests
│ ├── cli.test.js # CLI argument parsing tests
│ ├── integration.test.js # Integration tests (HTTP + WebSocket)
│ ├── logger.test.js # Logger module tests
│ ├── routes.test.js # HTTP route tests
│ ├── sessions.test.js # Session manager tests (mocked PTY)
│ ├── shells.test.js # Shell detection tests
│ ├── version.test.js # Version detection tests
│ └── websocket.test.js # WebSocket handler tests
├── docs/ # MkDocs documentation source
├── .github/workflows/ # CI, release, and docs deployment
├── package.json
└── mkdocs.yml
| File | What it does | When to edit |
|---|---|---|
src/server.js |
Orchestrator | Adding new middleware or startup logic |
src/cli.js |
CLI parsing | Adding new flags or env vars |
src/routes.js |
HTTP routes | Adding new API endpoints |
src/websocket.js |
WebSocket handler | Changing terminal I/O behavior |
src/auth.js |
Auth system | Changing authentication logic |
src/sessions.js |
PTY management | Changing how sessions are created/managed |
src/logger.js |
Logging | Changing log format or levels |
src/shells.js |
Shell detection | Adding new shell types |
src/tunnel.js |
DevTunnel | Changing tunnel creation or lifecycle |
public/index.html |
Session list UI | UI changes on the main screen |
public/terminal.html |
Terminal UI | Terminal rendering, touch controls |
-
Create a feature branch:
git checkout -b feat/my-feature
-
Make your changes. The pre-commit hook will automatically:
- Format staged files with Prettier
- Syntax-check JS files with
node --check
-
Run tests locally:
npm test -
Test manually — start the server and verify on your phone:
npm run dev
We use Node.js built-in test runner (node:test + node:assert). No extra test framework needed.
# Run all tests
npm test
# Run a specific test file
node --test test/auth.test.js
# Run tests with verbose output
node --test --test-reporter=spec test/*.test.js- Tests live in
test/<module>.test.js - Use
node:test(describe/it) andnode:assert - Mock
node-ptyfor session tests (seetest/sessions.test.jsfor the pattern) - Clear
require.cachebetween tests when testing modules that readprocess.argv
- ✅ Pure logic (parsing, validation, token generation)
- ✅ Middleware behavior (auth, rate limiting)
- ✅ Session lifecycle (create, list, delete, shutdown)
⚠️ WebSocket/HTTP integration — manual testing for now
- Formatter: Prettier (runs automatically via pre-commit hook)
- Config:
.prettierrc(single quotes, trailing commas, 100 char width) - Linting:
node --checkfor syntax validation - Manual:
npm run formatto format all files,npm run lintto syntax-check
Key principles:
- Minimal dependencies — prefer built-in Node APIs
- Keep modules focused — one responsibility per file
- Comment why, not what
- Follow existing patterns in the codebase
We use Conventional Commits:
<type>(<scope>): <description>
| Type | Description | Example |
|---|---|---|
feat |
New feature | feat(auth): add OAuth2 support |
fix |
Bug fix | fix(terminal): handle resize on rotation |
docs |
Documentation | docs: update security guide |
refactor |
Code restructuring | refactor(sessions): extract PTY spawn logic |
test |
Tests | test(auth): add rate limit edge cases |
chore |
Tooling/CI | chore(ci): add Node 22 to matrix |
perf |
Performance | perf(ws): reduce JSON serialization overhead |
Breaking changes: Add ! after the type:
feat!: require password by default
- Push your branch to your fork
- Open a PR against
mainon dorlugasigal/TermBeam - Fill in the PR template (if available)
- Ensure CI passes (tests run on Node 20, 22, 24)
- Wait for review — we'll provide feedback if needed
- Tests pass locally (
npm test) - New features have tests
- Commits follow conventional format
- Documentation updated (if user-facing changes)
- Manually tested on mobile (if UI changes)
Releases are triggered manually via GitHub Actions:
- Go to Actions → Release workflow
- Click Run workflow
- Select the bump type:
- patch (0.0.x) — bug fixes, small changes
- minor (0.x.0) — new features, backward compatible
- major (x.0.0) — breaking changes
- The workflow automatically:
- Bumps the version in
package.json - Updates
CHANGELOG.mdwith commit history - Commits, tags, and pushes
- Publishes to npm
- Creates a GitHub Release with auto-generated notes
- Bumps the version in
Current: 1.2.3
→ patch bump → 1.2.4
→ minor bump → 1.3.0
→ major bump → 2.0.0
Docs are built with MkDocs Material and deployed to GitHub Pages.
# Install mkdocs locally (one-time)
pip install mkdocs-material
# Preview docs
mkdocs serve
# Docs are in docs/ directoryChanges to docs/ or mkdocs.yml pushed to main auto-deploy to GitHub Pages.
- Be kind and respectful to all contributors
- Welcome newcomers and help them get started
- Give constructive feedback
- Assume good intentions
Thank you for making TermBeam better! 📡