Thank you for your interest in contributing to CrystalCanvas! We welcome contributions from researchers, software engineers, and crystal structure modeling enthusiasts.
CrystalCanvas is a cross-language project (Rust + C++ + TypeScript). All toolchains are isolated within the project directory via a Zero-Global-Pollution strategy.
- macOS (Primary): Install Xcode Command Line Tools:
xcode-select --install. - Linux (Ubuntu): Install
build-essential,cmake,libgtk-3-dev, andlibwebkit2gtk-4.1-dev. - Rust: Source the
dev_env.shscript (source dev_env.sh) to initialize project-local.rustupand.cargodirectories, then install the stable toolchain:rustup toolchain install stable. - Node.js / package manager: We strictly use
pnpmto manage dependencies. Do not usenpmoryarn.
- Fork the repository on GitHub.
- Clone your fork locally:
git clone https://github.com/XiaoJiang-Phy/CrystalCanvas.git cd CrystalCanvas
We use a unified build system powered by Tauri. The dev server handles frontend bundling and Rust/C++ compilation automatically.
# 1. Initialize the local Rust toolchain
source dev_env.sh
# 2. Install frontend dependencies
pnpm install
# 3. Start the application (compiles Rust + C++ automatically)
pnpm run tauri devNote: The C++ kernel (Spglib, Gemmi, Eigen) is compiled automatically via
build.rsusingcxx-build. No manual CMake interaction is required.
- Create a Branch: Always work on a new branch for your feature or fix.
git checkout -b feature/your-feature-name
- Make Changes: Follow the Coding Guidelines below.
- Commit: Use Conventional Commits format:
feat: add distance/angle measurement toolfix: correct CHGCAR coordinate alignmentrefactor: extract StateTransaction helper from commands.rs
- Push & PR: Push to your fork and open a Pull Request against the
mainbranch.
| Category | Convention | Examples |
|---|---|---|
| Variables / Functions | snake_case |
sigma_k, calculate_self_energy |
| Types / Classes | PascalCase |
CrystalState, BondInstance |
| Constants | UPPER_CASE |
MAX_ATOMS, PI |
| Template Arguments | PascalCase |
ScalarType, DevicePolicy |
Physics symbol fidelity: Preserve mathematical case sensitivity — delta_k ≠ Delta_K.
- Use
cargo fmtandcargo clippybefore committing. - All core crystal state must reside in the Rust layer (Single Source of Truth, SSoT).
- Dual-precision discipline: Use
f64for physics calculations (fractional coordinates),f32for GPU rendering (Cartesian positions). - ColMajor enforcement: All lattice matrices follow Fortran column-major order. Never transpose implicitly.
- Lock ordering: When acquiring multiple
Mutexlocks, always followcrystal_state → settings → rendererorder to prevent deadlocks. - FFI boundaries must use the
cxxbridge. Do not use rawextern "C"unlesscxxis insufficient for a specific interface. - Use the
with_state_updatetransaction helper for any command that mutatesCrystalState, instead of manual lock-mutate-rebuild-emit boilerplate.
- Keep the public API minimal using "Thin C Wrappers".
- Use
Eigenfor linear algebra andSpglibfor symmetry analysis. - All C++ exceptions must be caught within the wrapper and converted to Rust
Resulttypes. Exceptions must never cross the FFI boundary. - Do not use
using namespace std;orusing namespace Eigen;— all external library calls must be explicitly qualified. - Comment discipline: only
///Doxygen docs, physics formula references (e.g.,// Eq.(3.12) [Mahan00]), and non-obvious technical rationale. No "Step 1 / Step 2" narration comments.
- UI Frameworks Banned: Build all components from scratch using pure TailwindCSS classes. Do not use UI libraries like Headless UI, DaisyUI, or Radix UI.
- Strict IPC Typing: Any data crossing the Rust ↔ TypeScript boundary (e.g.,
CrystalState,CrystalCommand) must have a strict 1:1 mapped TypeScript interface insrc/types/. Avoidany. - Do not hold physical state in the UI. Use the Command Bus to interact with the backend.
- When splitting large components, use
React.lazy()for panel-level code splitting.
- Write all shaders in WGSL (the sole source language, cross-compiled by
naga). - Do not use platform-specific extensions to ensure compatibility across Metal, Vulkan, and DX12.
- Only use features guaranteed by
wgpu::DownlevelFlags::default().
L4: React + TypeScript + TailwindCSS (Presentation)
L3: Rust / Tauri 2.0 (Application Logic / SSoT)
L2: Rust / wgpu (Rendering Engine)
L1: C++ (Spglib / Gemmi / Eigen) (Physics Kernel)
Key architectural rules:
- L4 is a pure presentation layer — no physics state caching.
- L3 owns all crystal state and orchestrates L1 ↔ L2 communication.
- L2 holds only GPU-side rendering buffer mirrors — no physical logic.
- L1 is a stateless computation engine: input → output, no state caching.
For the project roadmap, see ROADMAP.md.
- Rust:
cargo testinsrc-tauri/. All tests must pass before PR submission. - C++: Unit tests within
cpp/via CMake CTest. - Visual verification: For rendering changes, verify on at least macOS Intel (our development baseline). Screenshots of before/after are encouraged in the PR description.
- Performance thresholds: Do not modify timing thresholds or tolerance constants to make a failing test pass. Fix the underlying logic.
- API Keys: LLM API keys are stored in the OS Keychain via Tauri's secure storage. Never log, hardcode, or commit API keys.
- LLM output is untrusted: All AI-generated commands pass through Schema Validation → Physics Sandbox → Undo Snapshot before execution.
By contributing to CrystalCanvas, you agree that your contributions will be licensed under the project's dual MIT and Apache-2.0 license.
If you have questions or want to discuss a large feature before starting work, please open an Issue or join our community discussions.