A

WebXrayDB: Rebuilding an X-ray Reference Database in Rust/WASM, and Why Sample Preparation Matters More Than We Admit

May 5, 202610 min read
Back to all posts

A look at WebXrayDB, a Rust/WebAssembly and React implementation inspired by XrayDB, with local X-ray reference data, sample preparation calculators, self-absorption tools, and a Tauri desktop build.

Share

Introduction

If you work with X-ray absorption spectroscopy, XAS, or XAFS, you have almost certainly used XrayDB either directly or indirectly. XrayDB, maintained by Prof. Matt Newville and contributors, packages atomic data, characteristic X-ray energies, and X-ray cross sections in a SQLite database with a Python interface.

webxraydb-rs takes the same general idea and rebuilds it with Rust + WebAssembly, adds a React interface, and then layers a set of beamline planning and sample preparation calculators on top.

The WebXrayDB elements screen. The periodic table leads into element-level X-ray reference data.The WebXrayDB elements screen. The periodic table leads into element-level X-ray reference data.

Credit first

The data curation work belongs to the XrayDB project. webxraydb-rs is not meant to replace XrayDB. It is a complementary deployment that repackages well-maintained atomic data for browser and desktop use, then adds practical sample-preparation tools on top.

Putting the database in the browser

The first engineering problem was how to bring the data itself into the browser. SQLite is an excellent packaging format for a Python library: it is self-contained, queryable, and fast. For a static web page, though, shipping a SQLite file plus the runtime needed to read it is more overhead than I wanted for a read-only reference database.

In webxraydb-rs, the source tables are rebuilt and re-encoded into a compact read-only binary representation, then embedded directly in the WASM bundle. Edges, emission lines, scattering factors, and attenuation coefficients for the periodic table are downloaded during the initial load.

After that, all calculations are local. There is no server round trip, no rate limit, and no maintenance window. Once the page is cached, it keeps working even when the network is unreliable. That local-first property becomes especially useful for the sample preparation tools.

Ninety percent of analysis quality is decided during sample preparation

My practical feeling from XAFS work is that roughly 90% of how smoothly the final analysis goes is decided at the sample-preparation stage. I do not mean that 90% of the working time is spent preparing samples. I mean that if the sample is prepared correctly, the downstream analysis becomes dramatically more straightforward.

The reverse is also true: if the sample preparation was compromised, even sophisticated downstream analysis cannot fully recover what the measured data has already lost.

Pressing a pellet with the right thickness, targeting a reasonable edge step, choosing transmission or fluorescence, and selecting a dilution level that avoids crushing the EXAFS oscillations through self-absorption are not cosmetic details. These choices largely determine whether background subtraction, normalization, and fitting feel stable after the beamtime.

The sample preparation section in webxraydb-rs is an attempt to turn that workflow intuition into software. Three calculators share the same local data layer.

Pellet mass calculation for transmission XAS

Given a target edge step, typically around Δμt≈1, this tool estimates the required sample and diluent masses. It helps check whether the sample is in a usable transmission range before beamtime.

Transmission

The Preparation Helper compares candidate conditions for Fe2O3 in transmission and fluorescence modes.The Preparation Helper compares candidate conditions for Fe2O3 in transmission and fluorescence modes.

Preparation Helper does not pretend that there is a single magic dilution ratio. Instead, it evaluates edge step and self-absorption predictions, then presents several conditions that are likely to produce usable data.

This interaction would be awkward if every edit had to call a remote API. Because the calculation core is running next to React as WASM, changing a formula or geometry parameter can immediately update the local calculation.

Self-absorption deserves its own section

The most technically interesting part of this implementation is the self-absorption correction.

When a concentrated sample is measured in fluorescence mode, fluorescent X-rays generated inside the sample can be reabsorbed by the sample before reaching the detector. The observed EXAFS oscillation amplitude is therefore suppressed. If that suppression is ignored, coordination numbers can be underestimated and Debye-Waller factors can be distorted.

Classical algorithms, including the line of work from Tröger, Eisebitt, and Pfalzer, introduce simplifications to make the problem analytically manageable. Common assumptions include the thick-sample limit, where the sample is effectively treated as semi-infinite, and the assumption that EXAFS oscillations in the correction term can be ignored. These assumptions are reasonable in some regimes, but they stop being reliable outside those regimes.

Booth and Bridges formulated a treatment that can handle arbitrary sample thickness and concentration while retaining the EXAFS contribution in the correction term. They frame the correction in terms of the absorption coefficient μ rather than directly correcting χ, which avoids ambiguity from different χ normalization conventions across analysis pipelines.

webxraydb-rs takes the same Booth-equation family and pushes it from the numerical side. The core idea is to make one explicit assumption by fixing χ to a chosen value, then solve the remaining geometry, concentration, and thickness dependence numerically.

The Self Absorption screen plots retained amplitude around the Fe K-edge for Fe2O3.The Self Absorption screen plots retained amplitude around the Fe K-edge for Fe2O3.

In practice, this means the same correction routine can be used for a dilute Fe/silica pellet, a thick electrode laminate, or a frozen aqueous sample without manually switching between thin- and thick-sample mental models. The app can show the Ameyanagi, Booth, and Tröger curves side by side so the user can decide which behavior is appropriate.

The self-absorption algorithms are also split out into a separate selfabs crate. They are not locked inside the web app or WASM binding layer, so they can be reused from ordinary Rust code.

Use the desktop build at the beamline

The web app can run offline after it has been loaded once, but beamline networks are not always friendly. Visitor Wi-Fi may fail, external domains may be blocked, and shared computers may not let you install the environment you want.

For that reason, GitHub Releases also provides Tauri 2 desktop builds for Linux, macOS, and Windows. After launch, the app runs locally and does not require an external connection.

The practical advantage is that you do not need to install a Python runtime or heavy scientific dependencies such as NumPy, SciPy, and SQLAlchemy on the beamline computer. Python environments are powerful, but on shared computers they can be blocked by permissions, version mismatches, or package build issues. A Tauri app is much easier to carry into the hutch and launch when you need it.

Technical stack

The app is not just a thin web UI. The Rust/WASM calculation core is the center of the design.

LayerTechnology
FrontendReact 19, TanStack Router, Tailwind CSS 4, Vite 7, Plotly, KaTeX
WASMRust, wasm-bindgen, wasm-pack
X-ray data layerxraydb crate, chemical-formula crate
Self absorptionselfabs crate
DesktopTauri 2
Package managerBun

The current UI collects element lookup, edge lookup, line lookup, attenuation, absorption formulas, scattering factors, sample preparation, self absorption, ion chambers, mirror reflectivity, Darwin widths, and analyzer crystal tools in one interface.

Why this matters for the XAFS community

XAFS has an unusual entry barrier. The physics can be written cleanly on paper, but the practical knowledge required to turn that physics into interpretable data is often transmitted orally inside labs.

What edge step should I aim for? When is fluorescence better than transmission? What BN-to-sample ratio should I try first? How do I recognize data damaged by excessive absorption? New graduate students often learn these answers by failing at the beamline, which is an expensive way to learn.

A tool that turns part of that tacit knowledge into sliders, plots, and candidate conditions does not replace experience. It does, however, shorten the ramp-up. If a first-year student can enter a proposed composition and immediately see that transmission is unrealistic while roughly 5 wt% in BN for fluorescence looks plausible, the first few beamtimes change.

The project thesis is simple: build the data layer once, package it as a small local bundle that works almost anywhere, then put practical decision tools on top. Sample preparation should be treated as a first-class part of the analysis workflow, not as a prelude to the real analysis.

Credits and data sources

The data sources are the same family used by XrayDB: Elam/Ravel/Sieber, Chantler, and Waasmaier-Kirfel. The work of collecting, maintaining, and making these X-ray data practically useful belongs to Prof. Matt Newville and the XrayDB contributors.

webxraydb-rs is best understood as a complementary deployment: the same well-maintained atomic data, packaged for browser and desktop use, plus sample preparation tools for the moment when it is 2 a.m. and you are standing in front of a sample press wondering whether you should have diluted the pellet by another factor of two.

The project is dual-licensed under MIT / Apache-2.0. If the idea is useful, a star on the GitHub repository is appreciated. Bug reports, feature requests, and pull requests are welcome.

References

Written by

Ameyanagi

Ameyanagi

Principal Scientist at the intersection of chemistry and computational science. Passionate about XAFS analysis, heterogeneous catalysis, and Rust programming.