Guide
Linux
nsh apps also run on Linux. The Linux backend renders them with GTK 4 widgets and lays out text with Pango; the core,
the reactive graph, the renderer, Taffy layout and the nsh/ui/mobile components are the same as on iOS and Android,
so one bundle runs everywhere. On Linux, Platform.OS is "linux" and the desktop={{…}} props apply.
#Requirements
- GTK 4.14 or later. To build nsh’s Linux runtime (from a checkout, or
cargo xtask diston Linux) you need their development packages and clang:libgtk-4-dev clangon Debian and Ubuntu (24.04 or later),gtk4 clangon Arch,gtk4-devel clangon Fedora. - GStreamer plugins for the video formats your app plays (GTK plays video through GStreamer).
#Running an app
On Linux, nsh run opens the app in a GTK window (390×844 by default), with hot reload, logs in the terminal and the
error overlay as on the other targets:
nsh run my-app # --target linux is the default on Linux
In a checkout, nsh run builds the development host (nsh-linux-host) first; the distribution made on Linux ships
it in runtime/linux/. Ctrl-C closes the window, and closing the window ends nsh run. The host also runs a built
bundle on its own:
nsh build my-app --release -o build
dist/nsh/runtime/linux/nsh-linux-host --bundle build/bundle.qbc --size 1024x768 # in a checkout: target/debug/nsh-linux-host
--size is the window’s default size; tiling window managers may give the window another one.
#Packaging
nsh package my-app --target linux [--run]
Writes a directory and the same as an archive:
out/<Name>/
<Name> the executable (nsh's release runner)
nsh/bundle.qbc your app, compiled
nsh/assets/… the assets it imports
nsh/app.json the window title and the application id
<id>.desktop a desktop entry (StartupWMClass is the id)
<id>.png the icon, when nsh.json names one
out/<Name>.tar.gz
The executable finds nsh/ next to itself (a symbolic link to it, in ~/.local/bin say, works too). GTK 4 and Pango
must be installed where the app runs. To show the app in a desktop’s launcher, put the executable (or a link) on the
PATH, the .desktop file in ~/.local/share/applications and the icon in an icon theme directory. --run launches
the app after packaging it.
#Embedding in a GTK app
The nsh-platform-linux crate (from the nsh repository) gives a Rust GTK app AppView: one nsh engine as a GTK widget.
Each AppView is independent; several can run at once.
use std::rc::Rc;
use nsh_platform_linux::{gtk4 as gtk, AppOptions, AppView, AssetBase, Bundle};
use gtk::prelude::*;
fn main() -> gtk::glib::ExitCode {
let app = gtk::Application::builder().application_id("com.example.host").build();
app.connect_activate(|app| {
let window = gtk::ApplicationWindow::builder().application(app).default_width(390).default_height(844).build();
let view = AppView::new(AppOptions {
asset_base: Some(AssetBase::Directory("app/assets".into())),
..AppOptions::default()
});
// register native components here, before loading
let code = std::fs::read_to_string("app/bundle.js").expect("bundle");
view.load(Bundle::source(code).into());
window.set_child(Some(&view.widget()));
// The window keeps the view; closing it stops the app.
let keep = std::cell::RefCell::new(Some(Rc::clone(&view)));
window.connect_destroy(move |_| if let Some(view) = keep.take() { view.stop() });
window.present();
});
app.run()
}
AppView::load replaces whatever ran; stop ends the app. asset_base tells it where asset:/ URIs resolve
(AssetBase::Directory or AssetBase::Http). Bytecode bundles (bundle.qbc) load with unsafe { Bundle::bytecode(bytes) }:
QuickJS bytecode is trusted input, so only load it from your own app’s files.
Native components are registered with AppView::register_component; see Native components.
#What differs on Linux
The environment is a desktop’s: the safe area and the keyboard height are 0, Platform.constants.interfaceIdiom is
"desktop", Platform.Version is the kernel’s major and minor version, and dark mode follows the desktop’s setting
(through the XDG settings portal) live. See Device and environment.
Not supported:
WebView: it would need WebKitGTK; a web view shows a neutral placeholder.- Video
rate: GTK plays at normal speed only.onEndonly comes for videos that do not loop. - Zooming scroll views (
zoomTo, the zoom props). mixBlendModeandbackdropFilter(the background color still draws);borderCurve: "continuous"draws circular corners.- Selectable text, input accessory views and the status bar (no desktop equivalent).
- Accessibility:
accessiblegrouping, customaccessibilityActions; live regions are announced instead.
#See also
- CLI:
nsh run --target linux,nsh package --target linux - Packaging
- Platform-specific code