A modern, multi-platform presentation system built in Rust with real-time synchronization across devices.
Toboggan is a presentation system that allows you to create, serve, and control slide-based presentations across multiple platforms. Write your slides in Markdown or TOML, serve them via a WebSocket-enabled server, and present from any client - web browser, terminal, desktop app, or mobile device.
Note: This is an educational and fun project created to explore Rust's capabilities across different platforms - from embedded systems to web browsers. While fully functional, it's designed primarily for learning and experimentation rather than production use. It's a playground to demonstrate how Rust can target everything from microcontrollers to iOS apps!
- 📝 Simple Content Creation: Write presentations in Markdown or TOML format
- 🔄 Real-time Synchronization: Multi-client synchronization via WebSocket protocol
- 🌐 Multi-platform Clients: Web, Terminal, Desktop, iOS, and embedded support
- 🎯 Educational Focus: Perfect for exploring Rust ecosystem
Pre-compiled binaries for Linux, macOS, and Windows are available on the Releases page.
Each release includes:
toboggan-cli— convert Markdown to TOMLtoboggan-server— WebSocket presentation servertoboggan-tui— terminal UI client
Linux/macOS:
# Download the latest release
curl -sSfL https://github.com/Tednoob17/toboggan/releases/latest/download/toboggan-x86_64-unknown-linux-gnu.tar.gz -o toboggan.tar.gz
# Extract and install to /usr/local/bin (system-wide)
tar -xzf toboggan.tar.gz
sudo cp toboggan-x86_64-unknown-linux-gnu/* /usr/local/bin/
# Or install to ~/.local/bin (user-only, no sudo needed)
mkdir -p ~/.local/bin
cp toboggan-x86_64-unknown-linux-gnu/* ~/.local/bin/
# Make sure ~/.local/bin is in your PATH:
# echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
# Verify
toboggan-cli --help
toboggan-server --help
toboggan-tui --helpWindows:
# Download and extract
curl -sSfL https://github.com/Tednoob17/toboggan/releases/latest/download/toboggan-x86_64-pc-windows-msvc.tar.gz -o toboggan.zip
# Extract to a folder and add it to your PATH (System Properties → Environment Variables)# Download individual .deb packages
curl -sSfL https://github.com/Tednoob17/toboggan/releases/latest/download/toboggan-cli_0.1.0-1_amd64.deb -o toboggan-cli.deb
curl -sSfL https://github.com/Tednoob17/toboggan/releases/latest/download/toboggan-server_0.1.0-1_amd64.deb -o toboggan-server.deb
curl -sSfL https://github.com/Tednoob17/toboggan/releases/latest/download/toboggan-tui_0.1.0-1_amd64.deb -o toboggan-tui.deb
# Install them
sudo dpkg -i toboggan-cli.deb toboggan-server.deb toboggan-tui.deb
# Install dependencies if missing
sudo apt-get install -f# Create a systemd service file
sudo tee /etc/systemd/system/toboggan.service << 'EOF'
[Unit]
Description=Toboggan Presentation Server
After=network.target
[Service]
ExecStart=/usr/local/bin/toboggan-server /path/to/your/presentation.toml
Restart=on-failure
User=youruser
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable toboggan.service
sudo systemctl start toboggan.service
# View logs
journalctl -u toboggan.service -fStep 1: Install Rust
If you don't have Rust installed yet:
# Download and install Rust (choose default options when prompted)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Restart your terminal or run:
source "$HOME/.cargo/env"Step 2: Build Toboggan
# Clone the repository
git clone https://github.com/Tednoob17/toboggan
cd toboggan
# Build the main workspace (CLI + server + TUI)
cargo build --release
# For the desktop app (requires more RAM and GPU drivers):
cargo build --release --manifest-path toboggan-desktop/Cargo.toml
# Run the server with an example presentation
cargo run -p toboggan-server -- "slides_ex/presentations/How to Fuzz Like a Pro/How to Fuzz Like a Pro.toml"# Build the Building Secure Smart Contracts talk from source slides
cargo run -p toboggan-cli -- "slides_ex/presentations/Building Secure Smart Contracts/" -o my-talk.toml
cargo run -p toboggan-server -- my-talk.toml
# Or serve the pre-built How to Fuzz Like a Pro talk directly
cargo run -p toboggan-server -- "slides_ex/presentations/How to Fuzz Like a Pro/How to Fuzz Like a Pro.toml"Then open http://localhost:8080 in your browser.
# Convert Markdown to TOML
cargo run -p toboggan-cli -- path/to/slides/ -o my-talk.toml
# Or create TOML directly
cat > my-talk.toml << 'EOF'
title = "My Presentation"
date = "2026-05-30"
[[slides]]
kind = "Cover"
[slides.title]
type = "Text"
text = "Welcome"
[[slides]]
kind = "Standard"
[slides.title]
type = "Text"
text = "Hello!"
[slides.body]
type = "Text"
text = "This is my first slide."
EOF# Start the server
cargo run -p toboggan-server -- my-talk.toml
# Open web interface
open http://localhost:8080
# Or use terminal client
cargo run -p toboggan-tui -- --host localhost --port 8080To run the Android client:
- Install Android Studio and the Android NDK (25+).
- Add Rust Android targets:
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
- From the repo root, generate the native libraries and Kotlin bindings:
mise build:android
- Open
toboggan-android/in Android Studio and run on an emulator or device. Use10.0.2.2:8080on the emulator to reach the host server; for physical devices update the server URL inPresentationViewModel.kt.
- Rust 1.83+ (2024 edition)
- Node.js 20+ (for web frontend)
mise(optional, for task automation)
The project is split into two Cargo workspaces to manage build resources:
toboggan/ # Main workspace (fast build, ~4 GB RAM)
├── toboggan-core/ # Core domain models (no_std compatible)
├── toboggan-stats/ # Slide statistics engine
├── toboggan-server/ # Axum WebSocket + REST server
├── toboggan-cli/ # Markdown → TOML CLI
├── toboggan-client/ # Shared WebSocket client library
├── toboggan-tui/ # Terminal UI (ratatui)
└── toboggan-mobile/ # iOS/Android Rust library via UniFFI
toboggan-desktop/ # Separate workspace (iced + wgpu)
# Heavier build, compiled independently
# See "Desktop" section below
Why 2 workspaces?
toboggan-desktopusesicedwhich pulls the entire Rust GPU ecosystem (wgpu, naga, ash...). Isolating it keeps the main build fast and compatible with free CI runners (7 GB RAM limit).
| Component | Prerequisites | RAM | Notes |
|---|---|---|---|
toboggan-server |
Rust only | ~2 GB | Works headless, web UI optional |
toboggan-cli |
Rust only | ~2 GB | Markdown → TOML converter |
toboggan-tui |
Rust only | ~2 GB | Needs a real TTY (works over SSH) |
toboggan-desktop |
Rust + GPU libs | ~8 GB | Separate workspace (iced/wgpu) |
| Web frontend | Node.js + npm + wasm-pack | ~2 GB | Required for browser UI |
| iOS app | Xcode + Rust targets | ~4 GB | macOS only |
| ESP32 | ESP-IDF toolchain | ~2 GB | Embedded target |
# Main build (CLI + server + TUI — fast, ~4 GB RAM)
cargo build --release
# Desktop build (iced/wgpu — separate, ~8+ GB RAM)
cargo build --release --manifest-path toboggan-desktop/Cargo.toml
# Or in one command
cargo build --release && cargo build --release --manifest-path toboggan-desktop/Cargo.toml
# Light build (essentials only)
cargo build --release -p toboggan-cli -p toboggan-server -p toboggan-tuiThe browser UI requires the WASM crate. Without it, the server still works
but shows a placeholder page at http://localhost:8080.
# 1. Install wasm-pack (https://wasm-pack.rs/)
# Download pre-built binary (faster than cargo install):
curl -sSfL https://github.com/rustwasm/wasm-pack/releases/download/v0.15.0/wasm-pack-v0.15.0-x86_64-unknown-linux-musl.tar.gz \
-o /tmp/wasm-pack.tar.gz
tar -xzf /tmp/wasm-pack.tar.gz -C /tmp/
cp /tmp/wasm-pack-v0.15.0-x86_64-unknown-linux-musl/wasm-pack ~/.cargo/bin/
wasm-pack --version
# For macOS/Windows, see docs/src/installation.md
# 2. Add the WASM target
rustup target add wasm32-unknown-unknown
# 3. Install JS dependencies and build
cd toboggan-web
npm install
# 4. Build the WASM crate first
cd toboggan-wasm
wasm-pack build --target web --release
cd ..
# 5. Build the TypeScript frontend
npm run build
cd ..Then rebuild the server to embed the frontend:
cargo build --release -p toboggan-serverQuick alternative: skip the web UI and use the TUI client instead (
toboggan-tui --host <ip> --port 8080). It works over SSH and needs no JavaScript toolchain.
mise build:ios
# Or manually:
cd toboggan-mobile
./build.shRequires macOS with Xcode installed.
# Build from the dedicated workspace
cargo build --release --manifest-path toboggan-desktop/Cargo.toml
# Or directly from the folder
cd toboggan-desktop && cargo build --releaseNote: Desktop requires ~8+ GB RAM and system GPU libraries
(libxkbcommon-dev, libwayland-dev, libegl1-mesa-dev on Linux).
On memory-constrained or headless machines, use the TUI or web client instead.
cargo build -p toboggan-tui --releaseThe TUI works in any terminal (including SSH). No special dependencies needed — just a real TTY (not a CI or tool sub-shell).
Toboggan is designed as a modular system with clear separation of concerns. The architecture follows Clean Architecture principles with well-defined boundaries between components.
The project is organized into two Cargo workspaces to manage build resources:
toboggan/ # MAIN workspace (~4 GB RAM build)
├── toboggan-core/ # Core domain models (no_std compatible)
├── toboggan-stats/ # Slide statistics engine
├── toboggan-server/ # Axum WebSocket + REST server
├── toboggan-cli/ # Command-line Markdown → TOML converter
├── toboggan-client/ # Shared async WebSocket client
├── toboggan-tui/ # Terminal UI (ratatui + crossterm)
├── toboggan-mobile/ # iOS/Android bindings via UniFFI
├── toboggan-web/ # TypeScript frontend + WASM crate
└── TobogganApp/ # SwiftUI iOS application
toboggan-desktop/ # SEPARATE workspace (iced + wgpu)
# Heavier build, compiled independently
# See "Building" section for instructions
toboggan-esp32/ # ESP32 embedded (excluded, future)
toboggan-py/ # Python bindings (excluded, future)
Why 2 workspaces?
toboggan-desktopusesicedwhich pulls the entire Rust GPU ecosystem (wgpu, naga, ash...). By isolating it, the main build stays fast and fits in 4-6 GB RAM, compatible with free CI runners.
- WebSocket Protocol: JSON-based real-time communication
- Memory Safety: Zero (direct) unsafe code, comprehensive error handling
- Cross-platform: Single codebase targeting multiple platforms
- Modular Design: Clear separation between server, clients, and core logic
Toboggan supports multiple client types, each optimized for different use cases and platforms.
- Technology: TypeScript frontend with WASM client
- Features: Modern web interface, keyboard shortcuts, responsive design
- Usage: Open
http://localhost:8080when server is running - Platform: Any modern web browser
- Technology: ratatui with crossterm
- Features: Full-featured terminal interface, presenter view, slide navigation
- Usage:
cargo run -p toboggan-tui - Platform: Linux, macOS, Windows terminals
- Technology: iced native GUI framework
- Features: Native desktop experience with system integration
- Usage:
cargo run -p toboggan-desktop - Platform: Linux, macOS, Windows native
- Technology: SwiftUI with Rust core via UniFFI
- Features: Native iOS interface, gesture controls, AirPlay support
- Usage: Build and run from Xcode
- Platform: iOS 16+ devices and simulator
- Technology: ESP-IDF with embedded-graphics
- Hardware: ESP32-S3-BOX-3B development board
- Features: WiFi connectivity, LCD display, LED indicators
- Platform: ESP32 microcontrollers
Toboggan uses a simple JSON-based WebSocket protocol for real-time synchronization:
Register,Unregister,Ping- Connection managementFirst,Last,GoTo { slide: N }- Slide navigationNextSlide,PreviousSlide- Step through slidesNextStep,PreviousStep- Step through progressive revealsBlink- Visual notification effect
State { current_slide, state }- Presentation state updatesError { message }- Error notificationsPong- Heartbeat responseBlink- Visual notificationTalkChange- Talk file reloadedRegistered- Registration confirmationClientConnected,ClientDisconnected- Peer events
cargo test # All tests
cargo nextest run # Faster parallel tests
cargo test -p toboggan-core # Specific cratecargo fmt # Format code
cargo clippy # Lint code
mise check # All checkscargo doc --open # Generate and open docsWe welcome contributions to Toboggan! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Make your changes following the project guidelines
- Run tests:
mise checkorcargo test - Submit a pull request
- Code Quality: All code must pass
cargo fmt,cargo clippy, and tests - Safety: No
unsafecode allowed (enforced by lints) - Error Handling: Use
ResultandOption, avoidunwrap()in favor ofexpect() - Documentation: Document public APIs and complex logic
- Testing: Add tests for new features and bug fixes
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Built with excellent Rust crates including:
Core Infrastructure
- tokio - Async runtime powering the server and clients
- axum - Web framework for the REST API and WebSocket server
- serde - Serialization framework for all data structures
- anyhow - Flexible error handling across the project
Client Platforms
- wasm-bindgen - WebAssembly bindings for browser
- web-sys - Browser API bindings for WASM
- gloo - Toolkit for building WASM applications
- ratatui - Terminal UI framework
- crossterm - Cross-platform terminal manipulation
- iced - Native desktop GUI framework
- uniffi - Rust-Swift interoperability for iOS
- esp-idf-svc - ESP-IDF services for ESP32
- embedded-graphics - 2D graphics for embedded displays
- mipidsi - MIPI Display Interface driver
Networking & Communication
- tokio-tungstenite - Async WebSocket implementation
- reqwest - HTTP client for API calls
- tower-http - HTTP middleware and services
Utilities
- clap - Command-line argument parsing
- tracing - Structured application logging
- jiff - Date and time handling
- toml - TOML configuration parsing
- comrak - Markdown parsing and rendering
And many more amazing crates that make Rust development a joy!
