Installation¶
vibe-qc is a Python package with a C++ core. The C++ core links against libint (Gaussian integrals), libxc (XC functionals), spglib (crystal symmetry), FFTW3 (Ewald long-range Hartree), libecpint (effective-core potentials), plus a pinned snapshot of pugixml + libcerf inside libecpint’s tree, and an optimised BLAS + LAPACK (Apple Accelerate on macOS, OpenBLAS / MKL on Linux) that Eigen delegates dense linear algebra to, see BLAS backend below.
Choose the installation you need¶
Goal |
Recommended route |
Native compiler build? |
|---|---|---|
Stable calculations |
clone the default |
yes |
Develop or test current |
|
yes |
Reproduce a published calculation |
|
yes |
Read QVF files only |
no |
|
Calculate and view on one machine |
install vibe-qc, then follow Install both |
vibe-qc only |
If this is your first visit, Start here gives the shortest end-to-end route, including verification and a first calculation. This page is the detailed engine-installation reference: platform packages, manual build steps, BLAS selection, clusters, updates, and failure recovery.
Note
vibe-qc is not on PyPI yet. There is no pip install vibe-qc. The
supported install path is: clone the repo, install your platform’s build
prerequisites, then run ./scripts/install.sh. It builds or verifies the
vendored libraries, creates the managed virtualenv, installs the package, and
checks the live extension. The advanced manual recipe remains below for custom
provisioning.
Request repository access¶
Note
The repository is currently private, and will go public once the
JCC release paper is out. To get clone access: email
mpei@vibe-qc.com with a public SSH key (a .pub file) to be added
as a read-only Deploy Key. Once added, clone over SSH using the
non-standard port shown below.
What a successful install does¶
The recommended command is intentionally a bootstrap, not merely a Python package install:
./scripts/install.sh
It performs these steps in order:
selects the requested release, branch, or tag;
checks the compiler, CMake, Ninja, headers, OpenMP, and BLAS;
fetches and verifies the pinned native dependency sources;
installs native libraries below
third_party/in this checkout;creates a checkout-local
.venv;builds the editable Python/C++ package;
imports vibe-qc and prints the linked-library banner.
The first clean build normally takes 15 to 40 minutes and uses several gigabytes of build space. Re-running the installer is much faster when the native dependency stamps are current.
After it finishes, verify the exact interpreter and package path:
.venv/bin/python -c "from vibeqc import print_banner; print_banner()"
.venv/bin/python -c "import vibeqc; print(vibeqc.__file__)"
The second command should resolve inside the checkout you just installed.
If it points into another worktree, recreate the environment here instead of
sharing that other checkout’s .venv.
See also
Once installation is done, good practices covers the working conventions for actually using vibe-qc – where to put your calculations (hint: not inside the source tree), naming, reproducibility, performance hygiene, and what to try when SCF diverges. Worth a five-minute read before your first production run.
The five pinned core libraries are vendored.
scripts/setup_native_deps.sh fetches libint, libxc, spglib, FFTW, and
libecpint from upstream, configures them the way vibe-qc needs, builds them,
and installs them into third_party/<name>/install/. Eigen, Boost, GMP, and
the BLAS implementation are supplied by the platform or an opt-in route, so
record the banner when exact build provenance matters.
Each fetched tarball / git tag is verified against a pinned SHA-256 /
commit SHA before use (see the per-script comment blocks in
scripts/build_*.sh for the resolved values and the re-resolve recipe),
so a moved upstream tag or a network-level tamper fails loudly rather
than silently changing what vibe-qc links against.
If a third_party/<dep>/install/ is missing, the top-level CMake
configure silently falls back to system discovery for that one
dependency. That is convenient for development, but it weakens the
vendored-ABI guarantee. CI and release builds that need the guarantee
should set VIBEQC_REQUIRE_VENDORED (either
-DVIBEQC_REQUIRE_VENDORED=ON at configure time or the matching env
var), which turns the fallback into a hard error for the five always-
vendored deps (libint, libxc, spglib, fftw, libecpint). OpenBLAS is
opt-in (WITH_OPENBLAS=1) and stays excluded from the strict check.
Only want the viewer?
None of the build requirements below apply if all you need is
vibe-view, the viewer for .qvf archives. It is a
wheel-based Python install: no local C++ compiler, no CMake, no vendored native
dependencies, and it does not need vibe-qc installed at all. One checkout
installer or one hosted-wheel install is enough; vibeview is not on PyPI yet.
Follow Getting started with vibe-view alone instead, which covers Linux and macOS.
Choose the component you need¶
The checkout contains four independently installable command-line tools. Each uses its own virtual environment by default, so installing a companion tool does not trigger vibe-qc’s native C++ build or disturb another component.
Component |
What it provides |
Install command |
Default environment |
|---|---|---|---|
vibe-qc |
Molecular and periodic calculations |
|
|
vibe-view |
QVF, structure, browser, desktop, and terminal viewing |
|
|
vq (Python 3.12+) |
Local/remote queue, daemon, and optional web dashboard |
|
|
vibe-basis |
External-code basis-set optimization driver |
|
|
Every component has the same four lifecycle entry points in its scripts/
directory:
./COMPONENT/scripts/install.sh # first setup
./COMPONENT/scripts/update.sh # update source and installed package
./COMPONENT/scripts/reinstall.sh # rebuild the environment from this source
./COMPONENT/scripts/uninstall.sh # remove only the component installation
For vibe-qc itself, omit COMPONENT and use the root scripts/ directory.
Run --help before choosing profiles and --dry-run to preview paths and
changes. The scripts support macOS and Linux and should be run as your regular
user; only operating-system package installation may need sudo. Existing
environments are validated before replacement, and reinstall operations keep a
rollback copy until the new environment verifies successfully.
All four component installers stamp a checkout-specific ownership marker.
Replacement and removal refuse an ordinary or foreign virtualenv even when it
has pyvenv.cfg. For a pre-marker vibe-qc, vibe-view, or vq installation,
inspect the target and use the command’s explicit --adopt-legacy flow (and
its required replacement flag, shown by --help). Adoption succeeds only when
trusted, non-executing PEP 610 metadata points to this exact checkout.
vibe-basis has no legacy adoption path because its standalone lifecycle is new;
an unmarked environment must be moved or removed manually after inspection.
The root vibe-qc, vibe-view, and vibe-basis packages support Python 3.11+. The vq queue package requires Python 3.12+.
The default vibe-view profile includes standalone/core commands, browser, desktop, and TUI support. Its importers also accept common files such as XYZ, CIF, PDB, MOL2, SDF, cube, and Gaussian input, so the viewer can be useful without installing vibe-qc or when results originate in another code.
For a compact comparison of all four install, update, repair, and uninstall flows, see Install and maintain the vibe toolset.
Requirements¶
System tools the build needs:
Python ≥ 3.11 (3.11-3.14 all work; 3.14 is what the macOS install recipe below uses). On macOS, Apple’s stock
/usr/bin/python3is currently 3.9 and is too old, install Homebrew’spython@3.14and make sure it wins onPATH(see the macOS section below).C++17 compiler, AppleClang 13+, GCC 10+, Clang 13+
CMake ≥ 3.20 and Ninja
git, make, curl, tar, pkg-config
OpenMP, comes with GCC / Clang on Linux; on macOS it’s
libompfrom Homebrew (AppleClang ships without OpenMP support and several vendored deps hard-require it).An optimised BLAS + LAPACK, Apple Accelerate ships with macOS; on Linux install OpenBLAS or MKL (system package or vendor it via
WITH_OPENBLAS=1, see BLAS). Reference netlib BLAS is functional but slow and not recommended.
Plus three small system libraries that libint’s code generator uses during its own build (we deliberately don’t vendor these, GMP has arch-specific assembly, and Boost / Eigen are header-only and on every distro):
Eigen (3.4+ or 5.0+), header-only. Both major versions work; libint 2.13.1’s bundled CMake module handles either header layout. As of mid-2026, Homebrew’s
eigenformula and Arch’seigenpackage are both 5.0.x, that’s the version vibe-qc builds against on macbook + planetx today. Debian/Ubuntu still shiplibeigen3-dev3.4.x, which also works fine.Boost, header-only
GMP with C++ bindings (gmpxx)
scripts/setup_native_deps.sh runs a preflight check that verifies
every one of the above is present before it starts building anything,
and prints the exact per-distro install command for whatever is
missing. If you’ve never installed vibe-qc on a given machine before,
just run the script, it will tell you what to brew install /
pacman -S / apt install first.
Python runtime dependencies such as NumPy, SciPy, spglib, seekpath,
jsonschema, joblib, and ASE come from pyproject.toml through pip.
scikit-build-core and pybind11 are isolated build requirements. pytest,
PySCF, and the other validation tools belong to the optional test and dev
extras; a calculation-only installation does not need them.
One-shot bootstrap¶
After installing the system tools below, the easiest path on every platform is:
git clone ssh://git@gitlab.peintinger.com:26/mpei/vibeqc.git
cd vibeqc
./scripts/install.sh # preflight → native deps → venv → pip install → banner
install.sh drives the full bootstrap and prints the banner so you
can confirm the C++ extension loaded. It accepts the same branch /
extras / venv flags as update.sh:
./scripts/install.sh --dev # bleeding-edge main
./scripts/install.sh --current # keep the current Git ref
./scripts/install.sh --branch basissetdev # paper-writing branch
./scripts/install.sh --branch v0.9.0 # pin to a tag
./scripts/install.sh --extras dev # tests + dispersion + py-spy
./scripts/install.sh --extras viewer-gpu # add co-located vibe-view browser UI
./scripts/install.sh --extras basisopt # add co-located vibe-basis
./scripts/install.sh --python python3.13 # force a specific interpreter
./scripts/install.sh --venv .venv-bsd --branch basissetdev # side-by-side per branch
./scripts/install.sh --with-openblas # vendor OpenBLAS
./scripts/install.sh --libint-max-am 5_4_3 # faster libint, no g-function Hessians
./scripts/install.sh --force # atomically replace an existing .venv
install.sh --help prints the full surface. Internally it coordinates the
same native setup and editable package build shown in the manual recipe, then
adds cross-platform checkout and target locks, safe-path and ownership checks,
transactional replacement, profile handling, and live-extension verification.
With no branch flag, it installs the latest release; use --current when you
explicitly want to install an already-checked-out development snapshot.
Existing environments have a complete lifecycle:
./scripts/update.sh # update source, native deps, and package
./scripts/reinstall.sh # rebuild this checkout's venv with rollback
./scripts/uninstall.sh # remove only this checkout's owned venv
--force, --recreate-venv, and reinstall.sh keep the prior venv in a
same-parent backup until the replacement installs and verifies. Unsafe paths,
symlinks, the checkout itself, directories without pyvenv.cfg, and venvs
owned by another checkout are refused rather than recursively deleted. For a
pre-marker installation from this checkout, add --adopt-legacy (and use
--python to name an external interpreter when the default is unsuitable).
Note
Worktree-private venvs. If you keep multiple checkouts (one per
branch you actively develop on), run install.sh inside each
checkout so each gets its own .venv pinned to that checkout’s
third_party/ trees. Never share a venv across checkouts – the
editable pip install pins the C++ extension to one specific
third_party/ tree, and a venv from a different checkout will
load the wrong native libraries.
Advanced manual bootstrap¶
If you’d rather invoke the steps by hand (e.g. on a stripped-down machine, or to integrate with your own provisioning):
git clone ssh://git@gitlab.peintinger.com:26/mpei/vibeqc.git
cd vibeqc
./scripts/setup_native_deps.sh # preflight → 15-40 min build, idempotent
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -e .
Contributors and parity-test environments should request the development tools explicitly:
.venv/bin/python -m pip install -e '.[dev]'
This manual environment does not receive the checkout ownership marker written
by install.sh. Ordinary in-place pip work remains possible, but a later
managed replacement or uninstall requires the explicit, exact-PEP-610
--adopt-legacy proof. Prefer install.sh unless custom provisioning needs
the individual steps.
setup_native_deps.sh first runs the preflight check (a few seconds)
that verifies every build prerequisite is present. If anything is
missing it bails with a copy-pasteable per-distro install command; if
everything is present it proceeds straight into the vendored builds.
git clone lands you on release (the project’s default branch),
which is the latest tagged release. The banner reads
Release vX.Y.Z to match the tag. For active development on
main instead, add git checkout main after the clone, main is
the higher X.Y.dev0 development version and rebuilds with every
push. Pin to a specific tag (git checkout v0.4.6) for fully
reproducible calculations.
setup_native_deps.sh calls (in order):
build_libint.sh, libint 2.13.1build_libxc.sh, libxc 7.0.0build_spglib.sh, spglib 2.7.0build_fftw.sh, FFTW3 3.3.10build_libecpint.sh, libecpint + pugixml + libcerfsetup_basis_library.sh, populate the gitignoredbuild/basis_library/basis/overlay from libint’s standard set plus our custom additions
After the build, setup_native_deps.sh probes which BLAS the
system has and prints a tip if it would benefit from an upgrade.
See BLAS backend below.
Each per-dep script is idempotent. The orchestrator compares its provenance stamp before those existence checks, so a changed version, recipe, or missing library rebuilds only the affected dependency. Legacy install trees without a stamp remain explicitly uncertified until a full native rebuild; they are not relabeled as current merely because an idempotent build skipped them. Locking-only lifecycle changes are excluded from the build-relevant recipe fingerprint and therefore do not rebuild unchanged native libraries. Existing three-field stamps migrate to the newer fingerprint during a normal update without recompilation when their recipe identity matches directly or an exact, reviewed historical-to-current fingerprint pair. Unknown fingerprints and real native-recipe changes still rebuild the affected dependency.
BLAS backend¶
vibe-qc’s C++ core uses Eigen for
dense linear algebra. At build time, CMake links Eigen against
whatever optimised BLAS+LAPACK is available so dense matrix
products, eigendecompositions, and Cholesky factorisations
delegate to it (EIGEN_USE_BLAS / EIGEN_USE_LAPACKE). Without
an optimised BLAS, Eigen’s generic-C++ kernels run instead,
correct, but several × slower at SCF size. The print-banner’s
linked: line carries the chosen backend (blas Accelerate,
blas OpenBLAS, etc.) so a persisted SCF log records which BLAS
produced the calculation.
Backend selection happens automatically:
macOS: Apple Accelerate (system framework, no install needed).
Linux: system OpenBLAS / MKL / netlib BLAS via CMake’s
FindBLASauto-detect.All platforms (opt-in): a vendored OpenBLAS built into
third_party/openblas/install/, see below.
To install an optimised BLAS via your system package manager (simpler, lighter):
Arch / Manjaro:
sudo pacman -S blas-openblasDebian / Ubuntu:
sudo apt install libopenblas-dev liblapacke-devFedora / RHEL:
sudo dnf install openblas-devel lapack-develmacOS: nothing, Accelerate already provides what we need.
To vendor OpenBLAS into the checkout (no sudo needed, useful for HPC / locked-down workstations / CI reproducibility, needs a Fortran compiler):
WITH_OPENBLAS=1 ./scripts/setup_native_deps.sh
This invokes scripts/build_openblas.sh which clones OpenBLAS
0.3.33 from upstream, builds it with DYNAMIC_ARCH=1
(runtime CPU detection), USE_LAPACK=1 USE_LAPACKE=1
(bundles LAPACK + LAPACKE into libopenblas.so), and installs
into third_party/openblas/install/. The next pip install -e .
picks up the vendored install automatically (CMake’s
find_package(BLAS BLA_VENDOR=OpenBLAS) resolves it via
CMAKE_PREFIX_PATH), with the banner reading
linked: ... · blas OpenBLAS +LAPACKE.
To disable BLAS linkage entirely and force Eigen’s generic
kernels (mainly for debugging numerical issues), pass
-DVIBEQC_USE_BLAS=OFF to the vibe-qc CMake configure.
See user_guide/blas for the full surface: how to read the linkage off the banner, the threading model, when the vendored path is worth it (and when it isn’t), and a candid note on which perf problems BLAS linkage does not solve.
Per-platform: install the system tools¶
These are the commands the preflight check in
./scripts/setup_native_deps.sh will print if anything is missing on
your box. You can run them up-front or wait for the preflight to point
out what to install, either path lands at the same place.
macOS (Homebrew)¶
brew install cmake ninja pkg-config libomp boost eigen gmp git python@3.14
# Optional but recommended for the OpenBLAS escape hatch:
brew install gcc # provides gfortran
No separate BLAS package, Apple Accelerate ships with macOS and is what Eigen links against. The preflight check will confirm Accelerate is reachable and tell you if the framework is somehow missing (extremely unusual; happens on stripped-down corporate images).
Note
Homebrew’s eigen formula is currently Eigen 5.0.1 – that’s
expected and fine. libint 2.13.1 (vendored under
third_party/libint/) ships a CMake module that handles both the
Eigen 3 and Eigen 5 header layouts, so vibe-qc builds cleanly
against the brew install with no path-mangling on your end. If
brew info eigen shows you 5.x and you’ve seen guidance elsewhere
warning to pin Eigen 3, ignore it – that guidance is stale.
If Homebrew isn’t installed yet, install it first
(/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")
the preflight check will detect its absence and refuse to start.
Python on macOS. Apple’s stock
/usr/bin/python3is currently Python 3.9 (the Xcode Command Line Tools stub) and does not meet vibe-qc’s ≥3.11 minimum. Homebrew’spython@3.14is the recommended runtime, thebrew installline above pulls it in.After installing, make sure
python3on your$PATHresolves to the new install rather than Apple’s stub. The canonical Homebrew shell setup does this, verify and persist it once per shell:eval "$(/opt/homebrew/bin/brew shellenv)" echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrcThen check:
python3 --version # expect 3.14.x (or whichever brew installed) which python3 # expect /opt/homebrew/bin/python3If
python3 --versionstill shows 3.9.x, Homebrew’s bin isn’t winning onPATH, force the symlink:brew link --overwrite --force python@3.14The preflight in
setup_native_deps.shcatches the stale-Apple- python case explicitly so you’ll get a clear error rather than a cryptic CMake or pybind11 failure later.
Apple Silicon note. Homebrew lives at
/opt/homebrewon ARM Macs. vibe-qc’s CMake configuration runsbrew --prefixand adds that toCMAKE_PREFIX_PATHautomatically, so no manual path setup is needed.
libompis not optional on macOS. AppleClang ships without OpenMP support, and several vendored deps (spglib in particular) hard-require it.brew install libompputs the headers + library at$(brew --prefix libomp); vibe-qc’ssetup_native_deps.shauto-detects this onmain(commit973c8f3and later). On older release branches that pre-date the auto-detect, also export the hint env var before runningsetup_native_deps.sh/scripts/update.sh:export OpenMP_ROOT=$(brew --prefix libomp)Add it to
~/.zshrcif you want it to persist across sessions. Without it, CMake’sFindOpenMPerrors out withCould NOT find OpenMP_C (missing: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES)and the spglib configure stops there.
Linux, Arch / Manjaro¶
sudo pacman -S base-devel cmake ninja pkg-config git curl \
gmp eigen boost python blas-openblas
# Optional but recommended for the OpenBLAS escape hatch:
sudo pacman -S gcc-fortran
base-devel is the meta-group that carries gcc/g++/make/binutils.
python on Arch is 3.13+ as of mid-2026 and bundles pip and the
venv module out of the box, no separate python-pip /
python-virtualenv needed. curl is used by setup_native_deps.sh
to fetch libint / libxc / spglib / FFTW / libecpint tarballs.
blas-openblas is the OpenBLAS+LAPACK package; without an optimised
BLAS, Eigen’s generic-C++ kernels run at SCF size and you lose a
multiple-× of performance. The default Arch BLAS slot ships as
reference netlib BLAS, which is functional but doesn’t beat
Eigen-generic, blas-openblas is the right pick.
Note
Arch’s eigen package is currently version 5.0.1. This works
fine – libint 2.13.1 (which we vendor in third_party/libint/)
shipped a CMake module that handles both the Eigen 3 and Eigen 5
header layouts. Arch keeps Eigen 5’s headers under
/usr/include/eigen3/ for backward compatibility with dependent
packages, so no path-mangling is needed on your end.
If you previously installed the AUR eigen3 (3.4.x) package as a
workaround, you can safely switch back to the standard eigen –
yay -S eigen and accept the conflict prompt.
If you’d rather not install anything system-wide, an
AUR helper like yay or paru works
the same way:
yay -S base-devel cmake ninja pkg-config git curl \
gmp eigen boost python blas-openblas
If you need a specific Python version that differs from Arch’s
rolling-release default, pyenv
(yay -S pyenv) builds an isolated interpreter under ~/.pyenv
without touching the system Python.
Linux, Debian / Ubuntu¶
sudo apt update
sudo apt install \
build-essential cmake ninja-build pkg-config git curl \
libeigen3-dev libboost-dev libgmp-dev libgmpxx4ldbl \
libopenblas-dev liblapacke-dev \
python3 python3-dev python3-venv
# Optional but recommended for the OpenBLAS escape hatch:
sudo apt install gfortran
libopenblas-dev brings the BLAS+LAPACK Eigen wants;
liblapacke-dev adds the C interface so Eigen’s dense solvers
(LLT, SelfAdjointEigenSolver, …) also delegate.
Linux, Fedora / RHEL¶
sudo dnf install \
@development-tools cmake ninja-build pkgconfig git curl \
eigen3-devel boost-devel gmp-devel gmp-c++ \
openblas-devel lapack-devel \
python3 python3-devel
# Optional but recommended for the OpenBLAS escape hatch:
sudo dnf install gcc-gfortran
What each step does¶
Step |
Purpose |
|---|---|
OS-package install |
C++ compiler, CMake/Ninja, plus the headers libint’s code generator needs at build time (Boost, Eigen, GMP) and the BLAS+LAPACK Eigen delegates dense linear algebra to. |
|
Fetches and builds libint, libxc, spglib, FFTW3, libecpint into |
|
Builds the packaged basis inventory under |
|
Isolates vibe-qc from your system Python. |
|
Drives CMake via scikit-build-core, picks up the vendored libs from |
Verifying¶
.venv/bin/python -c "import vibeqc; vibeqc.print_banner()"
Should print a labeled box with vibe-qc’s version, the build’s git provenance, and every linked native library:
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Release v0.15.x "Neese's Cheetah" -- Quantum chemistry for molecules and solids ║
║ © Michael F. Peintinger · MPL 2.0 · https://vibe-qc.com ║
║ linked: libint 2.13.1 · libxc 7.0.0 · spglib 2.7.0 · libecpint 1.0.7 (vendored, MAX_L=5) · fftw3 3.3.10 · blas Accelerate ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
When the optional [dispersion] extra is installed (pip install -e '.[dispersion]'), the banner gains a second linkage line
listing the dftd3 and dftd4 PyPI-wheel versions whose
bundled binary libraries vibe-qc loads at runtime:
║ linked: libint 2.13.1 · libxc 7.0.0 · spglib 2.7.0 · libecpint 1.0.7 (vendored, MAX_L=5) · fftw3 3.3.10 · blas Accelerate ║
║ dispersion: dftd3 1.4.0 · dftd4 4.2.0 ║
If you cloned from main instead of release, the first line
reads dev X.Y.Z.devN (main @ <sha>) (with a dirty flag if the
working tree has uncommitted changes). The exact
libint / libxc / spglib / libecpint / fftw3
versions match what setup_native_deps.sh vendored
(libecpint annotates its bundled angular-momentum cutoff
MAX_L=5 so a build can be matched to a MAX_L mismatch at a
glance). The trailing blas … field records which BLAS backend
Eigen got linked against – Accelerate on macOS, OpenBLAS +LAPACKE for an optimised Linux install, etc. See
BLAS for the full label table. The banner
exercises the C++ extension under the hood (each linked library
reports its own version through the pybind11 module), so seeing it
is proof both that the Python side imports and that the native
side loaded.
If even that crashes, fall back to the minimal smoke test that isolates the C++ extension load from anything else:
.venv/bin/python -c "import vibeqc; print(vibeqc.hello())"
# vibeqc core alive
End users should run the banner check and one small calculation. Contributors should select the affected test lane:
.venv/bin/python scripts/test_gate/run_full_suite.py \
--wt "$PWD" --list-lanes
.venv/bin/python scripts/test_gate/run_full_suite.py \
--wt "$PWD" --py .venv/bin/python --lane <affected-lane>
See Running calculations and Developer test lanes. The full inventory is a release-confidence tool, not the default installation smoke test.
Optional terminal viewer (MolTUI)¶
Vibe-qc writes Molden files
by default for any calculation that calls run_job(...). Those
files render in any of Avogadro, Jmol, VMD, PyMOL,
Molden, or ChimeraX – but if you’d rather inspect orbitals
inline in the terminal (handy on a remote SSH session, or when
you’re iterating fast), MolTUI
is the right tool. Pure Python; renders geometries, orbitals, and
normal modes via Unicode block characters.
Two ways to install it alongside vibe-qc:
1. As a vibe-qc extra – single command, captures the dependency in your install record:
.venv/bin/pip install '.[viewer]' # from the repo checkout
(pip install 'vibe-qc[viewer]' will become the right command once
vibe-qc lands on PyPI – not yet.)
2. Interactive script – run any time after the venv is set up; re-runnable, asks before installing each tool:
./scripts/install_optional_tools.sh
# → "Install moltui? [Y/n]"
Pass --yes for non-interactive automation, or a tool
name to install just that one (./scripts/install_optional_tools.sh moltui). Use --upgrade to refresh an already-installed tool,
--venv PATH or --python BIN to choose the target explicitly, and
--dry-run to preview the pip command. For example:
./scripts/install_optional_tools.sh --venv .venv --upgrade --yes moltui
After install:
.venv/bin/python water.py # produces water.molden
.venv/bin/moltui water.molden # render in the terminal
MolTUI also supports .cube (vibe-qc’s grid output), .fchk,
.xyz, .gbw (ORCA), and .hess (ORCA normal modes), so the
same install lets you view files from external codes too.
If your output is a .qvf¶
vibe-view renders QVF archives in the terminal itself, no extra tool required – and because a QVF is one self-describing archive, the same command reaches the band structure, spectra, SCF trail, charges and citation bundle, not just the geometry:
vibe-view show water.qvf # one frame, then exit (base install)
vibe-view tui water.qvf # interactive; install with --extras tui
For a dedicated terminal install, run
./vibe-view/scripts/install.sh --extras tui from the repository root. For an
existing viewer environment, run
./vibe-view/scripts/update.sh --skip-git --extras tui. A bare public-index
pip install 'vibeview[tui]' does not work because vibeview is not on PyPI.
Like MolTUI it needs no GUI and no display server. See
reading a .qvf in the terminal, over SSH.
Pick MolTUI for loose files or output from other codes; pick terminal mode
when you have a .qvf.
Optional basis-set optimization driver (vibe-basis)¶
vibe-basis drives external SCF programs (currently CRYSTAL23) under
an optimization loop to fit new basis sets. It is the modern successor
to the CRYSTAL09 + MINUIT2 pipeline behind pob-TZVP, and is co-located at
vibe-basis/ in this checkout and versions independently of vibe-qc
(see vibe-basis/VERSIONING.md).
You need it only if you are fitting basis sets. Using an existing basis set needs nothing here.
Use its standalone installer. It owns vibe-basis/.venv, so it never
collides with vibe-qc’s compiled root environment:
./vibe-basis/scripts/install.sh # standard profile (SciPy)
./vibe-basis/scripts/install.sh --extras all # every optimizer backend
Profiles are core, standard, optimizers, all, and test. The
standard profile is the recommended starting point. The queue tool vq is a
separate co-located project rather than a public package dependency; request
it explicitly when you want queue integration:
./vibe-basis/scripts/install.sh --with-vq # requires Python 3.12+
The same standalone environment has update, reinstall, and uninstall entry points. Uninstall retains source and user calculation data:
./vibe-basis/scripts/update.sh
./vibe-basis/scripts/reinstall.sh
./vibe-basis/scripts/uninstall.sh
The root lifecycle also accepts --extras basisopt when you intentionally want
vibe-basis in the compiled vibe-qc environment. It resolves the co-located
package explicitly because pip does not read [tool.uv.sources]. The dedicated
standalone environment above remains the recommended onboarding path.
Installing it is also what makes vibeqc.basis_optimization’s CRYSTAL
recipe modules importable. calculators and
recipes.crystal_stage1..3 / crystal_objective / production import
vibe_basis directly. Without the extra they raise
ModuleNotFoundError; the rest of vibeqc.basis_optimization (the
parametrisation, gradients, BDIIS driver and LD diagnostics) works
without it.
After install:
vibe-basis/.venv/bin/vb --version
vibe-basis/.venv/bin/vb parse crystal my-run.out # energy + convergence flags
Common issues¶
“Preflight: the following build prerequisites are missing”
setup_native_deps.sh aborts upfront if a build tool / header /
library it needs isn’t on the box. The message names every missing
item and ends with the exact per-distro install command – copy it,
run it, re-run ./scripts/setup_native_deps.sh. The check runs at
the very top of the script so you never end up halfway through a
libint build before discovering pkg-config was missing.
Set VIBEQC_SKIP_PREFLIGHT=1 only if you know the message is a
false positive (e.g. a custom-prefix install the heuristic doesn’t
find); the underlying CMake errors are much less actionable.
“python ≥3.11 on PATH (found python3 = 3.9 – likely Apple’s stub)”
You’re on macOS and /usr/bin/python3 wins over Homebrew’s install.
Fix:
brew install python@3.14 # if not already
eval "$(/opt/homebrew/bin/brew shellenv)" # current shell
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc # persist
brew link --overwrite --force python@3.14 # if still not first
python3 --version # confirm 3.14.x
The preflight detects this case explicitly because the Apple stub silently breaks the venv-and-pip step later with a much less obvious message.
./scripts/build_libint.sh: line N: brew: command not found
You’re on Linux but the script tried the macOS path. This was fixed
in 0.1.0+; pull main and re-run. The script now sniffs uname -s
and uses the right toolchain per platform.
“Could not find Libint2 / Libxc / Spglib / FFTW3”
CMake didn’t find one of the vendored installs. The most common cause
is that setup_native_deps.sh was interrupted partway through.
Re-running it is safe – finished deps short-circuit, only the
unfinished one rebuilds.
If you genuinely want to point at a system install instead of the
vendored one, simply don’t run that dep’s build script. CMake silently
falls through to system discovery if third_party/<dep>/install/ is
absent.
“error: externally-managed-environment” on macOS
You’re trying to pip install against Homebrew’s system Python.
PEP 668 blocks this; always use a virtualenv:
python3 -m venv .venv && .venv/bin/pip install -e '.[test]'
libint build is slow
The libint code generator produces a large amount of source for
max_am=5 plus derivatives through 2nd order (several thousand files).
The generated-kernel count grows roughly as max_am^4, and since
2026-08-06 the 2nd-derivative stratum is generated at max_am=4
(g functions) rather than 3, which triples that stratum. The compile
phase uses Ninja which parallelizes; expect 1.5-2 h on a modern
8-core machine, longer on Mac minis / small VMs. This is a one-time
cost per checkout: re-running the install scripts skips a libint
install that is already present.
Since 2026-08-13 the codegen + compile chatter goes to
third_party/libint/build.log rather than the terminal; the terminal
shows one heartbeat line per minute (elapsed time, last Ninja step,
disk/memory headroom), and if the build fails, the last 200 log lines
are replayed so the error is always visible. Follow the full output
live with tail -f third_party/libint/build.log, or set
VIBEQC_BUILD_VERBOSE=1 to stream everything into the terminal as
before. The log stays still during the single-threaded codegen step
(20-30 min): that is Ninja buffering one long step, not a hang; the
heartbeat keeps counting.
That build is a choice rather than a fixed cost. --libint-max-am sets it:
./scripts/install.sh --libint-max-am 5_4_3
The three numbers are the max angular momentum at derivative orders 0, 1 and 2, each in the range 1..6:
Spec |
Build |
Energies |
Gradients |
Hessians |
|---|---|---|---|---|
|
~30 min |
h (L=5) |
g (L=4) |
f (L=3) |
|
~1.5-2 h |
h |
g |
g |
|
longer |
i (L=6) |
h |
g |
|
longest |
i |
i |
i |
Above a stratum’s limit libint throws rather than returning a wrong
number, so the spec only decides which basis sets each derivative
order accepts: no computed value changes. Dropping to 5_4_3 costs
you analytic Hessians on a g-function basis (def2-TZVPP heavy atoms,
cc-pVQZ, def2-QZVP) and nothing else; energies, gradients, geometry
optimization and every periodic path are bit-identical. Going up to
6_5_4 buys i-function energies for cc-pV6Z-class work.
6 is the ceiling: vibe-qc’s periodic AO-pair Fourier transform throws
above cart_to_sph_data.hpp’s kMaxL = 6, so a higher libint would
build integrals the periodic stack cannot consume. The error message
says so, and says what raising it would take.
The same flag exists on update.sh and update_native_deps.sh, and
the setting is recorded in the built tree, so you can change your mind
in either direction later without knowing any force flags:
./scripts/update.sh --libint-max-am 5_4_4
That rebuilds libint, and only libint. ./scripts/doctor.sh reports
which spec the current install was built with.
On Linux the install scripts automatically cap parallelism to
prevent the OOM-kill pattern that hung planetx on 2026-05-16. The
cap is min(nproc, max(2, mem_mb // 15000), 8) – 15 GB/worker
budget, hard ceiling of 8 even on monster boxes. Concretely:
Host (Linux) |
nproc |
RAM |
parallelism |
|---|---|---|---|
planetx (32 th, 125 GB) |
32 |
125 GB |
8 |
mars (16 th, 62 GB) |
16 |
62 GB |
4 |
small VM (4 th, 16 GB) |
4 |
16 GB |
2 |
The same scripts also self-re-exec under nice -n 19 ionice -c 3
on Linux so the build runs at idle CPU + IO priority – the box
stays responsive while compiling. The mechanism is in
scripts/_safe_build_env.sh (sourced by every entry-point script
that triggers heavy compilation).
To override either side-effect:
# Pin parallelism to a specific value (skips the formula).
CMAKE_BUILD_PARALLEL_LEVEL=12 ./scripts/setup_native_deps.sh
# Skip the nice/ionice re-exec (use full CPU + IO priority).
VIBEQC_BUILD_NICED=1 ./scripts/setup_native_deps.sh
# Silence the cap-announcement banner.
VIBEQC_BUILD_ENV_QUIET=1 ./scripts/setup_native_deps.sh
On macOS the cap doesn’t engage (no /proc/meminfo, no
ionice) – set CMAKE_BUILD_PARALLEL_LEVEL manually if your dev
box is RAM-constrained.
Python 3.14 + some dependency refuses to build Most scientific packages have wheels for 3.11-3.13; 3.14 is bleeding edge and occasionally missing binary wheels (numpy, pyscf, scipy typically catch up within a few weeks). Stick to 3.12 or 3.13 if you hit this.
Clean rebuild
If everything goes sideways, the safe button is update.sh --clean:
./scripts/update.sh --clean
which removes the pinned native source/build/install caches and Python build
caches, then failure-atomically replaces .venv/ after rebuilding from
source. Do not delete python/vibeqc/basis_library/basis/: that is tracked
runtime data, not a generated cache. For a reinstall that preserves the native
builds, use:
./scripts/reinstall.sh --skip-native-deps
“Is my install OK?” – doctor.sh
Run ./scripts/doctor.sh for a read-only health report:
working-tree state, which vendored third_party/<dep>/install/
trees exist, build-stamp drift against the current build_*.sh
files, venv health (broken python / stale pip shebang / pyvenv.cfg
mismatch), and the banner. No builds, no installs – safe to run
at any time, including during an in-flight calculation.
Updating¶
./scripts/update.sh # → latest tagged release
./scripts/update.sh --dev # → bleeding-edge main (X.Y.devN banner)
The wrapper handles git pull + stamp-aware setup_native_deps.sh +
pip install -e '.[test]' + the new-banner print
in one shot – and refuses to run if the working tree is dirty
(stashing-without-asking is worse than failing loud). It also refuses before
changing Git when no usable venv exists. --recreate-venv preserves the
existing base interpreter by default; select a different one explicitly with
--recreate-venv --python python3.13.
The dependency scripts compare version, build-recipe, and artifact stamps and
automatically rebuild an affected library when those inputs drift.
--rebuild-native-deps is the repair and audit option that forces clean
rebuilds of all vendored trees; it is not required for an ordinary pinned
version update:
./scripts/update.sh --rebuild-native-deps
./scripts/update.sh --dev --rebuild-native-deps
If you keep two checkouts side-by-side (one for production runs,
one for dev), use update.sh (or --release) inside the release
tree and update.sh --dev inside the dev tree. The full option set
the manual-equivalent recipe (for debugging an update that didn’t take) are in
updating.md.
Picking a build to test against¶
vibe-qc’s runtime banner records which git revision produced any
output (see release_process.md). When you
want to run calculations against a specific build for testing –
comparing against release, validating a topic-branch fix, etc.
– update.sh --ref takes any branch or tag:
./scripts/update.sh --ref v0.9.0 # pin to a tag
./scripts/update.sh --ref feature/some-topic # try a branch
The banner on the next run will then read e.g. Release v0.9.0 or
dev 0.9.0 (feature/some-topic @ abc1234), which is what you’ll see
prepended to every persisted SCF log.