otter-lua. Shared layout, drawing, Wayland, configuration, and desktop services stay native.
Repository structure
The otter-shell organization has one Git repository per component. The workspace root is a thin repository containing package submodules. Commit component code in its own repository; root changes only track workspace files and submodule pins.
otter-zenith pins the shell release in
pins.json and the compiler in otr-toolchain.pin. Each component’s otr/build.otr runs from its package root, for example cd otter-bar; otr run otr/build.otr --release-fast -- check.
Architecture
otter-http provides native HTTP/HTTPS, otter-crypto provides cryptographic primitives, and otter-cue provides opt-in interaction sounds. otter-lua connects hosted scripts to native services.
UI applications describe layout through otter-ui, emit otter-render command lists, and rasterize into Wayland shared-memory buffers. Lua builds frames through native bindings; it does not replace the native layout or rasterizer.
The otr applications statically link their Otter libraries and support Lua plugins for extensions. Shared
libotter_*.so APIs and the Zig .so plugin ABI are unsupported.
Toolchain and retained Zig code
Use otr 0.2.0 and matching v0.13.0 component trees. System development dependencies vary by package; Building explains runners, dependency preparation, and verification. Zig 0.17.0 builds the terminalvt/, package-manager zapt/, highlighting zhl/, and static PipeWire boundaries. The browser remains on its separate zig-maint source/library set and WPE WebKit packaging path. Otter Bench and its separate gaming packaging also retain their own Zig library pins; do not build them against otr-only library siblings. Legacy differential scripts can require a preserved historical tree or frozen Zig artifacts; removed root Zig build files are not available in a clean otr checkout. Use zig build only where the component’s instructions call for it.
Configuration and Lua paths
Application settings use$XDG_CONFIG_HOME/otter-shell/, defaulting to ~/.config/otter-shell/. Shared styling is selected by theme.conf; plugin policy uses plugins.conf, and selected surface UI choices use ui.conf.
Store Lua code in data directories: user plugins under $XDG_DATA_HOME/otter-shell/plugins/, and user surface scripts under $XDG_DATA_HOME/otter-shell/ui/. The default data home is ~/.local/share. See Configuration overview.
Packaging boundaries
otter-shelladds desktop applications tootter-shell-core. Neither defines a user-session compositor. The greeter uses Hyprland for its login screen only.- Assistant and speech packages belong to
otter-shell-extras. - Otter Bench and Otter HUD belong to the separate
otter-gaming-utilsmetapackage. otter-hyprandotter-cueare workspace components, not standalone end-user packages in zenith’sdebian/control.- A library appearing in release pins does not imply an installable package with that name.
Next
- Building from source: package runners and verification
- Creating an app: native application development
- Writing plugins: Lua extension development
- Libraries overview: native APIs and Lua bindings

