RustiQ is a Rust prototype for quantum chemistry software.
License: MIT OR Apache-2.0.
The point of this repository is not to claim that a young Rust code can already replace Gaussian, Molpro, PySCF, Psi4, ORCA, or Quantum Package. The point is to show what a modern electronic-structure codebase can look like when it is built with current software-engineering tools: strong types, explicit errors, structured input files, unit and CLI tests, reproducible dependencies, readable diagnostics, and a small architecture that a new contributor can actually understand.
This README is written for two audiences:
- theoretical chemists who are used to mature Fortran-era codes and care first about equations, numerical validation, and scientific trust;
- software engineers working on scientific codes who care about maintainability, modularity, developer experience, dependency management, and how much accidental complexity a codebase accumulates over time.
RustiQ is currently an experimental command-line application. It can parse TOML calculation files, read XYZ molecular geometries, load Gaussian basis sets, construct molecular integrals, run Hartree-Fock calculations, and optionally run MP2 from converged HF orbitals.
Implemented today:
clap-based command-line interface;- TOML runfiles parsed through
toml-spanner; - source-span diagnostics for invalid input through
miette; - XYZ geometry parsing and unit conversion;
- geometry inspection and transformation commands for info, rotation, translation, centering, and combined isometries;
- molecule validation for electron count, charge, and multiplicity;
- local basis-set cache and optional online basis-set download;
- Gaussian basis construction;
- one-electron core Hamiltonian terms;
- overlap matrix construction and symmetric orthogonalization;
- compact two-electron integral storage;
- RHF for closed-shell systems;
- UHF for open-shell systems;
- Automatic RHF/UHF resolution;
- DIIS acceleration;
- multiple density guesses, including core-Hamiltonian and randomized guesses;
- finite-value and positive-definiteness checks around sensitive numerical operations;
- RHF-MP2 and UHF-MP2 correlation energy paths;
- CLI reports for SCF and MP2;
- sample calculations for H2, OH, ethanol, and cholesterol;
- unit tests and CLI sample tests.
This is not yet production scientific software. The numerical results must be treated as experimental and cross-checked against established programs before being used for chemical interpretation.
Do not use RustiQ results for research conclusions without independent validation against established quantum chemistry packages.
The repository is intentionally split into small domains:
src/cli/handles command dispatch, terminal output, and user-facing reports.src/runfile/owns the TOML input schema, validation, typed configuration, and diagnostics.src/molecules/owns atoms, elements, geometry parsing, units, charge, multiplicity, electron-count logic, and geometry transforms.src/basis/owns basis-set files, cache management, Gaussian shells, and contractions.src/eri.rsandsrc/eri/own electron-repulsion integrals and compact ERI indexing/storage.src/hf/owns RHF, UHF, DIIS, density guesses, numerical checks, and SCF results.src/mp2.rsowns the post-HF MP2 layer for RHF and UHF references.tests/cli_samples.rschecks that real command-line samples run and produce expected energies.
This separation is one of the core messages of the project. A quantum chemistry code does not have to be a single historical mass of tightly coupled routines. It can expose clear boundaries between input, chemistry objects, basis handling, integrals, SCF algorithms, post-HF methods, and reporting.
Rust is not automatically better than Fortran for numerical kernels. Mature Fortran code is still extremely good at dense numerical work, and many electronic-structure packages exist because Fortran made high-performance scientific programming possible.
The interesting argument for Rust is different:
- Rust makes ownership and mutation explicit, which helps when large tensors, matrices, caches, and temporary workspaces start interacting.
- Typed errors with
thiserrorandmiettemake failure modes part of the design instead of an afterthought. - Cargo makes dependency management, testing, feature flags, formatting, and reproducible builds standard rather than project-specific infrastructure.
- Pattern matching and enums make configuration states explicit, for example HF method selection, density guesses, and validated runfile options.
- The ecosystem allows the project to reuse maintained crates instead of rebuilding every tool from scratch.
- Safe Rust is a strong default for high-level orchestration, while unsafe code can be isolated and documented when performance-sensitive storage needs it.
In RustiQ, this shows up concretely in the compact ERI storage, typed runfile validation, DIIS configuration, UHF spin handling, MP2 input validation, and source-located diagnostics for input files and xyz files.
RustiQ deliberately uses community crates where they make the code clearer:
nalgebrafor dense matrices, linear algebra, and 3D geometry operations;ndarrayfor array-shaped reference data in compact tensor tests;rayonfor data parallelism in integral and post-HF paths;clapfor declarative command-line parsing;serde,serde_json, andtoml-spannerfor structured data and recoverable TOML parsing;miettefor diagnostics that point at invalid TOML fields and XYZ geometry lines;thiserrorfor explicit error handling;reqwest,tokio,dirs, andindicatiffor optional online basis-set download and cache behavior;periodic_tableandphysical_constantsrather than hand-maintained chemistry constants;rstest,proptest, andapproxfor numerical and property-style testing;tabled,humantime,figlet-rs, andbatfor readable terminal output.
For a software engineer, the important point is not that every dependency is final. The point is that the project is designed like a modern application: dependency graph declared in one place, lockfile committed, tests integrated, formatting standardized, features configurable, and errors surfaced cleanly.
This also makes the architecture easier to compare with established research codes: scientific kernels can be isolated from user-interface and input-code paths, low-level optimizations can be concentrated in small modules such as compact ERI storage, and the code structure makes it clear where more serious Rust-native integral engines, determinant machinery, or perturbative corrections could be plugged in later. The extensibility is mainly visible for density guess and random distribution.
For a theoretical chemist or a thesis supervisor, the interesting part is that the computational chemistry concepts are visible rather than hidden behind a large legacy interface:
- the runfile explicitly states basis, molecule, charge, multiplicity, HF method, convergence threshold, DIIS, density guess, and MP2 options;
- RHF and UHF paths are separate enough to discuss the physical assumptions;
- MP2 is implemented as a post-HF layer that depends on converged HF orbitals;
- the code checks that MP2 is not run on an unconverged HF result;
- open-shell examples resolve to UHF and are tested through the CLI;
- numerical failure modes are not only strings; finite values, dimensions, orbital partitions, and overlap positive-definiteness are checked explicitly;
- sample outputs can be compared to reference packages such as PySCF;
- the codebase is small enough that SCF, UHF, ERIs, and MP2 can be located quickly and discussed directly;
- the separation between equations, inputs, validation, algorithms, and reports makes the scientific assumptions inspectable;
- the project leaves room for didactic method implementations without immediately fighting a large historical infrastructure.
This makes RustiQ useful as a discussion object for people used to mature Fortran-era packages as well as for developers of research codes: one can inspect where a method is implemented, where the assumptions enter, where validation is missing, and where performance would need serious work.
The useful conversation is not "Rust versus Fortran" in the abstract. RustiQ's
chemistry implementation is written in Rust: portable by default, easy to build
on the main desktop and HPC platforms, and still performance-oriented through
Rust's native compilation model, rayon parallelism, and nalgebra-based
numerical linear algebra. The goal is to show that a clean quantum chemistry
code can keep both the scientific layers and the performance-critical
implementation in the same modern, cross-platform ecosystem.
The missing pieces are substantial:
- systematic validation against established codes across molecules, bases, spin states, and charge states;
- a documented numerical reference suite with tolerances;
- broader basis-set support, angular-momentum coverage, contraction conventions, and normalization validation;
- gradients, geometry optimization, and vibrational frequencies;
- DFT functionals, grids, and numerical integration;
- robust treatment of larger systems with explicit memory strategy;
- faster Rust-native integral algorithms, screening, batching, and memory-aware integral handling;
- more post-HF methods and stronger validation of the current MP2 layer;
- standard chemistry formats beyond the current TOML/XYZ workflow;
- scientific documentation of equations, conventions, units, and tested approximations;
- benchmarks against PySCF, Psi4, ORCA, Quantum Package, and other relevant references;
- release packaging, versioned documentation, and a stable CLI contract.
Until those are addressed, RustiQ should be described as a modern prototype and architecture experiment, not as a production research code.
RustiQ can be developed either with the repository's Nix flake or with a
regular Rust installation. direnv is optional: it only automates entering and
leaving the Nix development shell.
If Nix is new to you, start with the official introduction to Nix and learning resources. Nix is a package manager and development-environment tool; NixOS is a complete Linux distribution built around it. You do not need to replace your operating system with NixOS to use this repository's flake.
The flake supports the following platforms:
- Linux on x86_64 and AArch64;
- macOS on Apple Silicon.
The pinned nixpkgs revision no longer supports Intel macOS (x86_64-darwin).
Use the native Cargo workflow on that platform.
On Windows, use the native Cargo workflow below or run the Linux flake through
WSL2. WSL2 can run either NixOS-WSL
or another Linux distribution with the Nix package manager installed. Native
Windows itself is not one of the systems currently declared by flake.nix.
Choose the case that matches your machine:
-
On NixOS, including NixOS-WSL: Nix is already installed as part of the operating system. NixOS-WSL installation instructions are available for users who want to run NixOS directly under WSL2. Make sure the modern Nix command and flakes are enabled in your NixOS configuration:
nix.settings.experimental-features = [ "nix-command" "flakes" ];
Apply the configuration with
sudo nixos-rebuild switch, then continue withnix developor the direnv workflow below. -
On another Linux distribution, macOS, or a non-NixOS WSL2 distribution: install Nix separately as an additional package manager. It works alongside tools such as
apt,dnf,pacman, or Homebrew and does not replace them. Follow the official Nix download and installation instructions for your platform, restart the shell if requested, and verify the installation withnix --version. The official page recommends a multi-user installation when the platform supports it.
In either case, Nix reads flake.nix and flake.lock from this repository to
create the same project-specific toolchain without installing those development
tools globally. The first invocation may take some time because Nix must
download the pinned dependencies; later invocations reuse its local store.
Install Nix with flakes enabled, clone the repository, and enter the development shell manually:
git clone https://github.com/mveril/RustiQ.git
cd RustiQ
nix developThis provides the Rust toolchain selected by rust-toolchain.toml and the
development utilities. On x86_64-linux and aarch64-darwin, where nixpkgs
currently supports its PySCF package, it also provides a Python environment
containing PySCF and its scientific Python dependencies. The shell remains
usable without PySCF on the other declared platforms and reports its absence
when it starts. Platform-specific profiling and debugging tools are included
where available. Run the usual Cargo commands inside it:
cargo build
cargo test
cargo run -- run samples/h2/sto-3g/calculation.tomlLeave the environment with exit or Ctrl-D. You can also build the default Nix
package without entering the development shell:
nix buildInstall both Nix and direnv, enable the direnv hook for your shell, then run:
git clone https://github.com/mveril/RustiQ.git
cd RustiQ
direnv allowThe tracked .envrc contains use flake, so direnv loads the same Nix
development environment automatically whenever you enter the repository and
unloads it when you leave. direnv allow is deliberately required the first
time, and again after .envrc changes, so that repository-provided shell code
is not executed without review. Use direnv deny to revoke permission.
If use flake is unknown, install or configure
nix-direnv, or use nix develop
directly. Some direnv/Nix installations already provide this integration.
Install Git and Rust through rustup, then use Cargo
directly on Linux, macOS, or Windows:
git clone https://github.com/mveril/RustiQ.git
cd RustiQ
rustup show
cargo build
cargo test
cargo run -- run samples/h2/sto-3g/calculation.tomlrustup show causes rustup to notice rust-toolchain.toml and install the
requested stable toolchain and components if necessary. This route is enough to
build and run RustiQ, but the extra tools and the PySCF reference environment
from the Nix development shell must be installed separately if you need them.
To install RustiQ directly from the source repository with Cargo, clone the project and run:
git clone https://github.com/mveril/RustiQ.git
cd RustiQ
cargo install --path .This installs the rustiq binary into Cargo's local binary directory. If you
want a development build instead, use cargo run from the repository root.
Build the project:
cargo buildRun the test suite:
cargo testRun a simple Hartree-Fock calculation:
cargo run -- run samples/h2/sto-3g/calculation.tomlRun an MP2 example:
cargo run -- run samples/h2/sto-3g/mp2_calculation.tomlRun an open-shell UHF example:
cargo run -- run samples/oh/sto-3g/calculation.tomlRun a larger sample:
cargo run -- run samples/ethanol/sto-3g/calculation.tomlA minimal calculation file looks like this:
[global]
basis = "sto-3g"
[global.molecule]
geometry = "./molecule.xyz"
charge = 0
multiplicity = 1
molecule_unit = "Angstrom"
[hf]
method = "Rhf"
max_iterations = 100
convergence_threshold = 1e-8
diis = true
diis_size = 8
[hf.guess]
type = "CoreHamiltonian"An MP2 calculation adds:
[mp2]
frozen_orbitals = 0The molecule file uses XYZ format:
2
Hydrogen molecule
H 0.0 0.0 -0.37
H 0.0 0.0 0.37
List locally cached basis sets:
cargo run -- basis listList online basis sets:
cargo run -- basis list --onlineDownload a basis set:
cargo run -- basis download sto-3gRemove cached basis sets:
cargo run -- basis remove sto-3gUseful checks before submitting a change:
cargo fmt
cargo clippy --all-targets --all-features
cargo testMost unit tests are colocated with implementation modules in src/. Shared
fixtures live in tests/data/, and sample calculation inputs live in
samples/.
See also:
CONTRIBUTING.mdfor contribution guidelines.ROADMAP.mdfor project priorities and research-grade requirements.CITATION.cfffor citation metadata.