This document provides detailed information for developers who want to contribute to or understand the NoteDeck Columns codebase.
The NoteDeck Columns codebase is organized as follows:
notedeck_columns
├── src
│ ├── ui # UI components and views
│ │ ├── note # Note-related UI components (posts, replies, quotes)
│ │ ├── column # Column UI components
│ │ ├── search # Search functionality
│ │ ├── profile # Profile views and editing
│ │ └── ...
│ ├── timeline # Timeline data structures and logic
│ ├── storage # Persistence mechanisms
│ ├── accounts # Account management
│ ├── decks # Deck management
│ ├── app.rs # Main application logic
│ ├── app_creation.rs # Application initialization
│ ├── route.rs # Routing system
│ ├── nav.rs # Navigation logic
│ └── ...
- Rust toolchain (latest stable recommended)
- nostrdb and its dependencies
- egui and eframe
-
Clone the repository:
git clone https://github.com/damus-io/notedeck cd notedeck -
Build the project:
cargo build --release
-
Run the application:
cargo run --release
For development, you might want to run with debug symbols:
cargo run- Deck: A collection of columns that a user can switch between
- Column: A view into a specific type of Nostr content (timeline, profile, etc.)
Timelines are a fundamental concept in NoteDeck Columns:
Timeline: Represents a stream of notes with filters and subscriptionsTimelineKind: Defines the type of timeline (Universe, Profile, Notifications, etc.)TimelineTab: Filtered views of a timeline (e.g., Notes only vs. Notes & Replies)TimelineCache: Caches timeline data for efficient access
Route: Represents application navigation targetsRouter: Manages the navigation stack for each columnNavTitle: Renders the title bar for navigationRenderNavAction: Actions resulting from navigation events
The UI is built with egui and organized into components:
PostView,PostReplyView,QuoteRepostView: Note creation UINoteView: Displays Nostr notesProfileView: Displays and edits profilesTimelineView: Renders timelines in columnsDesktopSidePanel: Side navigation panel
NoteDeck Columns manages Nostr subscriptions and relay connections to provide realtime updates:
MultiSubscriber: Handles subscriptions to multiple relaysSubscriptions: Tracks application-wide subscriptionsOutboxPool: Manages relay connections and remote subscriptions
- User actions create routes or trigger navigation
- Routes are mapped to timeline kinds or other UI views
- Timelines query nostrdb for notes matching their filters
- UI components render the note data
- Subscriptions keep the data updated in realtime
State is managed at different levels:
Damus: Contains global application stateDecksCache: Holds deck and column configurationsTimelineCache: Caches timeline data- Various component-specific state structures
Run the test suite:
cargo testThe codebase includes unit tests for critical components.
- Add a new variant to
TimelineKindenum intimeline/kind.rs - Implement the necessary filter logic
- Update the serialization and parsing methods
- Add UI support in the AddColumn view
- Create a new Rust file in the appropriate ui directory
- Implement the component using egui
- Connect it to the routing system if needed
When implementing new features:
- Start by understanding the relevant parts of the codebase
- Look for similar implementations as reference
- Follow the existing patterns for state management and UI components
- Add appropriate tests
- Update documentation
- Render Issues: Check the egui-related code for layout problems
- Data Freshness: Verify subscription and filter setup
- Performance: Look for inefficient queries or rendering
- Use
tracingmacros (debug!,info!,error!) for logging - Run with
RUST_LOG=debugfor verbose output - Use
cargo expandto inspect macro expansion
egui was chosen for its immediate mode rendering approach and Rust integration, making it well-suited for a responsive multi-column UI.
nostrdb provides high-performance local storage and querying for Nostr events, which is essential for a responsive client.
The codebase is structured around timelines because they provide a natural abstraction for the different types of Nostr content views needed in a column-based interface.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Run tests:
cargo test - Submit a pull request
Please follow the existing code style and patterns.