by community

Habits,
not cronjobs.

Human-like scheduler for AI Agents and applications — works for your AI Agents, or your applications in Node, Vue, or React.

Node · Browser · Vue · React · CLI · tiny, zero‑dependency core
accurate by default, jittered on demand · no drift · SSR‑safe
remind-me-to-drink-water.ts live
{ every: '20s ~ 4s' }
Next 5 runs now 00:00:00

    Install

    Add it to your project

    $npm i habicron
    Add the agent skills (Claude · OpenClaw)
    $npx skills add imrim12/habicron

    Then import from habicron, habicron/browser, habicron/vue, habicron/react — or schedule shell commands with the habit CLI.

    habits.ts
    import { useHabit } from 'habicron/vue'
    
    // remind me to drink water every hour
    useHabit(drinkWater, { every: '1h ~ 8m' })
    
    // check my cat every 2 hours
    useHabit(checkCat, { every: '2h ~ 20m' })
    
    // a whole routine, with controls
    const { nextRun, pause } = useHabit(routine, {
      controls: true,
      habits: [
        { every: '20s', jitter: ['3s', '5s'] },
        { times: 2, per: 'day', jitter: '2h' },
      ],
    })

    Use cases

    Give your software a daily rhythm

    AI agents
    • Review and improve your memory every 2h
    • Re-read the project goals every 30m ~ 5m
    • Summarize what changed in the repo 2× / day
    • Touch base with the user every 90m, jittered
    Smart CLI tools
    • Scout a shopping site for sales every 1h
    • Pull the repo and rebuild 3× / day
    • Back up to object storage every 6h ~ 30m
    • Run the test suite while you focus every 45m
    Web apps
    • Check my cat from the camera every 5m
    • Refresh the live dashboard every 20s ~ 4s
    • Autosave the draft roughly every 1m
    • Nudge "drink water" every 1h ~ 8m
    Servers & workers
    • Poll a webhook source every 90s, jittered
    • Warm the cache 4× / day
    • Reconcile with the upstream API every 15m ~ 2m
    • Sweep stale sessions every 1h

    Examples

    Five ways to use it

    node
    import { createHabit } from 'habicron'
    
    // poll a feed, roughly every 15 min
    const job = createHabit(syncFeed, {
      every: '15m ~ 2m',
    })
    browser
    import { useHabit } from 'habicron/browser'
    
    // no framework — react via callbacks
    useHabit(refreshWidget, {
      every: '20s ~ 4s',
      onFire: n => badge.textContent = n,
    })
    react
    import { useHabit } from 'habicron/react'
    
    useHabit(runAgent, {
      controls: true,
      habits: [
        { every: '2h ~ 20m' },        // check the cat
        { times: 2, per: 'day', jitter: '90m' },
      ],
    })
    vue
    <script setup lang="ts">
    const { counter, pause } = useHabit(post, {
      controls: true, every: '20s ~ 4s',
    })
    </script>
    
    <template> fired {{ counter }}× </template>
    cli — manage habits from your shell
    # start commands in the background, jittered so you don't look like a bot
    $ habit start --name stretch --every "10m ~ 2m" -- notify-send "Stretch"
    $ habit start --every 1h --jitter 12m -- node scrape.js
    
    # list what's running — and what each one runs
    $ habit list
      id  name     status   schedule    command           runs  next
      1   stretch  running  every 10m~2m notify-send …     4     in 8m
      2   scrape   running  every 1h~12m node scrape.js    1     in 47m
    
    $ habit logs stretch   # stop · restart · update · delete · kill