Skip to content

Getting Started

wirelessEye edited this page Jun 29, 2026 · 3 revisions

Getting Started

Nestix is a Rust workspace with three core crates:

  • nestix: the crate most applications and component libraries import.
  • nestix-signal: the reactive runtime.
  • nestix-macros: procedural macros used through nestix.

The main crate re-exports the macros and signal primitives, so most code can use one import:

use nestix::*;

Add the Dependency

While Nestix is developed in this repository, run the following command in your terminal:

cargo add nestix --git https://github.com/wirelesseye/nestix.git

Create a Component

Components are ordinary Rust functions annotated with #[component].

use nestix::{Element, component, layout};

#[component]
fn App() -> Element {
    layout! {
        Text("Hello from Nestix")
    }
}

The #[component] macro turns the function into a component type. The function body still reads like normal Rust and returns any mountable component output: (), Element, Option<Element>, or layouts containing elements.

Mount a Root

Nestix can mount a component tree, but it does not know how to render platform objects by itself.

use nestix::{layout, mount_root};

mount_root(&layout! { App });

For a real application, the mounted tree must contain renderer components that create host objects, provide handles, listen for placement changes, and clean up on unmount. See Renderer Integration.

Use State

Use create_state for mutable reactive values. Reads inside effect!, computed!, layout if branches, or reactive props establish dependencies.

use nestix::{Element, callback, component, computed, create_state, layout};

#[component]
fn Counter() -> Element {
    let count = create_state(0);

    layout! {
        Button(
            .on_click = callback!([count] || count.set(count.get() + 1)),
        ) {
            Text(computed!([count] || format!("Count: {}", count.get())))
        }
    }
}

Use Props

Define component props with #[props].

use nestix::{Element, Shared, component, layout, props};

#[props(debug)]
#[derive(Debug)]
pub struct ButtonProps {
    #[props(default)]
    disabled: bool,
    on_click: Option<Shared<dyn Fn()>>,
}

#[component]
pub fn Button(props: &ButtonProps) -> Element {
    layout! {
        Text(if props.disabled.get() { "Disabled" } else { "Enabled" })
    }
}

Fields become PropValue<T> unless they use #[props(extends(...))]. That lets callers pass either plain values or signals:

layout! {
    Button(.disabled = computed!([busy] || busy.get()))
}

Explore the Example

The repository includes nestix/examples/example-web-app, a small web renderer and application. It demonstrates:

  • a root component that provides the DOM mount handle;
  • host components for Div, Text, Button, and Input;
  • state and computed values;
  • keyed list rendering with for item in items where key = ...;
  • event callbacks with callback!.

Clone this wiki locally