Salva simulates fluids as particles for Rust games
2 and 3-dimensional fluid simulation library in Rust.
At a glance
- What is it?
- Salva is a Rust library for two and three dimensional particle based fluid simulation, with several pressure solvers, viscosity and surface tension models, and optional two-way coupling to rigid bodies. It suits game and animation work where a full fluid solver is more than the pipeline can carry.
- Who is it for?
- Adopt Salva if you are writing Rust and need real time fluid behaviour in a game or animation, especially if you want 2D and 3D from one codebase or need the simulation to exchange forces with rigid bodies.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 76 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A solver, not a game engine
Salva is a two and three dimensional particle based fluid simulation engine for games and animations. The word engine here means the physics solver, not a rendering stack or a scene graph, and the repository layout reflects that division. The top level is src/, examples2d/, examples3d/, build/, Cargo.toml, a CHANGELOG.md, a LICENSE and a publish.sh script. The examples directories hold the demonstrations, and the documentation says the demos are based on WASM and WebGL 1.0 so they should work on most modern browsers, with a note to ask for help and discuss features on the project's Discord. So the audience is a Rust developer who has a renderer, or who intends to write one, and needs the fluid behaviour underneath. The topics on the repository place it firmly: animation, fluids, gamedev, pbf, physics, rust, sph. The names pbf for position based fluids and sph for smooth particle hydrodynamics are the two families of method behind the library, and both appear in the feature list. The homepage is salva.rs, with a users guide, and separate 2D and 3D API documentation on docs.rs for the salva2d and salva3d crates.
One codebase, two dimensions, four published crates
The claim that 2D and 3D implementations share mostly the same code is the structural fact that makes the library interesting. The workspace in Cargo.toml makes that concrete. Its members are build/salva2d, build/salva2d-f64, build/salva3d and build/salva3d-f64, along with the two example crates, and the default members are the four library crates. The build directory holds the crate manifests that generate the dimension and precision variants, and the patch section of the workspace manifest maps the crates.io names salva2d, salva2d-f64, salva3d and salva3d-f64 onto those local paths. So the dimension is a compile time choice rather than a separate implementation, and there is a f32 and an f64 build of each. That distinction matters more than it sounds. A game running on a wide range of hardware often needs the 32 bit build for memory and iteration cost, while an offline or offline-adjacent pipeline that cares about accumulated numeric error wants the 64 bit one. The rust.unexpected_cfgs lint configuration in the workspace lists the feature values dim2, dim3, nphysics and ncollide, which tells you the feature flags that select the dimension and the optional backends. The library uses nalgebra for vector and matrix math.
The solver set is where the real choice lies
The feature list reads like a menu of numerical methods, and picking between them is the main design decision a user makes. Pressure resolution offers DFSPH and IISPH. Viscosity covers DFSPH viscosity, artificial viscosity and XSPH viscosity. Surface tension includes WCSPH surface tension plus methods from He et al. 2014 and Akinci et al. 2013. Elasticity is supported through a method from Becker et al. 2009. Multiphase fluids let you mix several fluids with different characteristics such as densities and viscosities. Optional two-way coupling with bodies from rapier is available, and there is WASM support. What the list does not say is which combination is right for your scene, and that is the practical gap. Each of these methods trades cost against behaviour in a different way, and the library exposes the choice without documenting a decision guide. If you are building a game, the artificial viscosity option is often the one people reach for first because it is the cheapest way to stop particles from clumping, while the multiphase support is the feature that justifies a dedicated library at all if your content needs more than one liquid with different properties. Expect to experiment rather than to configure.
Coupling to rigid bodies works, but the workspace still patches rapier
Two-way coupling with rapier is the feature that makes Salva usable inside a real game rather than a demo, and the way it is described is precise: the library can optionally interface with rapier for two-way coupling with rigid bodies, multibodies and deformable bodies. The mechanism is the part to understand, because the direction of force exchange is where fluid games usually go wrong. Two-way coupling means the fluid applies forces to the bodies and the bodies push back on the fluid, so a floating crate displaces water and the water slows the crate, rather than the two systems passing through each other. Rapier comes from the same organisation, dimforge, which also maintains parry, the collision detection library, so the integration is between related code. The caveat is visible in the workspace manifest. A TODO comment reads remove these patches once a rapier release ships, and beneath it sit commented out patch entries pointing at local git paths and at a branch on the dimforge/rapier repository, including names such as rapier_testbed2d and rapier_testbed3d. The [patch.crates-io] section currently redirects only the four salva crates, so the rapier patching is set aside in comments rather than active. In other words, the coupling is available in the project but the exact rapier build it was developed against is not what you will get from crates.io, so budget time for that integration.
Running the examples is the fastest way to see it work
The examples are the entry point, and the two commands to run them are short:
cargo run --release -p examples2d --bin all_examples2
cargo run --release -p examples3d --bin all_examples3The release profile is used because the workspace manifest sets a development profile with opt-level = 1, with a comment explaining that the examples otherwise seem laggy. That single line is a useful warning about the library in general. A particle based fluid solver does a lot of work per frame, and running it in a debug build is not a fair test of whether it fits your frame budget. The examples themselves are separate workspace members, so cargo resolves the correct package and binary for you without any path juggling. Beyond that, the library itself is consumed from crates.io, where the project publishes the salva2d and salva3d crates, and the API documentation for each is published on docs.rs. The users guide on the project website is the place to start for the concepts, and the Discord server is where the project asks for feature discussion.
The licence is permissive and the project is quiet but alive
Salva is licensed under Apache-2.0, which is a permissive grant with an explicit patent clause, so commercial use and modification are both straightforward provided you carry the notice. The licence file sits at the root of the repository. On the maintenance side, the repository is not archived and the last push to it was on 2026-08-08, so the work is current as of that date, though the absence of GitHub releases means there is no version history to point at and no tagged artefacts to diff between. The published versions live on crates.io instead, and the presence of a CHANGELOG.md in the root is where the version history for each change is recorded. The dimforge name on the repository is worth noting for context, since the same group maintains rapier and parry, so the two-way coupling is between projects that share an author rather than an integration assembled from unrelated code. The scope of the library is also narrower than the name suggests. It solves for fluid motion and hands you particle positions, and it does not render, so the visual quality of the result depends entirely on what you build on top: a point sprite renderer, a screen space fluid pass, or a mesh extraction step are all on you. That boundary is what makes it usable inside a game engine you already have, and it is also the reason the examples are minimal WASM demos rather than a full demonstration.
Editorial conclusion
Adopt Salva if you are writing Rust and need real time fluid behaviour in a game or animation, especially if you want 2D and 3D from one codebase or need the simulation to exchange forces with rigid bodies. Do not adopt it if you need a renderer, a scene graph or an offline bake, since the library is the solver and its examples are minimal WASM demos, and note that the workspace carries only commented out rapier patch entries, a sign the coupling was developed against a rapier build you will not get from crates.io. Before you start, read the users guide at salva.rs, check that the salva2d or salva3d crate on crates.io matches the API you need, and confirm the simulation cost is acceptable for your target frame rate before you wire it into a game loop.
Frequently asked questions
What is Salva used for?
Salva is a 2D and 3D particle based fluid simulation engine for games and animations, written in Rust. It uses nalgebra for vector and matrix math and can optionally couple two-way with rigid bodies from rapier.
How do I run the Salva examples?
Run `cargo run --release -p examples2d --bin all_examples2` or `cargo run --release -p examples3d --bin all_examples3` from the repository. The examples are based on WASM and WebGL 1.0 so they should work on most modern browsers, and the release profile is used because the dev profile makes them seem laggy.
Which fluid simulation methods does Salva support?
Pressure resolution with DFSPH and IISPH, viscosity with DFSPH viscosity, artificial viscosity and XSPH viscosity, surface tension with WCSPH plus methods from He et al. 2014 and Akinci et al. 2013, elasticity from Becker et al. 2009, and multiphase fluids with different densities and viscosities.
How does Salva couple with rigid bodies?
It can optionally interface with rapier for two-way coupling with rigid bodies, multibodies and deformable bodies. The workspace manifest also carries commented out patch entries for rapier, with a TODO to remove them once a rapier release ships, so the exact rapier build the coupling was developed against is not the one you get from crates.io.
Which Salva crates are published?
The workspace builds and publishes salva2d, salva2d-f64, salva3d and salva3d-f64, so there is a 32 bit and a 64 bit build for each dimension. The 2D and 3D implementations share mostly the same code, with the dimension selected through feature flags such as dim2 and dim3.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dimforge-salva)Was this useful?