From 2f0b22443765d013351f0b344aa3aa8979790fce Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:55:40 +0000 Subject: [PATCH] docs: ban $bindable(default_value) on optional props in CLAUDE.md (#8267) Add a "Banned Patterns" section documenting that $bindable(default_value) on props that can be undefined is banned. The correct alternatives are using $derived(my_prop ?? default_value) or creating a useMyPropState() helper higher in the component tree. Closes #8266 Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: windmill-internal-app[bot] --- CLAUDE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 4e7afeba8a..0acc541c92 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,6 +26,27 @@ Open-source platform for internal tools, workflows, API integrations, background - **Login**: `admin@windmill.dev` / `changeme` - **Instance settings**: navigate to `/#superadmin-settings` +## Banned Patterns + +### `$bindable(default_value)` on optional props + +Using `$bindable(default_value)` on props that can be `undefined` is **banned**. This pattern causes subtle bugs because the default value masks the `undefined` state. + +**Bad:** +```svelte +let { my_prop = $bindable(default_value) }: { my_prop?: string } = $props() +``` + +**Correct alternatives:** + +1. **Use `$derived` with nullish coalescing** — handle the potential `undefined` at the usage site: + ```svelte + let { my_prop = $bindable() }: { my_prop?: string } = $props() + let effective_value = $derived(my_prop ?? default_value) + ``` + +2. **Create a `useMyPropState()` helper** — encapsulate the undefined-handling logic in a reusable function and call it higher in the component tree, so the child component always receives a defined value. + ## Core Principles - Search for existing code to reuse before writing new code