The one C library that survived every previous purification pass — Oniguruma, pulled in transitively through candle’s tokenizer dependency — is gone, and for the first time the fix reaches everyone who depends on the published crate, not just this workspace.
Today we released Kizzasi 0.2.3 — a purity-and-portability release: the default build now compiles zero C for downstream consumers too, a pure-Rust video backend lands alongside the existing FFmpeg one, and Apple Metal acceleration becomes safe to enable from any host.
No C. No C++. No Fortran. And, as of this release, no Oniguruma even in the crates published to crates.io. Kizzasi still compiles to a single static binary (or WASM) and runs no_std on microcontrollers.
video, video-pure, metal, and mqtt-tls all stay opt-in — the CPU-only, FFmpeg-free, TLS-free default build is unchanged.
Why Kizzasi 0.2.3 is a game changer
Three separate cracks had opened in the “100% Pure Rust” claim:
- Upstream candle’s mandatory
tokenizersdependency selects theonigfeature, which compiles the Oniguruma C library — the one C compilation that survived every earlier purification pass, with no configuration lever inside Kizzasi to turn it off. The previous release candidate patched around it locally with a[patch.crates-io]entry pointing at a sibling../candlecheckout — which fixed the build here and nowhere else, because[patch]does not propagate to crates.io. Anyone depending on a published Kizzasi crate was still compilingonig. kizzasi-core’smetalfeature forwarded straight tocandle-core/metal. Cargo features aren’t target-aware, so that one line also fired on Linux and Windows, pulling in candle’s Metal backend and, with it,objc2— whoselib.rsopens witherror: objc2 only works on Apple platforms.cargo build/test/clippy --all-features, the exact command the README documents and CI runs, could not complete anywhere except macOS.kizzasi-io’s video support was FFmpeg-only, meaning every consumer who wanted video paid for a C dependency even if they only needed to read a handful of Y4M files or a webcam.
Kizzasi 0.2.3 ends all of that. The tensor backend moves to a COOLJAPAN fork that drops onig for good — verified from outside this workspace with cargo tree -i onig — a new kizzasi-metal crate makes the Metal feature target-scoped instead of target-blind, and a pure-Rust video backend (the OxiMedia stack) gives video-pure users an FFmpeg-free path for files and cameras alike.
Technical Deep Dive: what changed
- The tensor backend moved from
candle-core/candle-nntooxicandle-core/oxicandle-nn, the COOLJAPAN fork of candle 0.11.0. The fork selectsfancy-regexinstead ofonig(tracking upstream candle PR #3790). The dependency keys are unchanged —candle-core/candle-nnwithpackage = "oxicandle-*"— souse candle_core::…compiles unchanged and no source file in the workspace was touched.candle-metal-kernelsno longer needs a patch entry of its own either: both fork crates now depend on the upstream registrycandle-metal-kernels 0.11.0directly. kizzasi-metal— a new workspace crate that exists to solve a Cargo problem, not a Rust one. A Cargo feature can’t be conditional on target, but a Cargo dependency can — so this crate declarescandle-coretwice, once undertarget.'cfg(target_vendor = "apple")'with themetalfeature and once without, andkizzasi-core’s feature becomesmetal = ["dep:kizzasi-metal"]. Apple builds get the real GPU backend; every other target builds a small inert crate, andis_metal_available()/new_device()/device_ordinals()return honest errors naming the target instead of a CPU device in disguise. A renamed-alias alternative was tried first and rejected by Cargo itself —cargo metadata --filter-platformrefuses a manifest depending on the same crate “multiple times with different names.”kizzasi-io’svideo-purefeature decodes Y4M (YUV4MPEG2) files end to end — demux, YUV→RGB/RGBA/Gray conversion, bilinear rescale — and captures from cameras on Linux (V4L2), macOS (AVFoundation), and Windows (Media Foundation), negotiating NV12/YUYV/UYVY/planar-4:2:0/RGB24/MJPEG in ascending conversion cost. The old 2,152-linesrc/video.rs— previously a near-total stub, whereVideoReader::newnever opened anything andmetadata()was hardcoded to 30fps/1920x1080 — is now split intosrc/video/{mod, types, processing, backend_ffmpeg, backend_pure, backend_pure_camera}.rs; the publickizzasi_io::Video*surface is unchanged, and a newVideoBackendenum (Auto/Ffmpeg/Pure) picks the pure path automatically wherever it’s compiled in and can open the source.mqtt-tlsmoved off rustls’s defaultaws-lc-rsprovider (which compiles the AWS-LC C/assembly library) onto an explicitly-injected pure-Rust RustCrypto provider,oxitls-rustcrypto-provider. Cipher suites narrow to the 9 AEAD suites the provider implements — ECDHE-{ECDSA,RSA} × {AES-GCM,ChaCha20} plus the three TLS 1.3 suites — with no CBC suites.
Getting Started
Nothing changed in the basic Rust API — add the crate and predict:
cargo add kizzasi
use kizzasi::prelude::*;
fn main() -> KizzasiResult<()> {
let config = KizzasiConfig::new()
.model_type(ModelType::Mamba2)
.input_dim(3)
.output_dim(3)
.hidden_dim(256)
.state_dim(16)
.num_layers(4)
.context_window(8192);
let mut predictor = Kizzasi::new(config)?;
let output = predictor.step(&array![0.1, 0.2, 0.3])?;
println!("Predicted: {:?}", output);
Ok(())
}
New in 0.2.3 — decode a Y4M file or a webcam with zero FFmpeg linkage:
use kizzasi_io::{VideoConfig, VideoReader, VideoBackend};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = VideoConfig::from_file("clip.y4m").with_backend(VideoBackend::Pure);
let mut reader = VideoReader::new(config).await?;
while let Some(frame) = reader.read_frame().await? {
let rgb = frame.to_array()?; // ndarray::Array3<u8>
println!("frame {}: {:?}", reader.current_frame(), rgb.shape());
}
Ok(())
}
And probe the Metal backend directly if you need to know before enabling it end to end:
match kizzasi_metal::new_device(0) {
Ok(device) => println!("Metal device ready: {device:?}"),
Err(err) => println!("no Metal device: {err}"),
}
What’s New in 0.2.3
- Zero C, downstream too: the candle fork (
oxicandle-core/oxicandle-nn) drops theonigC dependency from the default build of every published Kizzasi crate, not just this workspace. - New crate:
kizzasi-metal— a target-scoped activation shim that makeskizzasi-core’smetalfeature buildable on every platform and live only on Apple. - New feature:
video-pureonkizzasi-io— pure-Rust Y4M decode and Linux/macOS/Windows camera capture via the OxiMedia stack, alongside the existing FFmpeg-backedvideofeature. mqtt-tlsis pure Rust: RustCrypto (oxitls-rustcrypto-provider) replaces rustls’s defaultaws-lc-rs, narrowing to 9 AEAD cipher suites with no CBC.- Fixed:
--all-featuresbuilds/tests/clippy on non-Apple hosts, previously broken byobjc2;VideoConfig::from_camera’s defaultcamera_format, previously hardcoded to"video4linux2"on every OS, now agrees withCameraDevice::default_format()’s per-platform value.
Tips
- If you build with
--all-featureson Linux or Windows, you’re unblocked.metalno longer pullsobjc2off Apple — enabling it there is inert but honest:is_metal_available()isfalseandget_best_device()stays on CPU instead of erroring out the whole build. - Verify your own downstream build with
cargo tree -i onig. After depending on any Kizzasi 0.2.3 crate, it should come back empty — that’s the whole point of the fork. video-pure’s camera enumeration is more honest thanvideo’s. On Linux,oximedia-capturereports a device only whenVIDIOC_QUERYCAPconfirms real capture/streaming capability, instead of listing every/dev/video*node unconditionally — re-check any code that relied on the old unfiltered list.- A live camera can’t seek.
video-purereturnsIoError::Unsupportedrather than silently dropping frames if you callwith_start_time/seek on a camera source; network streams and non-Y4M containers still route to FFmpeg only. - If your MQTT broker is CBC-only, the handshake will now fail.
mqtt-tls’s 9 supported suites are all AEAD — that’s deliberate, not a regression.
This is the foundation
Kizzasi 0.2.3 keeps riding SciRS2 0.6 with OxiFFT and Oxicode, and now adds the OxiMedia stack (oximedia-container/-core/-cv/-capture/-codec/-simd) as its pure-Rust video layer and oxitls-rustcrypto-provider as its pure-Rust TLS layer, alongside the WebGPU backend on wgpu and neuro-symbolic constraints on tensorlogic-ir. It shares the deep-learning neighborhood with ToRSh, TensFloweRS, TrustformeRS, and SkleaRS, and sits alongside OxiLLaMa, OxiONNX, and VoiRS — a sovereign alternative to the PyTorch/CUDA/GGML/FFmpeg world for signals that aren’t text.
Repository: https://github.com/cool-japan/kizzasi
Star the repo if compiling zero C — even for the people who depend on your crate — is something you want from your signal-prediction stack. The era of “it’s pure Rust, except for what your dependents end up pulling in” is over. Pure Rust, all the way down the dependency graph, is here.
— KitaSan at COOLJAPAN OÜ August 13, 2026