viexp must let Linux users disable, replace and add file-type behaviors easily. Research
(research/plugin-architecture) shows: declarative rules carry configuration, external
process contracts carry ~90% of real-world extension, and embedded interpreters are the most
expensive layer to stabilize (yazi is still "beta" partly because of it). WASM (zellij) costs
host complexity that a single-maintainer learning project cannot afford.
Options considered
Option
Pros
Cons
Phased: TOML rules → script contract → Lua (mlua)
each phase shippable; users' language of choice; no unsafe early
three layers to document eventually
Lua from day 1
yazi-grade power early
API design + FFI before first working product; high frustration risk
WASM components (wasmtime/extism)
best sandboxing
WIT churn, users must compile components; zellij-scale effort
External-only
simplest
no stateful in-process previews/fetchers ever
Decision (confirmed with the project owner, 2026-10-17)
v0.1 — declarative registry: modules.toml maps mime/glob → previewer/opener; per-module
enabled switch; user rules merge via prepend_*/append_* (yazi semantics). All built-in
modules dispatch through the same tables.
v1.0+ — embedded Lua via mlua with vendored Lua, registered through the same tables;
only for what scripts cannot do (stateful/in-process previews). Re-evaluate Luau if sandbox
isolation becomes a requirement. WASM is explicitly rejected for v1.x.
Consequences
Positive: shippable increments; extension by Linux-familiar means; Lua postponed until the
host API is stable enough to expose.
Negative: three layers of documentation eventually; write-back protocol must be designed
carefully once and frozen.
Mitigations: one dispatch model for all layers (yazi lesson); contract docs written as part
of the v0.2 sprint DoD, not after.