Skip to content

Authoring Extensions

A Rust app can share ordinary modules, or it can author a native extension that Go and TypeScript apps load. Rust apps enable crate features instead of listing extensions in config.

#Choose an extension type

What you are addingWhat you ship
Components or application logicA Rust module or crate
Optional QuickGUI capabilitiesCargo features such as updater and terminal
A native service for Go or TypeScriptA cdylib, a manifest, and a typed wrapper

A Rust app already links quickgui. It does not load a separate host library.

#Create an extension project

quickgui init-extension my-extension --type rust

Use this when Go or TypeScript apps should consume a native service. --npm-package sets the artifact package name.

#Share a component

Export functions that return Element:

use quickgui::{Color, Element, text};

pub fn notice(message: impl Into<std::sync::Arc<str>>) -> Element {
    text(message)
        .p(12.0)
        .bg(Color::rgb8(239, 246, 255))
        .text_color(Color::rgb8(30, 64, 175))
        .rounded(8.0)
}

Return notice("Saved") as a child. Keep application-wide services outside View::render.

#Lay out a native extension

A native extension ships quickgui.extension.json, a versioned shared library, and declared resources. Rust extensions can vendor extension_api.rs and build a cdylib without linking the renderer. See the Go Authoring Extensions guide for the native contract.

#Declare dependencies

Rust applications enable features in Cargo.toml. Keep the crate version already in your project:

[dependencies]
quickgui = { version = "...", features = ["terminal"] }

Go and TypeScript consumers declare the extension package in their own config.

#Implement the native contract

Implement invoke and shutdown. Copy borrowed input before returning, keep events scoped to their sessions, and release workers when a session stops.

#Automatic registration

Go and TypeScript CLIs bundle declared extensions. A Rust app has nothing extra to register: Cargo links the crates you depend on.

#Build and package artifacts

App edits rebuild the selected crate. Rebuild an extension when its native implementation changes, then rebuild the consuming Go or TypeScript app.

#Test and distribute

Test a packed cdylib with the generated demo app. Rust applications call crate APIs directly instead of invokeExtension.