Compo - Declarative and Reactive Component Framework
Compo is a general-purpose declarative and reactive component framework designed for single-threaded asynchronous
execution, offering high performance and safety guarantees.
It does not include any pre-implemented components but provides a #[component]
macro and essential type exports,
completely independent of third-party libraries.
Suitable for GUI scenarios or other similar non-GUI component systems.
Features
- Concise Syntax: Eliminates 99% of unnecessary boilerplate code, making it simple to use.
- Declarative Components: Easily define components using the
#[component]
macro. - Reactive Rendering: Automatically re-renders child components when dependent variables change.
- Minimal Trait Dependencies: No
Send
/Sync
or'static
constraints, and no cross-thread synchronization mechanisms. - Single-Threaded Async: Efficiently runs in a single-threaded environment, ideal for high-performance scenarios.
- No Third-Party Dependencies: Fully standalone, with no external libraries.
- Safety Guarantees: Strict type checking and runtime safety mechanisms.
Quick Start
Installation
Add Compo to your Cargo.toml
:
cargo add compo
Example Code
Here's a simple example demonstrating how to define and use components:
use *;
async
async
async
async
Running the Example
When you run this example with cargo run --example basic
, you'll see the following output:
hello, 0
9 seconds.
world, 0
world, 1
8 seconds.
7 seconds.
6 seconds.
5 seconds.
4 seconds.
3 seconds.
2 seconds.
1 seconds.
0 seconds.
Hello, app!
This output demonstrates:
- The button component first renders with default text "hello" and id=0
- The countdown component starts emitting events with countdown values from 9 to 0
- The button component re-renders with text "world" and id=0, then again with id=1
- The app component continues receiving countdown events
- After the countdown completes, the app component prints "Hello, app!"
API Documentation
#[component]
Macro
Used to define components. Components must be asynchronous functions and support rendering child components and reactive updates.
#[render]
Attribute
Marks child components for rendering. If dependent variables change, the child component will re-render.
#[field]
Attribute
Defines internal fields for components, with lifetimes matching the run
function.
#[event]
Attribute
Marks a component parameter as an event emitter. This allows child components to send events to their parent components. The parameter should be of type Option<T>
, where T
is the type of data to be emitted. Events can be emitted using the .emit()
method and received by the parent component using the .listen().await
method.
Contributing
Issues and Pull Requests are welcome!
License
Apache-2.0