Contributing
We welcome contributions to Wasmrun! This guide will help you get started with contributing code, documentation, plugins, and more.
Development Setup
Prerequisites
Required Tools:
# Just task runner (recommended)
cargo install just
# WebAssembly target (for testing)
rustup target add wasm32-unknown-unknown
Optional Tools for Plugin Testing:
# For C/C++ plugin testing
# Install Emscripten from: https://emscripten.org/
# For Go plugin testing
# Install TinyGo from: https://tinygo.org/
# For Rust web development
cargo install wasm-pack
cargo install trunk
# For AssemblyScript plugin testing
npm install -g assemblyscript
Getting Started
- Fork and Clone:
git clone https://github.com/yourusername/wasmrun.git
cd wasmrun
- Build:
just build # Or: cargo build --release
- Run Tests:
just test # Run all tests
# Run specific test modules
cargo test plugin::tests
cargo test server::tests -- --test-threads=1
- Code Quality:
just format # Format code with rustfmt
just lint # Run clippy lints
Development Workflow
Using Just Commands
Wasmrun uses a justfile for common development tasks:
# Development commands
just build # Build in release mode
just test # Run all tests
just format # Format both Rust and TypeScript/JavaScript code
just lint # Run clippy lints and ESLint
just type-check # Run TypeScript type checking
just clean # Clean build artifacts
# Plugin testing commands
just run WASM_FILE # Test with a WASM file
just stop # Stop running servers
# Release commands (for maintainers)
just prepare-publish # Prepare for publishing
just publish # Publish to crates.io and GitHub
Pre-Commit Checklist
Before pushing your changes, ensure:
# 1. Format code
just format
# or
cargo fmt --all
# 2. Run lints (must pass with no warnings)
just lint
# or
cargo clippy --all-targets --all-features -- -D warnings
# 3. Run tests locally
just test
# or
cargo test --all-features
# 4. Type check TypeScript (if UI changes)
just type-check
GitHub Workflows
All CI workflows are in .github/workflows/:
ci.yml- Format and lint checkstest.yml- Test executionexamples.yml- Example projects compilation
Code Style Guidelines
- Formatting: Use
rustfmtandprettierwith default settings (just format) - Linting: All clippy warnings and ESLint errors must be addressed (
just lint) - Type Checking: All TypeScript code must pass type checking (
just type-check) - Error Handling: Use the centralized
WasmrunErrortypes insrc/error.rs - Documentation: Add doc comments for public APIs and complex logic
- Testing: Add tests for new functionality, ensure they don't hang
- Plugin Integration: Use shared utilities from
utils/modules - UI Components: Follow React hooks best practices and TypeScript typing conventions
File Organization Guidelines
When adding new functionality:
- Commands: Add to
src/commands/if it's a CLI command - Plugin Languages: Add to
src/plugin/languages/for built-in plugins - Server Features: Add to
src/server/for web server functionality - Utilities: Add to
src/utils/for shared functionality - Templates: Managed via
src/template.rs, files stored in roottemplates/directory - UI Components: Add to
ui/directory for React/TypeScript web interface components - Tests: Co-locate with the module being tested or in
tests/for integration tests
UI Development Workflow
The wasmrun-ui is built with Preact, TypeScript, and Tailwind CSS:
# UI development setup (from ui/ directory)
cd ui
pnpm install # Install UI dependencies
pnpm dev # Start UI development server
# UI development commands (from project root)
just format # Formats both Rust and TypeScript code
just lint # Lints both Rust and TypeScript code
just type-check # Runs TypeScript type checking
# UI is automatically built and embedded during main build
just build # Does all checks and builds with ui
UI Component Development
When working on UI components:
- Component Structure: Follow existing patterns in
ui/src/components/ - Styling: Use Tailwind CSS classes for consistent design
- Type Safety: Ensure all props and state are properly typed
- Testing: Components are tested through integration tests
- Hooks: Use React hooks following established patterns (
useCallback,useEffect)
The UI is embedded into the Rust binary during build, so changes require a full rebuild to test in wasmrun.
Contributing Process
1. Create a Branch
git checkout -b feature/my-new-plugin
git checkout -b feature/enhance-rust-plugin
2. Development and Testing
# Make your changes
just format # Format code
just lint # Check lints
just test # Run tests
3. Documentation Updates
- Update relevant documentation in README.md if needed
- Add tests for new plugin functionality
- Update CONTRIBUTING.md if adding new patterns
4. Create Pull Request
- Clear description: Explain what your changes do and why
- Reference issues: Link to any related GitHub issues
- Include testing steps: Show how to test your plugin changes
- Breaking changes: Clearly mark any breaking changes
- Performance impact: Note any performance considerations
- Plugin compatibility: Ensure changes don't break other plugins
PR Review Checklist
Code Quality
- Code follows style guidelines (
just format&&just lint) - TypeScript code passes type checking (
just type-check) - All tests pass locally (
just test) - No clippy warnings (
cargo clippy --all-targets --all-features -- -D warnings) - Code is formatted (
cargo fmt --all -- --check)
Testing
- New functionality includes tests
- Tests don't hang (use
cfg!(test)guards for server tests) - Tests are cross-platform compatible
- Integration tests use appropriate timeouts
Documentation
- Documentation is updated if needed
- Doc comments added for public APIs
- Examples updated if APIs changed
- CHANGELOG.md updated for notable changes
CI/CD
- All CI workflows pass (format, lint, tests, examples)
- Examples compile on both Ubuntu and Windows
- No new dependency conflicts
- Breaking changes are clearly marked
Performance & Compatibility
- Error messages are user-friendly
- Performance impact is considered
- Cross-platform compatibility verified
- UI changes work in all supported modes (console, app)
- Binary size increase is reasonable
Bug Reports
When reporting bugs:
- Use the issue template if available
- Include system information:
- OS and version
- Rust version (
rustc --version) - Wasmrun version (
wasmrun --version)
- Include plugin information:
- Which plugin is affected (
wasmrun plugin list)
- Which plugin is affected (
- Provide reproduction steps
- Include relevant output with
WASMRUN_DEBUG=1if possible - Attach example files if applicable
- Attach screenshots if applicable
Plugin-Specific Bug Reports
For plugin-related issues:
# Get plugin information
wasmrun plugin info [plugin-name]
# Test with verbose output
WASMRUN_DEBUG=1 wasmrun run ./project --language [plugin-name] --verbose
Feature Requests
When requesting features:
- Check existing issues to avoid duplicates
- Explain the use case and why it's valuable
- Provide examples of how it would work
- Consider plugin architecture - could it be a new plugin?
- Consider implementation complexity
- Be open to alternative solutions
Plugin Enhancement Requests
For plugin-specific features:
- Identify target plugin - which plugin needs enhancement?
- Plugin compatibility - how would it affect other plugins?
- Shared utilities - could it benefit multiple plugins?
Testing Guidelines
Running Tests
# Run all tests
just test
# Run specific test categories
cargo test --lib # Unit tests
cargo test --test integration # Integration tests
cargo test plugin:: # Plugin tests
cargo test server:: -- --test-threads=1 # Server tests (single-threaded)
# UI-related testing
just type-check
just lint
just format
Test Data and Examples
Create realistic test scenarios:
tests/
├── fixtures/
│ ├── rust_project/
│ │ ├── Cargo.toml
│ │ └── src/main.rs
│ ├── c_project/
│ │ ├── Makefile
│ │ └── main.c
│ └── mylang_project/
│ ├── main.ml
│ └── mylang.config
└── integration/
├── plugin_tests.rs
└── server_tests.rs
Examples Development Guide
The examples/ directory contains sample WebAssembly projects for different programming languages. These serve as learning resources and testing grounds for Wasmrun's capabilities.
Available Examples
| Language | Directory | Capabilities |
|---|---|---|
| Rust | rust-hello/ | wasm-bindgen, browser APIs, memory management |
| Go | go-hello/ | syscall/js, concurrency, time operations |
| C | c-hello/ | Emscripten, math library, manual memory |
| AssemblyScript | asc-hello/ | TypeScript syntax, performance optimization |
Testing Examples
Examples work with standard wasmrun commands:
# Test compilation and running
wasmrun examples/rust-hello
wasmrun compile examples/go-hello
# Verify WASM output
wasmrun verify examples/rust-hello/target/wasm32-unknown-unknown/release/*.wasm
Creating a New Example
When adding a new language example:
- Create directory:
examples/language-hello/ - Add source code with standard functions:
greet(),fibonacci(),sum_array() - Include build config: Language-specific (Cargo.toml, package.json, etc.)
- Write README.md with usage instructions
- Test:
wasmrun run examples/language-hello
Example Requirements
- Works with standard wasmrun commands
- Implements common functions for consistency
- Includes comprehensive README.md
- Tests successfully in browser console
Advanced Development Topics
Adding New Commands
To add a new CLI command:
- Create command file:
// src/commands/my_command.rs
use crate::error::Result;
pub fn run_my_command(arg: &str) -> Result<()> {
println!("Running my command with: {}", arg);
Ok(())
}
- Update command module:
// src/commands/mod.rs
pub mod my_command;
pub use my_command::run_my_command;
- Add to CLI definition:
// src/cli.rs
#[derive(Parser)]
pub enum Commands {
// ... existing commands
MyCommand {
arg: String,
},
}
- Handle in main:
// src/main.rs
Commands::MyCommand { arg } => {
commands::run_my_command(&arg)?;
}
Extending Server Functionality
To add new server endpoints:
- Add handler:
// src/server/handler.rs
fn handle_my_endpoint(request: &Request<()>) -> Response<std::io::Cursor<Vec<u8>>> {
let response_body = "My custom response";
create_response(200, "text/plain", response_body.as_bytes())
}
- Register route:
// In the main request handler
"/my-endpoint" => handle_my_endpoint(request),
License
By contributing to Wasmrun, you agree that your contributions will be licensed under the project's MIT license.
Thank you for contributing to Wasmrun! Every contribution matters, whether it's code, documentation, bug reports, new plugins, or spreading the word about the project.
Next Steps
- Creating Plugins: Learn to create your own plugins
- Debugging: Debug your contributions effectively
- Architecture: Understand the codebase structure