-
-
Notifications
You must be signed in to change notification settings - Fork 2
Contributing a Desktop Feature
itsmylab edited this page Aug 4, 2026
·
1 revision
Generated from
docs/contributions/desktop-feature.md. Edit the canonical source through a pull request.
Use this playbook for a desktop workflow that primarily composes existing data and capabilities. If it requires a new native operation, also follow Native Capability. If it needs a new project tab or panel, also follow Project Surface.
flowchart TD
Feature[Feature requirement]
Scope{State lifetime?}
Local[Component state]
Project[ProjectView-owned state]
App[App-owned state]
Durable[Rust durable store]
Domain[Framework-free domain module]
UI[Feature component]
Feature --> Scope
Scope -- local --> Local
Scope -- one project --> Project
Scope -- all projects --> App
Scope -- survives app --> Durable
Local --> Domain
Project --> Domain
App --> Domain
Durable --> Domain
Domain --> UI
Typical desktop feature:
src/<feature>.ts pure rules and state projection
src/<feature>.test.ts behavior tests
src/components/<Feature>.tsx presentation
src/components/<Feature>.test.tsx interaction tests, when needed
src/components/ProjectView/index.tsx composition only, when project-scoped
src/App.tsx composition only, when app-scoped
- Write the user-visible behavior as a failing test.
- Identify the real state owner: component, project, app, or Rust store.
- Search for an existing module, store, channel, tab, and event path before creating one.
- Put reusable rules in
src/<feature>.ts, not inApp.tsxor the largeProjectViewcomponent. - Build the component from shared buttons, dialogs, menus, icons, and tokens.
- Wire it into the owning composition root with the smallest possible change.
- Add a shortcut, SpotSearch row, deep link, or notification only if the user needs that entry path.
- Preserve mounted state for long-lived surfaces.
- Test cleanup, empty states, errors, and focus behavior.
flowchart LR
Child[Parent and child] --> Props[Props and callbacks]
Consumers[Several consumers] --> Channel[createChannel]
Native[Rust state] --> Tauri[Tauri wrapper/event]
Stored[Durable store] --> Change[store:change invalidation]
Routed[App to one project] --> Event[Targeted canopy:* event]
Use the narrowest bus. A desktop feature should not introduce a global event by default.
npm run test -- src/<feature>.test.ts
npm run typecheck
npm run lint- State owner identified.
- Pure behavior extracted and tested.
- Existing store, channel, or registry reused.
- Composition roots contain wiring, not feature policy.
- Shared components and semantic tokens used.
- Long-lived surface and cleanup behavior preserved.
- Optional entry points are justified.
Generated from FluidWorksApp/canopy-ide. Canonical documentation changes belong in the main repository.
Canopy Architecture
- Home
- Architecture
- Core Rust System
- LLM Context
- Integration Guide
- Contribution Playbooks
- Testing and Coverage
- Publish the Wiki
Playbooks