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.tslive
{ every: '20s ~ 4s' }
Use the habicron CLI skill to create a habit every 20s ~ 4s to remind me to drink water
Next 5 runsnow 00:00:00
  • At --:--:--
  • At --:--:--
  • At --:--:--
  • At --:--:--
  • At --:--:--

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

habicron · MIT · built by communityaccurate by default · jittered on demand