{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"habit-os-native","type":"registry:block","title":"Habit OS (native)","description":"Habits as database rows with streak formulas and a dashboard view.","author":"Notion Arena","categories":["trackers"],"tags":["native","pro","habit","streak","database","formula","dashboard"],"meta":{"kind":"native","tier":"pro","version":"1.0.0","updatedAt":"2026-09-20","notionPlan":"Plus","emoji":"✅","delivery":["api","duplicate","guide"],"capabilities":{"interactive":false,"offlineSafe":true,"persistsLocally":false,"writesToNotion":true,"needsNetwork":false},"recipe":"habit-os-native","installUrl":"https://notionarena.vercel.app/api/install"},"files":[{"path":"recipes/habit-os-native.json","type":"registry:file","target":"notion/recipes/habit-os-native.json","content":"{\n  \"$schema\": \"https://notionarena.vercel.app/r/schema.json\",\n  \"notionVersion\": \"2026-03-11\",\n  \"id\": \"habit-os-native\",\n  \"summary\": \"Habits and Daily Logs with streak and completion-rate formulas computed from your rows, so the data follows you across devices.\",\n  \"databases\": [\n    {\n      \"ref\": \"habits\",\n      \"title\": \"Habits\",\n      \"icon\": \"🔁\",\n      \"properties\": {\n        \"Name\": {\n          \"title\": {}\n        },\n        \"Active\": {\n          \"checkbox\": {}\n        },\n        \"Frequency\": {\n          \"select\": {\n            \"options\": [\n              {\n                \"name\": \"Daily\",\n                \"color\": \"green\"\n              },\n              {\n                \"name\": \"Weekdays\",\n                \"color\": \"blue\"\n              },\n              {\n                \"name\": \"3× per week\",\n                \"color\": \"yellow\"\n              },\n              {\n                \"name\": \"Weekly\",\n                \"color\": \"purple\"\n              }\n            ]\n          }\n        },\n        \"Times per week\": {\n          \"number\": {\n            \"format\": \"number\"\n          },\n          \"description\": \"Used by the rate formula. Daily = 7, 3× = 3.\"\n        },\n        \"Emoji\": {\n          \"rich_text\": {}\n        },\n        \"Why\": {\n          \"rich_text\": {},\n          \"description\": \"The reason survives the days when motivation does not.\"\n        },\n        \"Started\": {\n          \"date\": {}\n        },\n        \"Logs\": {\n          \"relation\": {\n            \"type\": \"dual_property\",\n            \"dual_property\": {\n              \"synced_property_name\": \"Habit\"\n            }\n          },\n          \"__relationRef\": \"logs\"\n        },\n        \"Logs this month\": {\n          \"rollup\": {\n            \"relation_property_name\": \"Recent logs\",\n            \"rollup_property_name\": \"Completed\",\n            \"function\": \"count\"\n          }\n        },\n        \"Completed count\": {\n          \"rollup\": {\n            \"relation_property_name\": \"Logs\",\n            \"rollup_property_name\": \"Completed\",\n            \"function\": \"checked\"\n          }\n        },\n        \"Total logs\": {\n          \"rollup\": {\n            \"relation_property_name\": \"Logs\",\n            \"rollup_property_name\": \"Name\",\n            \"function\": \"count_values\"\n          }\n        },\n        \"All-time rate\": {\n          \"formula\": {\n            \"expression\": \"if(prop(\\\"Total logs\\\") == 0, 0, round(prop(\\\"Completed count\\\") / prop(\\\"Total logs\\\") * 100))\"\n          }\n        },\n        \"Best streak\": {\n          \"number\": {\n            \"format\": \"number\"\n          },\n          \"description\": \"Maintained by the streak formula on Logs, or by hand weekly.\"\n        },\n        \"Status\": {\n          \"formula\": {\n            \"expression\": \"ifs(not(prop(\\\"Active\\\")), \\\"⏸ Paused\\\", prop(\\\"All-time rate\\\") >= 80, \\\"🔥 Strong\\\", prop(\\\"All-time rate\\\") >= 50, \\\"🌱 Building\\\", true, \\\"🧊 Fragile\\\")\"\n          }\n        }\n      },\n      \"seed\": [\n        {\n          \"name\": \"Read 20 pages\",\n          \"props\": {\n            \"Active\": true,\n            \"Frequency\": \"Daily\",\n            \"Times per week\": 7,\n            \"Emoji\": \"📖\"\n          }\n        },\n        {\n          \"name\": \"Strength training\",\n          \"props\": {\n            \"Active\": true,\n            \"Frequency\": \"3× per week\",\n            \"Times per week\": 3,\n            \"Emoji\": \"🏋️\"\n          }\n        },\n        {\n          \"name\": \"No screens after 22:00\",\n          \"props\": {\n            \"Active\": true,\n            \"Frequency\": \"Daily\",\n            \"Times per week\": 7,\n            \"Emoji\": \"🌙\"\n          }\n        }\n      ]\n    },\n    {\n      \"ref\": \"logs\",\n      \"title\": \"Daily Logs\",\n      \"icon\": \"🗓️\",\n      \"properties\": {\n        \"Name\": {\n          \"title\": {}\n        },\n        \"Date\": {\n          \"date\": {}\n        },\n        \"Habit\": {\n          \"relation\": {\n            \"type\": \"single_property\",\n            \"single_property\": {}\n          },\n          \"__relationRef\": \"habits\"\n        },\n        \"Completed\": {\n          \"checkbox\": {}\n        },\n        \"Reps / amount\": {\n          \"number\": {\n            \"format\": \"number\"\n          }\n        },\n        \"Note\": {\n          \"rich_text\": {}\n        },\n        \"Weekday\": {\n          \"formula\": {\n            \"expression\": \"formatDate(prop(\\\"Date\\\"), \\\"ddd\\\")\"\n          }\n        },\n        \"Is today\": {\n          \"formula\": {\n            \"expression\": \"dateBetween(prop(\\\"Date\\\"), now(), \\\"days\\\") == 0\"\n          }\n        },\n        \"Week number\": {\n          \"formula\": {\n            \"expression\": \"formatDate(prop(\\\"Date\\\"), \\\"wo\\\")\"\n          }\n        },\n        \"Created\": {\n          \"created_time\": {}\n        }\n      },\n      \"seed\": []\n    }\n  ],\n  \"views\": [\n    {\n      \"on\": \"habits\",\n      \"name\": \"Habit dashboard\",\n      \"type\": \"dashboard\"\n    },\n    {\n      \"on\": \"habits\",\n      \"name\": \"Active habits\",\n      \"type\": \"gallery\",\n      \"configuration\": {\n        \"type\": \"gallery\",\n        \"card_layout\": \"cover_dominant\"\n      },\n      \"filter\": {\n        \"property\": \"Active\",\n        \"checkbox\": {\n          \"equals\": true\n        }\n      }\n    },\n    {\n      \"on\": \"habits\",\n      \"name\": \"Completion by habit\",\n      \"type\": \"chart\",\n      \"configuration\": {\n        \"type\": \"chart\",\n        \"chart_type\": \"bar\",\n        \"x_axis\": {\n          \"type\": \"title\",\n          \"property_name\": \"Name\"\n        },\n        \"y_axis\": {\n          \"aggregator\": \"average\",\n          \"property_name\": \"All-time rate\"\n        },\n        \"color_theme\": \"green\",\n        \"color_by_value\": true,\n        \"show_data_labels\": true,\n        \"height\": \"medium\"\n      }\n    },\n    {\n      \"on\": \"logs\",\n      \"name\": \"Calendar\",\n      \"type\": \"calendar\",\n      \"configuration\": {\n        \"type\": \"calendar\",\n        \"calendar_by\": \"Date\"\n      },\n      \"filter\": {\n        \"property\": \"Completed\",\n        \"checkbox\": {\n          \"equals\": true\n        }\n      }\n    },\n    {\n      \"on\": \"logs\",\n      \"name\": \"Today\",\n      \"type\": \"table\",\n      \"filter\": {\n        \"property\": \"Is today\",\n        \"checkbox\": {\n          \"equals\": true\n        }\n      }\n    },\n    {\n      \"on\": \"logs\",\n      \"name\": \"Logs per week\",\n      \"type\": \"chart\",\n      \"configuration\": {\n        \"type\": \"chart\",\n        \"chart_type\": \"line\",\n        \"x_axis\": {\n          \"type\": \"date\",\n          \"property_name\": \"Date\",\n          \"date_grouping\": \"week\"\n        },\n        \"y_axis\": {\n          \"aggregator\": \"count\"\n        },\n        \"color_theme\": \"blue\",\n        \"height\": \"medium\"\n      }\n    }\n  ],\n  \"pages\": [\n    {\n      \"title\": \"Habit OS\",\n      \"icon\": \"🔥\",\n      \"blocks\": [\n        {\n          \"object\": \"block\",\n          \"type\": \"callout\",\n          \"callout\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"Why a database instead of a widget? \",\n                  \"link\": null\n                },\n                \"annotations\": {\n                  \"bold\": true\n                }\n              },\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"A widget's streak lives in one browser's localStorage. These formulas live in your workspace: they follow you to your phone, they are visible to a coach, and you can roll them up into a quarterly life review.\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"icon\": {\n              \"type\": \"emoji\",\n              \"emoji\": \"🔥\"\n            },\n            \"color\": \"green_background\"\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"heading_2\",\n          \"heading_2\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"The loop\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\",\n            \"is_toggleable\": false\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"numbered_list_item\",\n          \"numbered_list_item\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"Press “Log today” once. It creates one Daily Log row per active habit, dated today.\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"numbered_list_item\",\n          \"numbered_list_item\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"Tick Completed on the rows you did. Leave the rest unchecked: an unchecked row is data, not failure.\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"numbered_list_item\",\n          \"numbered_list_item\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"On Sunday, look at the Completion by habit chart. Anything under 50% for three weeks gets its frequency reduced, not its willpower increased.\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"divider\",\n          \"divider\": {}\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"heading_2\",\n          \"heading_2\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"The formulas\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\",\n            \"is_toggleable\": false\n          }\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"toggle\",\n          \"toggle\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"All-time rate\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          },\n          \"children\": [\n            {\n              \"object\": \"block\",\n              \"type\": \"code\",\n              \"code\": {\n                \"rich_text\": [\n                  {\n                    \"type\": \"text\",\n                    \"text\": {\n                      \"content\": \"round(prop(\\\"Completed count\\\") / prop(\\\"Total logs\\\") * 100)\",\n                      \"link\": null\n                    }\n                  }\n                ],\n                \"language\": \"typescript\",\n                \"caption\": []\n              }\n            }\n          ]\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"toggle\",\n          \"toggle\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"Weekday, for pattern spotting\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          },\n          \"children\": [\n            {\n              \"object\": \"block\",\n              \"type\": \"code\",\n              \"code\": {\n                \"rich_text\": [\n                  {\n                    \"type\": \"text\",\n                    \"text\": {\n                      \"content\": \"formatDate(prop(\\\"Date\\\"), \\\"ddd\\\")\",\n                      \"link\": null\n                    }\n                  }\n                ],\n                \"language\": \"typescript\",\n                \"caption\": []\n              }\n            }\n          ]\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"toggle\",\n          \"toggle\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"Is today, for the Today view\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"color\": \"default\"\n          },\n          \"children\": [\n            {\n              \"object\": \"block\",\n              \"type\": \"code\",\n              \"code\": {\n                \"rich_text\": [\n                  {\n                    \"type\": \"text\",\n                    \"text\": {\n                      \"content\": \"dateBetween(prop(\\\"Date\\\"), now(), \\\"days\\\") == 0\",\n                      \"link\": null\n                    }\n                  }\n                ],\n                \"language\": \"typescript\",\n                \"caption\": []\n              }\n            }\n          ]\n        },\n        {\n          \"object\": \"block\",\n          \"type\": \"callout\",\n          \"callout\": {\n            \"rich_text\": [\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"A true current-streak formula needs a self-referencing lookup across dated rows, which Notion formulas cannot express. \",\n                  \"link\": null\n                },\n                \"annotations\": {\n                  \"bold\": true\n                }\n              },\n              {\n                \"type\": \"text\",\n                \"text\": {\n                  \"content\": \"That is an honest limitation, not a missing feature, which is why the weekly chart does the motivating instead.\",\n                  \"link\": null\n                }\n              }\n            ],\n            \"icon\": {\n              \"type\": \"emoji\",\n              \"emoji\": \"⚠️\"\n            },\n            \"color\": \"yellow_background\"\n          }\n        }\n      ]\n    }\n  ]\n}"},{"path":"recipes/habit-os-native.manual.md","type":"registry:file","target":"notion/recipes/habit-os-native.manual.md","content":"## Button: “Log today”\n\n**Why this cannot be scripted:** Button properties are response-only in the Notion API: the schema is returned on read, but the API ignores button settings on write and cannot create a button or configure its actions.\n\n1. On the Habit OS page: /button.\n2. Action: Add page to → Daily Logs, once per active habit. Notion buttons cannot loop over related rows, so add one action per habit and delete the action when you pause a habit.\n3. Each action sets Date = Today, Habit = the matching habit, Completed = unchecked.\n4. For more than about six habits, use the recurring template below instead.\n\n## Recurring template: daily log seeder\n\n**Why this cannot be scripted:** Recurring database templates (daily/weekly/monthly) are configured in the app on the template's ••• menu; the API can create pages from a template but cannot schedule recurrence.\n\n1. Daily Logs → ▾ beside New → + New template → “Daily seed”.\n2. Set Date to Today as a default.\n3. Template ••• → Repeat → Every day at 06:00.\n4. This creates one row per day; pair it with a Habit select you set by hand, or create one template per habit each repeating daily.\n\n## Widget views on the habit dashboard\n\n**Why this cannot be scripted:** Dashboard configuration is read-only. Create the dashboard, then add each widget as its own view with view_id pointing at it.\n\n1. POST /v1/views with type: \"dashboard\" and the Habits database's database_id.\n2. POST /v1/views with view_id = that dashboard for each widget: a Number widget (average All-time rate), a Bar chart (completion by habit), a Calendar (completed logs).\n3. Maximum 12 widgets, 4 per row.\n"}]}