Skip to content
Notion Arena
HomeComponentsTrackersHabit OS (native)
✅
🔥 TrackersProNative recipeNew

Habit OS (native)

Habits as database rows with streak formulas and a dashboard view.

Version
v1.0.0
Updated
2026-09-20
Plan
Plus

The install plan

Exactly what Notion Arena sends to Notion, in order. Notion's data-source model forces two passes: relations, rollups and the formulas that read them need data_source_ids that only exist once the databases do.

18
requests
11
manual steps
1POST
/v1/pages

Create the “habit-os-native” container page under the page you chose

2POST
/v1/databases

Create the “Habits” database with 8 base properties

3GET
/v1/databases/{habits_database_id}

Read back Habits to get its default data source id

4PATCH
/v1/data_sources/{habits_data_source_id}

Add 6 deferred properties to Habits: relations (with resolved data_source_ids), then the rollups and formulas that read them

5POST
/v1/databases

Create the “Daily Logs” database with 6 base properties

6GET
/v1/databases/{logs_database_id}

Read back Daily Logs to get its default data source id

7PATCH
/v1/data_sources/{logs_data_source_id}

Add 4 deferred properties to Daily Logs: relations (with resolved data_source_ids), then the rollups and formulas that read them

8POST
/v1/views

Create the “Habit dashboard” dashboard view (layout is read-only; widgets are added as further views with view_id)

9POST
/v1/views

Create the “Active habits” gallery view on habits

10POST
/v1/views

Create the “Completion by habit” chart view on habits

11POST
/v1/views

Create the “Calendar” calendar view on logs

12POST
/v1/views

Create the “Today” table view on logs

13POST
/v1/views

Create the “Logs per week” chart view on logs

14POST
/v1/pages

Seed 3 rows into Habits so the views are not empty on first open (one request per row; Notion has no bulk insert)

×3
15POST
/v1/pages

Create the “Habit OS” page

16PATCH
/v1/blocks/{habit_os_page_id}/children

Append 11 blocks of page body

“Habit dashboard” is created empty. Dashboard configuration is read-only in the API: each widget is its own POST /v1/views with view_id set to the dashboard. See the manual steps.

3 steps cannot be scripted: Button: “Log today”; Recurring template: daily log seeder; Widget views on the habit dashboard.

Run it yourselfNotion-Version 2026-03-11
curl -X POST https://notionarena.vercel.app/api/install \
  -H 'content-type: application/json' \
  -d '{
    "component": "habit-os-native",
    "mode": "plan"
  }'

# add "token" and "parentPageId" and switch to "mode": "api" to install for real

What gets created

The real property schemas, not a description of them. Every formula below is a Notion Formula 2.0 expression you can paste into a property by hand if you would rather not use the API at all.

🔁

Habits

ref: habits
1× title1× checkbox1× select2× number2× rich_text1× date1× relation3× rollup2× formula
Namen/a
Activen/a
FrequencyDaily · Weekdays · 3× per week · Weekly
Times per weeknumber
Emojin/a
Whyn/a
Startedn/a
Logs→ logs (two-way)
Logs this monthcount(Recent logs.Completed)
Completed countchecked(Logs.Completed)
Total logscount_values(Logs.Name)
All-time rateif(prop("Total logs") == 0, 0, round(prop("Completed count") / prop("Total logs") * 100))
Best streaknumber
Statusifs(not(prop("Active")), "⏸ Paused", prop("All-time rate") >= 80, "🔥 Strong", prop("All-time rate") >= 50, "🌱 Building", true, "🧊 Fragile")
🗓️

Daily Logs

ref: logs
1× title1× date1× relation1× checkbox1× number1× rich_text3× formula1× created_time
Namen/a
Daten/a
Habit→ habits
Completedn/a
Reps / amountnumber
Noten/a
WeekdayformatDate(prop("Date"), "ddd")
Is todaydateBetween(prop("Date"), now(), "days") == 0
Week numberformatDate(prop("Date"), "wo")
Createdn/a

Views

Created through POST /v1/views, which shipped in March 2026 and is the reason provisioning a workspace from code finally works end to end.

Habit dashboarddashboard

on habits

Active habitsgallery

on habits

filter: {"property":"Active","checkbox":{"equals":true}}…

Completion by habitchart

on habits

Calendarcalendar

on logs

filter: {"property":"Completed","checkbox":{"equals":true}}…

Todaytable

on logs

filter: {"property":"Is today","checkbox":{"equals":true}}…

Logs per weekchart

on logs

Documentation pages

Appended with real block types (headings, toggles, callouts, to-dos, column lists) in chunks of 100, the Append block children limit.

🔥Habit OS11 blocks
🔥Why a database instead of a widget? 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.
The loop
1.Press “Log today” once. It creates one Daily Log row per active habit, dated today.
1.Tick Completed on the rows you did. Leave the rest unchecked: an unchecked row is data, not failure.
1.On Sunday, look at the Completion by habit chart. Anything under 50% for three weeks gets its frequency reduced, not its willpower increased.

The formulas
All-time rate
round(prop("Completed count") / prop("Total logs") * 100)
Weekday, for pattern spotting
formatDate(prop("Date"), "ddd")
Is today, for the Today view
dateBetween(prop("Date"), now(), "days") == 0
⚠️A true current-streak formula needs a self-referencing lookup across dated rows, which Notion formulas cannot express. That is an honest limitation, not a missing feature, which is why the weekly chart does the motivating instead.

The parts the API cannot do

Every recipe ships with its manual steps written out, because pretending the API covers everything is how people end up with a half-built workspace. These are real Notion limitations, quoted from the API reference.

Button: “Log today”

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.

  1. 1On the Habit OS page: /button.
  2. 2Action: 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.
  3. 3Each action sets Date = Today, Habit = the matching habit, Completed = unchecked.
  4. 4For more than about six habits, use the recurring template below instead.

Recurring template: daily log seeder

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.

  1. 1Daily Logs → ▾ beside New → + New template → “Daily seed”.
  2. 2Set Date to Today as a default.
  3. 3Template ••• → Repeat → Every day at 06:00.
  4. 4This creates one row per day; pair it with a Habit select you set by hand, or create one template per habit each repeating daily.

Widget views on the habit dashboard

Dashboard configuration is read-only. Create the dashboard, then add each widget as its own view with view_id pointing at it.

  1. 1POST /v1/views with type: "dashboard" and the Habits database's database_id.
  2. 2POST /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).
  3. 3Maximum 12 widgets, 4 per row.

About this component

The data-backed counterpart to the Habit Heatmap widget. A Habits database and a Logs database, with formulas that compute current streak, longest streak and 30-day completion rate directly from your rows, so it syncs across devices and teammates, unlike any widget.

What it does

  • Streaks computed in Notion, so they follow you to every device
  • Dashboard view with up to 12 widgets across 4 rows
  • Chart view: completions per habit per week
  • Target frequency per habit: daily habits and 3×/week habits coexist

Where people put it

↳People who want habit data they can roll up into a life review
↳Coaches tracking client habits in a shared workspace
↳Teams running a shared ritual, like a reading club

Pairs well with

All in Trackers
🔥
Popular

Habit Heatmap Grid

GitHub-style contribution grid for up to six habits, with streaks.

TrackersFreeWidgetv1.4.1
💧
New

Water Intake Tracker

A one-tap daily drink counter with a goal ring and undo.

TrackersFreeWidgetv1.0.0
🌤️
New

Mood & Energy Tracker

Log how you feel in one tap and see the month as a calendar heatmap.

TrackersProWidgetv1.0.0