Gpui Entity

Manage component state and async operations safely in GPUI apps

✨ The solution you've been looking for

Verified
Tested and verified by our team
9771 Stars

Entity management and state handling in GPUI. Use when working with entities, state management, or entity lifecycles.

gpui rust state-management entities reactive frontend async components
Repository

See It In Action

Interactive preview & real-world examples

Live Demo
Skill Demo Animation

AI Conversation Simulator

See how users interact with this skill

User Prompt

I need to share a counter value between multiple GPUI components and update it from different places in my app

Skill Processing

Analyzing request...

Agent Response

Code showing how to create an Entity<T> for shared state, pass it between components, and safely update it with proper notifications

Quick Start (3 Steps)

Get up and running in minutes

1

Install

claude-code skill install gpui-entity

claude-code skill install gpui-entity
2

Config

3

First Trigger

@gpui-entity help

Commands

CommandDescriptionRequired Args
@gpui-entity shared-state-between-componentsCreate and manage state that multiple components need to access and modifyNone
@gpui-entity async-state-updatesHandle API calls and async operations that need to update component stateNone
@gpui-entity reactive-component-architectureBuild components that automatically re-render when their state changesNone

Typical Use Cases

Shared State Between Components

Create and manage state that multiple components need to access and modify

Async State Updates

Handle API calls and async operations that need to update component state

Reactive Component Architecture

Build components that automatically re-render when their state changes

Overview

Overview

An Entity<T> is a handle to state of type T, providing safe access and updates.

Key Methods:

  • entity.read(cx)&T - Read-only access
  • entity.read_with(cx, |state, cx| ...)R - Read with closure
  • entity.update(cx, |state, cx| ...)R - Mutable update
  • entity.downgrade()WeakEntity<T> - Create weak reference
  • entity.entity_id()EntityId - Unique identifier

Entity Types:

  • Entity<T>: Strong reference (increases ref count)
  • WeakEntity<T>: Weak reference (doesn’t prevent cleanup, returns Result)

Quick Start

Creating and Using Entities

 1// Create entity
 2let counter = cx.new(|cx| Counter { count: 0 });
 3
 4// Read state
 5let count = counter.read(cx).count;
 6
 7// Update state
 8counter.update(cx, |state, cx| {
 9    state.count += 1;
10    cx.notify(); // Trigger re-render
11});
12
13// Weak reference (for closures/callbacks)
14let weak = counter.downgrade();
15let _ = weak.update(cx, |state, cx| {
16    state.count += 1;
17    cx.notify();
18});

In Components

 1struct MyComponent {
 2    shared_state: Entity<SharedData>,
 3}
 4
 5impl MyComponent {
 6    fn new(cx: &mut App) -> Entity<Self> {
 7        let shared = cx.new(|_| SharedData::default());
 8
 9        cx.new(|cx| Self {
10            shared_state: shared,
11        })
12    }
13
14    fn update_shared(&mut self, cx: &mut Context<Self>) {
15        self.shared_state.update(cx, |state, cx| {
16            state.value = 42;
17            cx.notify();
18        });
19    }
20}

Async Operations

 1impl MyComponent {
 2    fn fetch_data(&mut self, cx: &mut Context<Self>) {
 3        let weak_self = cx.entity().downgrade();
 4
 5        cx.spawn(async move |cx| {
 6            let data = fetch_from_api().await;
 7
 8            // Update entity safely
 9            let _ = weak_self.update(cx, |state, cx| {
10                state.data = Some(data);
11                cx.notify();
12            });
13        }).detach();
14    }
15}

Core Principles

Always Use Weak References in Closures

 1// ✅ Good: Weak reference prevents retain cycles
 2let weak = cx.entity().downgrade();
 3callback(move || {
 4    let _ = weak.update(cx, |state, cx| cx.notify());
 5});
 6
 7// ❌ Bad: Strong reference may cause memory leak
 8let strong = cx.entity();
 9callback(move || {
10    strong.update(cx, |state, cx| cx.notify());
11});

Use Inner Context

1// ✅ Good: Use inner cx from closure
2entity.update(cx, |state, inner_cx| {
3    inner_cx.notify(); // Correct
4});
5
6// ❌ Bad: Use outer cx (multiple borrow error)
7entity.update(cx, |state, inner_cx| {
8    cx.notify(); // Wrong!
9});

Avoid Nested Updates

1// ✅ Good: Sequential updates
2entity1.update(cx, |state, cx| { /* ... */ });
3entity2.update(cx, |state, cx| { /* ... */ });
4
5// ❌ Bad: Nested updates (may panic)
6entity1.update(cx, |_, cx| {
7    entity2.update(cx, |_, cx| { /* ... */ });
8});

Common Use Cases

  1. Component State: Internal state that needs reactivity
  2. Shared State: State shared between multiple components
  3. Parent-Child: Coordinating between related components (use weak refs)
  4. Async State: Managing state that changes from async operations
  5. Observations: Reacting to changes in other entities

Reference Documentation

Complete API Documentation

  • Entity API: See api-reference.md
    • Entity types, methods, lifecycle
    • Context methods, async operations
    • Error handling, type conversions

Implementation Guides

  • Patterns: See patterns.md

    • Model-view separation, state management
    • Cross-entity communication, async operations
    • Observer pattern, event subscription
    • Pattern selection guide
  • Best Practices: See best-practices.md

    • Avoiding common pitfalls, memory leaks
    • Performance optimization, batching updates
    • Lifecycle management, cleanup
    • Async best practices, testing
  • Advanced Patterns: See advanced.md

    • Entity collections, registry pattern
    • Debounced/throttled updates, state machines
    • Entity snapshots, transactions, pools

What Users Are Saying

Real feedback from the community

Environment Matrix

Dependencies

GPUI framework
Rust compiler with async support

Framework Support

GPUI ✓ (required)

Context Window

Token Usage ~3K-8K tokens for typical entity patterns and implementations

Security & Privacy

Information

Author
longbridge
Updated
2026-01-30
Category
frontend