PhotonImplemented

Realtime product state

Photon is a Rust pub/sub runtime with typed topics and durable subscriptions. Storage is pluggable, with memory, SQLite, NATS, Fluvio, and Kafka adapters, and the same publish and subscribe code runs embedded or brokered.
Each topic page lists its subscriptions and the latest events published to it.

Why it exists

Photon gives you typed topics and subscriptions while your data stays in your datastore. The transport carries short-lived, encrypted events, and the browser refetches the data it shows when one arrives.

On this site

Photon pushes updates to the counter demo and the notification bell on this site. It notifies the UI; Valence or your datastore remains authoritative.
Typed topics and subscribers
Implemented
Declare topic payloads and subscriber handlers through #[topic] and #[subscribe].
Durable subscriptions
Implemented
Checkpoint sequence positions per partition for subscribers that must resume after restart.
Keyed topics
Implemented
Partition and filter event streams by declared payload keys.
Storage and broker adapters
Implemented
Run on memory or SQLite, or connect NATS, Fluvio, and Kafka for fleet deployments.
Browser synchronization
Implemented
Mark a server function with #[photon_leptos::synced] and choose whether the browser refetches, replaces or appends when the topic fires.
Retention
Implemented
Set one retention policy for the runtime: maximum event age, sweep interval, and whether dead letters are kept. Kafka and Fluvio handle retention on the broker.
Photon operator UI
Implemented
Inspect topics, subscriptions, and events from the runtime on this host at /photon.

See it in action

Code sample

Taken from the getting-started docs. See all code samples on Resources.
Photon topicPhoton
Typed topic + durable subscribe
use std::sync::Arc;
use photon::{subscribe, topic, JsonIdentityFactory, Photon};
use photon_core::Actor;

#[topic(name = "orders.created", keyed_by = "order_id")]
pub struct OrderCreated {
    pub order_id: String,
    pub amount_cents: u64,
}

#[subscribe(topic = "orders.created", durable = "billing")]
async fn on_order_created(actor: Box<dyn Actor>, event: OrderCreated) -> photon::Result<()> {
    tracing::info!(actor = actor.label(), order = %event.order_id, cents = event.amount_cents);
    Ok(())
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Requires PHOTON_TRANSPORT_KEY (base64, 32 bytes).
    let photon = Photon::builder().auto_registry().build()?;
    photon.start_executor(Arc::new(JsonIdentityFactory))?;

    OrderCreated {
        order_id: "ord-1".into(),
        amount_cents: 9900,
    }
    .publish_on(&photon)
    .await?;
    Ok(())
}