plugins/ — every handler crate, and nothing else
Two directories, and a plugin crate lives in one of them:
| directory | what is in it | built for |
plugins/native/ |
every handler crate — python, maven, media, skidbladnir, rust-toolchain, git | the host |
plugins/wasm/ |
the wasm examples — today just znippy-plugin-maven-wasm |
wasm32-unknown-unknown |
Nothing under plugins/ is a copy of anything else under plugins/.
The one rule the wasm side follows
A plugins/wasm/ crate holds no ecosystem logic. It depends on the plugins/native/ crate for its ecosystem and exports only the five symbols znippy-common/src/plugins/wasm/wasm_loader.rs imports:
alloc(u32) -> u32 reserve linear memory
result_len() -> u32 length of the last result
extract(path_ptr, path_len, data_ptr, data_len) -> u32 JSON object, or `null`
plugin_extensions() -> u32 "a,b,c"
plugin_schema() -> u32 "name:type,name:type"
For maven that shim is ~40 lines over plugins/native/znippy-plugin-maven, whose pom.rs, lib.rs JAR scan and row.rs field writer are target-independent and compile unchanged for wasm32.
Build and check the wasm example
cargo build --target wasm32-unknown-unknown --release -p znippy-plugin-maven-wasm
cargo test -p znippy-plugin-maven-wasm
The test loads the real .wasm through the real loader and asserts it answers with the same ExtensionRow as NativeMavenPlugin over the same bytes — including a DEFLATE JAR, where the two sides run different decompressors (native fans across ljar/gatling, wasm runs the single-threaded linflate scan) and must still land on the same row. A missing or stale .wasm fails the test with the build command; it never skips.
What is NOT here
znippy-common/src/plugins/native/*.rs — the six in-common handlers (cargo, npm, rpm, deb, gem, conda) plus skeletons.rs. They are MODULES in a crate, not crates, and they stay there. The native/ + wasm/ split inside znippy-common/src/plugins/ is the same rule as this directory's, one tier down: no plugin source sits loose outside it. They are native, and they stay there. They import only std and arrow, and they are public API of a published crate: holger/traits/src/lib.rs reaches six of them as znippy_common::plugins::<x>_native::<X>Plugin in non-test code. Moving them into crates here would require those crates to depend on znippy-common for ArchiveTypePlugin while znippy-common re-exported them back, which is a package cycle cargo rejects — so the published path would just vanish. Measured 2026-08-05, they cost gunnar's dependency guard zero crates, so nothing is bought by paying that. See .nornir/plugins-design.md §f3 (rule P-5).