Release announcement / LightNVR
One source of truth. A new build of LightNVR.
Introducing lightnvr-rs: the work behind our Rust build, why C remains the source of truth, and how we keep the two connected.
A milestone worth sharing
LightNVR 0.47.3 is now available with lightnvr-rs, our generated Rust build. The first release includes a Debian sid package and binary archive for Linux amd64, alongside a container image at ghcr.io/opensensor/lightnvr-rs:0.47.3.
LightNVR began with a practical goal: make network video recording accessible on modest hardware, with footage under the operator’s control. That work has grown into a system with its own recording lifecycle, camera integrations, web interface, and API contracts. Preserving that accumulated behavior matters to us.
With lightnvr-rs, we have brought a Rust build into that same project. We are proud of the engineering behind it: taking an established C application through translation, compilation, packaging, and behavioral checks, and making that process part of the development workflow.
The accomplishment is a repeatable path from the code we maintain to another build of the software. It gives us a concrete foundation for further work on Rust while keeping today’s contributors focused on one implementation.
Why keep C at the center?
Embedded hardware is a central reason. LightNVR serves Linux devices across ARM, x86, and MIPS, and Rust support varies by the exact processor, operating system, and C library. Some relevant targets, including MIPS Linux variants, are Tier 3 in Rust: target support exists, but official builds and automated upstream build and test coverage are absent. Making Rust mandatory would add toolchain and qualification work for those platforms. Keeping the native C build lets us continue supporting embedded devices through their existing C toolchains while developing the Rust build on platforms we can validate.
A second, independently maintained backend would mean keeping two implementations aligned whenever a feature changes or a bug is fixed. For an NVR, seemingly small differences in authentication, stream handling, or shutdown behavior deserve careful attention. We wanted an approach that keeps those decisions in one place.
C remains the source of truth. Contributors make their changes in the existing codebase, and automation produces the Rust crate from those sources. The frontend is shared. This lets us explore a Rust build without asking every contributor to implement each change twice.
We also want to make the build useful to teams evaluating Rust adoption. Those evaluations need to distinguish the source language and the safety properties of the resulting program. Publishing the methodology makes that distinction inspectable.
Make the process repeatable
The pipeline uses C2Rust with pinned translator and compiler versions. Mechanical adaptations needed by the generated code live in the generation tooling, so they can be applied again when the C sources change.
Generated Rust is tracked with a manifest that maps modules back to hashes of their C inputs. CI regenerates the crate, builds it, and runs smoke and API contract tests against the resulting executable. Guard checks reject manual edits to the generated tree and differences from fresh generation.
That separation matters: product behavior belongs in the maintained C code; reproducible translation fixes belong in the tooling. Generated files are an output of the process. A patch should remain understandable after the next regeneration.
What this milestone establishes
Today’s output is C-shaped, unsafe Rust. It retains raw pointers and links native libraries, including FFmpeg, SQLite, and libuv. Its safety properties are essentially those of the C build. A successful Rust compilation does not make the whole program memory-safe, and this release should not be treated as proof that an organization’s memory-safety requirements have been met.
Smoke and API contract checks give us evidence about the behaviors they exercise. They do not establish complete feature parity, media correctness, or long-running reliability across every camera and hardware configuration. Those require their own qualification.
What we have built is a maintained translation workflow, a traceable connection to the C sources, and a place to measure progress. We think that is an accomplishment worth explaining on its own terms.
A foundation we can build on
Reducing unsafe code over time will require deliberate work on ownership, interfaces, and the native-library boundaries. Any such changes also need a maintenance strategy that survives regeneration. We intend to evaluate that work with the same emphasis on reproducibility and observable behavior.
For now, contributors can continue working in C. People interested in the Rust build can inspect the generator, the manifest, and the checks alongside the rest of LightNVR. We welcome reports that include the build, configuration, and steps needed to reproduce a result.
We are proud of how far LightNVR has come, and grateful to the contributors and users whose fixes, testing, and feedback make this work possible. This is a new chapter in the same open-source project.