Tauri desktop note-taking app (apps/desktop/) with a web app (apps/web/).
Uses pnpm workspaces.
TinyBase as the primary data store (schema at packages/store/src/tinybase.ts), Zustand for UI state, TipTap for the editor. Sessions are the core entity — all notes are backed by sessions.
- Format:
pnpm exec dprint fmt - Typecheck (TS):
pnpm -r typecheck - Typecheck (Rust):
cargo check - Desktop dev:
pnpm -F @hypr/desktop tauri:dev - Web dev:
pnpm -F @hypr/web dev - Dev docs: https://char.com/docs/developers
- Format via dprint after making changes.
- JavaScript/TypeScript formatting runs through
oxfmtvia dprint's exec plugin. - Run
pnpm -r typecheckafter TypeScript changes,cargo checkafter Rust changes. - After editing files, run the relevant verification commands before finishing.
- For
apps/desktop/TypeScript changes, preferpnpm -F desktop typecheckto match CI. - After edits, run
pnpm exec dprint fmt. - Use
useForm(tanstack-form) anduseQuery/useMutation(tanstack-query) for form/mutation state. Avoid manual state management (e.g.setError). - For
plugins/dblive queries, keep schema creation, migrations, and DB initialization on the Rust side; TypeScript should only consumeexecute/subscribeAPIs. - Branch naming:
fix/,chore/,refactor/prefixes.
- Avoid creating types/interfaces unless shared. Inline function props.
- Do not write comments unless code is non-obvious. Comments should explain "why", not "what".
- Use
cnfrom@hypr/utilsfor conditional classNames. Always pass an array, split by logical grouping. - Use
motion/reactinstead offramer-motion.
Choose the lightest command structure that fits the workflow.
Use the full reducer/effect/runtime split only when the command has async orchestration, a multi-step workflow, or substantial state transitions that benefit from reducer-style tests.
commands/<name>/
mod.rs -- Screen impl, Args, run() [glue]
app.rs -- App or screen-local state [optional]
action.rs -- Action enum [optional]
effect.rs -- Effect enum [optional]
runtime.rs -- Runtime, RuntimeEvent [async I/O]
ui.rs -- draw(frame, app) [rendering]
Naming rules:
- Types drop the command prefix:
App,Action,Effect,Runtime,RuntimeEvent app.rs→app/mod.rswith private submodules when state is complexui.rs→ui/mod.rswith sub-files when rendering is complexaction.rs/effect.rsare siblings ofmod.rswhen they exist; do not create them by default for simple list/detail screensapp.rscontains no rendering logic, no API calls, no async code when using the reducer pattern- Prefer
screen.rsplus a small local state struct for simple browse/select flows - Do not add parent-level action/effect translation layers that proxy child workflows through another command's reducer
- Do not create summary docs or example code files unless requested.