Library / SDK
dimforge/kiss3d avatar
dimforge/kiss3d

kiss3d trades shaders and features for a simple window

Keep it simple, stupid 3d graphics engine for Rust.

1,790 stars200 forksRustBSD-3-Clause

At a glance

What is it?
kiss3d is a Rust graphics engine built on wgpu whose stated goal is the opposite of completeness: open a window with a camera and a light, draw primitives, and get out of the way. The README is candid that it is not designed to be fast or feature-complete, and the crate version in the manifest has moved well past the one the README shows.
Who is it for?
Adopt kiss3d when you want a Rust program that opens a window and draws geometry this week, when running the same code in a browser matters, and when wgpu is a backend you are already prepared to debug. Do not adopt it for photoreal rendering, physics-heavy work, or a project that needs a mature asset pipeline, because the README explicitly disclaims both speed and completeness.
Can I use it commercially?
Yes. BSD-3-Clause 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 18 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 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The pitch is stated as an argument against other engines

The README opens by explaining where kiss3d comes from. It is born from frustration that today's 3D graphics libraries are either too low level, where you write your own shaders and opening a window takes eight hours, 300 lines of code and ten litres of coffee, or high level but too hard to understand, built for photoreal or near-photoreal animation and games with so many features that drawing a few objects becomes work.

Then the honest part, which is unusual in a project README: kiss3d is not designed to be feature-complete or fast. It is designed to let you draw simple geometric figures and play with them with as little friction as possible.

That sentence is the whole contract. Anyone evaluating it should read it again after looking at the examples directory, which contains fog, depth of field, colour grading, HDR bloom, clustered lights, global illumination in 2D, raytracing and instancing examples. The engine has grown well past the README's summary, and the tension between a deliberately minimal pitch and a broad example set is the interesting thing about the project today.

The identity is also inherited. The author listed in Cargo.toml is Sébastien Crozet, and the crate keywords list graphics, wgpu and KISS. The name refers to the keep it simple, stupid principle it borrows from the military design doctrine, which is also the name of the older 3D library lineage it descends from.

One async main runs unchanged on native and in a browser

The example scene is short enough to read in one breath: create a window, create an orbit camera, create an empty scene, add a point light, add a cube, rotate it each frame.

rust
use kiss3d::prelude::*;

#[kiss3d::main]
async fn main() {
  let mut window = Window::new("Kiss3d: cube").await;
  let mut camera = OrbitCamera3d::default();
  let mut scene = SceneNode3d::empty();
  scene
          .add_light(Light::point(100.0))
          .set_position(Vec3::new(0.0, 2.0, -2.0));

  let mut c = scene.add_cube(1.0, 1.0, 1.0).set_color(RED);

  let rot = Quat::from_axis_angle(Vec3::Y, 0.014);

  while window.render_3d(&mut scene, &mut camera).await {
    c.rotate(rot);
  }
}

Two details carry the cross-platform claim. `#[kiss3d::main]` is a procedural macro from the separate `kiss3d-macro` crate, which Cargo.toml pins at 0.36.1, and the main function is `async`. On native platforms the runtime is driven with `pollster::block_on`; on WASM the async function integrates with the browser's `requestAnimationFrame` event loop.

That is the mechanism behind the README's claim that the same code works on native platforms and WASM without changes. You never write a platform branch, never maintain two entry points, and `while window.render_3d(...).await` is the loop, with the `await` on the render call being where the frame boundary sits.

The scene graph is minimal but present. `SceneNode3d::empty()` is a root, `add_cube` returns a handle you keep to mutate, `add_light` attaches a light with a position, and the mutating calls chain, so `set_color(RED)` returns something you can hold.

Note the styling. `OrbitCamera3d::default()` replaces several lines of camera setup, and the README states that out of the box you get a default arc-ball camera and a point light, with a first-person camera also available and user-defined cameras possible.

Input handling is on by default and can be overridden

The default controls are listed explicitly, which tells you what a first run feels like: scroll zooms in and out, left click plus drag looks around, right click plus drag translates the view point, and enter looks at the origin.

The README notes these are handled by default by the engine and can be overridden by the user. There is no code example for the override in the README, so the mechanism is not documented there, but the fact that it is configurable is stated.

The built-in behaviours are sensible defaults for inspection rather than for a game. An arc-ball camera with drag to orbit is what you want when you are loading a scene and looking at it. A first-person camera with translation is what you want once you know where you are.

Geometry support is listed as boxes, spheres, cones, cylinders, quads and lines, plus per-object colour or texture and per-object transform. The examples directory shows how far the current version goes beyond that list: glTF import, custom meshes, custom materials, an inspector, events, blend modes in 2D, an effect chain in 2D, camera modes, group hierarchies, adding and removing nodes at runtime, and an `android/` directory suggesting mobile is a target.

Two examples are worth singling out for what they imply about the engine's internals. `dda_raycast2d.rs` points to a raycaster, and `rt_switcher` in Cargo.toml confirms a raytracing path exists alongside the rasterizer, with a comment describing it as mainly for debugging and experiments comparing the two.

Optional features decide whether you need FFmpeg or an immediate mode GUI

The manifest lists five features. Two are headline features for users, and the rest reveal what the crate is willing to carry.

`recording` enables recording the 3D scene to MP4 video files, and it requires FFmpeg installed on your system. The README gives the platform commands: `brew install ffmpeg` on macOS, `sudo apt install ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev` on Ubuntu or Debian, and a download from ffmpeg.org added to PATH on Windows. Enabling it in Cargo.toml looks like this:

toml
[dependencies]
kiss3d = { version = "0.40", features = ["recording"] }

The feature maps to `dep:ffmpeg-the-third`, a Rust binding crate, so you are compiling FFmpeg bindings as well as installing the system library.

`egui` gives immediate mode GUI support, mapping to `dep:egui`, `dep:egui-wgpu` and `dep:rfd`. The manifest comment on `rfd` explains the third one: it powers the inspector's native Open dialogs, and is unused on WASM where it falls back to a plain path text field. That is a small detail with a lot of information in it about how the crate handles platform differences.

`serde` enables serialisation across `glamx/serde`, `bitflags/serde` and `rgb/serde`, so scene data and colour types can round-trip through a serialised format.

`rt_switcher` is the odd one out, and the comment above it is candid: it exists so you can flip between the raytracer and the rasterizer while keeping only the `.render_3d` call, rather than manually switching between `.render_3d` and `.raytrace_3d`. The comment says this is mainly for debugging and experiments. An engine shipping a feature flag for its own experiments is a sign of where the project is in its life.

The base dependency list is short and tells you the backend story: the `wgpu` keyword in Cargo.toml names the graphics API, and the dependencies include bitflags, bytemuck with derive, gltf 1.4 with import, utils and names, image 0.25 with default-formats, log 0.4, web-time 1, the macro crate, and `glamx` 0.3 for maths. `web-time` is the cross-platform replacement for `std::time::Instant` that works in a browser, which is the kind of small dependency that makes the WASM claim true rather than aspirational.

The README version and the manifest version do not agree

This is the first thing to check before pinning a dependency.

The README's compilation section says to add the following to your Cargo.toml:

toml
[dependencies]
kiss3d = "0.37"

Cargo.toml in the repository root declares `version = "0.47.0"`. Ten minor versions apart. The optional features section also uses `version = "0.40"` in both its recording and egui examples.

So the README is behind the crate by a wide margin, and the two feature snippets disagree with the plain dependency snippet as well as with the manifest. None of these numbers is wrong on its own terms; they were correct when written. But a reader who copies the README gets an old release, and a reader who copies the feature example gets a different old release than the one above it.

Take the version from crates.io or from the manifest, not from the prose. The edition is 2018, the licence is BSD-3-Clause, and the repository field points back at github.com/dimforge/kiss3d.

The `include` list is also worth reading if you vendor the crate. It packages only source files, WGSL shaders, a text font directory, a built-in bin asset, the examples, and the licence files. Shaders live in `src/**/*.wgsl` as real files, so anything that needs a custom shader means working inside that layout rather than embedding strings in Rust.

Active on a master branch with no tagged releases

The repository is not archived and the last push was on 2026-10-04. There are no GitHub releases at all, and the default branch is master rather than main.

With no GitHub release history shown, Cargo.toml records the repository's version. For a library distributed on crates.io this works, since the published crate carries its own version, but it does mean you cannot inspect a release history in the repository or find a dated note about what changed between 0.47.0 and 0.46.

A CHANGELOG.md is present at the root, so the history exists in some form, and AUTHORS, a `rustfmt.toml`, a `.typos.toml` and a `run_all_examples.sh` script sit alongside it. The website directory and the separate kiss3d.rs and kiss3d.dimforge.com links suggest documentation lives outside the repository and is built from it.

The licence is BSD-3-Clause, which is permissive, requires an attribution notice in redistributions, and has no copyleft reach. For a library you intend to vendor into a commercial project that is the uncomplicated case.

The honest framing for anyone evaluating it: this is an actively changing engine with a broad example set, a candid README about its own limits, and documentation that lags the code. Check the examples directory against the version you are about to pin, because the examples are the accurate description of what the library can currently do, and the feature list in the README is the description of what it promises.

Editorial conclusion

Adopt kiss3d when you want a Rust program that opens a window and draws geometry this week, when running the same code in a browser matters, and when wgpu is a backend you are already prepared to debug. Do not adopt it for photoreal rendering, physics-heavy work, or a project that needs a mature asset pipeline, because the README explicitly disclaims both speed and completeness. Verify first the version you pin, since the README shows kiss3d = "0.37" while Cargo.toml declares 0.47.0, and check which optional features you actually need because recording pulls in ffmpeg-the-third and egui pulls in egui, egui-wgpu and rfd.

Frequently asked questions

How do I add kiss3d to a Rust project?

Add it to your Cargo.toml dependencies. The README shows `kiss3d = "0.37"`, but Cargo.toml in the repository declares version 0.47.0, so check crates.io for the current version before pinning.

Does kiss3d work in a browser with WebAssembly?

Yes, and the README says the same code works on native platforms and WASM without changes. The `#[kiss3d::main]` macro and the async rendering API handle the difference: pollster::block_on on native, and requestAnimationFrame on WASM.

What graphics API does kiss3d use?

wgpu. The keywords in Cargo.toml list graphics, wgpu and KISS, and the optional egui feature pulls in egui-wgpu for the immediate mode GUI.

How do I record a kiss3d scene to video?

Enable the recording feature and install FFmpeg first. On Ubuntu or Debian that means `sudo apt install ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev`, and on macOS `brew install ffmpeg`. Then add `features = ["recording"]` to the dependency, which pulls in the ffmpeg-the-third bindings.

What mouse controls does kiss3d provide by default?

Scroll zooms in and out, left click plus drag looks around, right click plus drag translates the view point, and enter looks at the origin. The README states these are handled by default by the engine and can be overridden by the user.

Is kiss3d fast or feature complete?

The README states plainly that kiss3d is not designed to be feature-complete or fast. It is designed to let you draw simple geometric figures and play with them with as little friction as possible.

Official sources

  1. dimforge/kiss3d on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. Project website
  5. README
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dimforge-kiss3d.svg)](https://hysenlabs.com/projects/dimforge-kiss3d)