💧 HydraDev
Developer Hydration Companion
A friendly reminder to drink water, delivered by a small animated avatar.

Features
- A companion, not a notification. Every reminder is delivered by a small
animated avatar that walks onto your screen and asks "Did you drink water?"
- Real answers. Reply Yes or Not yet — the avatar reacts, and HydraDev
adapts: say "not yet" and it asks again shortly.
- Never nags. A configurable retry limit means HydraDev gives up gracefully and
returns to its normal schedule instead of pestering you.
- Snooze and quiet hours. Push a reminder back, or silence everything overnight.
- Five avatars. A developer robot, a developer, a cat, a dog and a penguin.
- Multi-monitor, cross-platform. Windows 10+, macOS 12+ and modern Linux. The
avatar always appears inside the display's work area, so it never hides under
the Dock, the taskbar or a Linux panel.
- Accessible. Full keyboard support, screen-reader labels, high-contrast and
prefers-reduced-motion support.
- Private and lightweight. No telemetry, no server, no account. Roughly
0 % CPU while idle — HydraDev only does work when a reminder is actually due.
How It Works
START
│
├─ wait for the interval (default 2 hours)
│
├─ the avatar walks onto the screen
│
└─ "Did you drink water?"
│
├─ YES ──▶ celebrates ──▶ walks away ──▶ timer resets
│
├─ NO ──▶ looks sad ──▶ asks again in 1 minute ──┐
│ ▲ │
│ └─────────────────────────────────────┘
│ (until Yes, or the retry limit)
│
└─ SNOOZE ──▶ back in 10 min / 30 min / 1 h / 2 h
Sleeping on the laptop does not produce a backlog of missed reminders. HydraDev
recalculates the schedule when your machine wakes and shows at most one
reminder.
HydraDev is a reminder tool. It cannot measure how much water you actually
drank. The statistics describe how often you answered the reminder.
Screenshots
The companion shows one of two things depending on your machine:
| Floating desktop companion |
In-editor companion |
| Frameless, transparent, always-on-top window that floats over your desktop. Clicks outside the avatar pass straight through to the app underneath, and the window never steals keyboard focus while you type. |
Rendered inside VS Code using the same component. This is the mode used by Marketplace installs, and it is the better choice for keyboard-only and screen-reader users. |
Configuration
All settings live under hydraDev.*.
| Setting |
Default |
Description |
hydraDev.enabled |
true |
Master switch. |
hydraDev.reminderInterval |
120 |
Minutes between reminders. Presets: 30, 60, 90, 120, 180, 240 — or any value from 1 to 720. |
hydraDev.retryInterval |
1 |
Minutes before asking again after "Not yet". Presets: 1, 2, 3, 5, 10. |
hydraDev.maxRetries |
5 |
How many times to re-ask. Presets: 1, 3, 5, 10, or 0 for unlimited. |
hydraDev.avatar |
robot |
robot, developer, cat, dog or penguin. |
hydraDev.position |
bottom-right |
Which corner the avatar walks in from. |
hydraDev.monitor |
primary |
primary, active (the display under your cursor) or index. |
hydraDev.monitorIndex |
0 |
Zero-based display index, used when monitor is index. |
hydraDev.soundEnabled |
true |
Short, subtle cues. OS volume and mute are always respected. |
hydraDev.notificationsEnabled |
true |
Also show a VS Code notification. The avatar is the primary notification. |
hydraDev.animationEnabled |
true |
Walk-in/walk-out movement and avatar animations. |
hydraDev.reducedMotion |
false |
Force reduced motion. Your OS prefers-reduced-motion setting is honoured even when this is off. |
hydraDev.theme |
system |
system, light or dark. |
hydraDev.companionMode |
auto |
auto, floating or webview. See Companion modes. |
hydraDev.showStatusBar |
true |
Show the 💧 HydraDev status bar item. |
hydraDev.quietHours.enabled |
false |
Pause everything during a time window. |
hydraDev.quietHours.start |
"22:00" |
24-hour HH:MM, local time. |
hydraDev.quietHours.end |
"07:00" |
24-hour HH:MM. The window may wrap past midnight. |
hydraDev.showWelcomeOnInstall |
true |
Show the welcome panel on first activation. |
hydraDev.logLevel |
info |
error, warn, info or debug. |
Commands
| Command |
What it does |
HydraDev: Enable |
Turns reminders on. |
HydraDev: Disable |
Pauses reminders. |
HydraDev: Test Reminder |
Shows the companion once, without touching your statistics or schedule. |
HydraDev: Remind Me Now |
Shows a real reminder and records it. |
HydraDev: Reset Timer |
Restarts the interval from now. |
HydraDev: Open Settings |
Opens the HydraDev settings. |
HydraDev: Show Statistics |
Opens the statistics panel. |
HydraDev: Change Avatar |
Picks a different companion. |
Clicking the 💧 HydraDev status bar item opens a quick menu with the most common
actions and a live countdown.
Avatars
| Avatar |
Description |
| 🤖 Developer Robot |
A friendly little helper with a glowing visor. The default. |
| 🧑💻 The Developer |
An original full-body cartoon boy in a teal hoodie, carrying a water bottle. |
| 🐈 Hydration Cat |
Mostly asleep. Still counting your water breaks. |
| 🐕 Water Dog |
Excited about every single reminder. |
| 🐧 Penguin |
Formal. Hydrated. Extremely serious about the ocean. |
Each avatar has artwork for every state — idle, walking, question, happy,
sad, celebrating and sleeping — and all of it is generated procedurally
from scripts/generate-assets.mjs, so the repository contains no opaque blobs.
The Developer sprite is original vector artwork, not a copied stock image.
Companion modes
hydraDev.companionMode controls where the avatar appears:
auto (default) — use the floating desktop companion when an Electron
runtime is available, otherwise fall back to the in-editor companion.
floating — prefer the floating window; still falls back rather than failing.
webview — always use the in-editor companion.
In floating mode, the transparent companion window travels from the opposite
edge of the selected display to its configured corner while the avatar walks.
In webview mode, movement is confined to the VS Code panel.
Why the Marketplace build uses the in-editor companion. A true desktop
overlay needs an embedded runtime. Bundling Electron would add roughly 250 MB to
the VSIX, which is unacceptable for a reminder tool. The floating companion is
therefore enabled when you run HydraDev from a source checkout (npm install
provides the runtime) or when you point HYDRADEV_ELECTRON_PATH at an existing
Electron binary. In every case the companion itself — the same HTML, CSS,
JavaScript, animations, themes and accessibility features — is identical; only
the host window differs.
Privacy
HydraDev is built to be boring about your data.
HydraDev never collects, reads, stores or transmits:
- your source code, file names or open editors
- keystrokes or clipboard contents
- browsing history, passwords or any personal files
- anything at all about you
What is stored, and where:
- Your settings, in VS Code's own settings store.
- A reminder counter per day, plus your last answer, in VS Code's local
globalState on your machine.
There is no telemetry and no analytics. There is no backend, no database
and no account. Everything works fully offline. Uninstalling the extension
leaves no HydraDev data behind.
HydraDev is designed to be invisible until it is needed.
- No polling. There is no 1-second tick anywhere. Timers are single
setTimeout calls that re-arm only when something actually changes.
- No duplicate loops. Every reminder goes through one centralised timer
manager with named slots, so exactly one normal timer and at most one retry
timer can exist — even across a window reload or a settings change.
- Lazy process start. The companion process is only launched when the first
reminder is due. Before that, HydraDev costs a single timer.
- Idle means idle. While hidden, the companion stops all animations, clears
its timers and releases its audio elements. The status bar countdown re-arms
itself once per displayed minute rather than ticking every second.
- Compositor-friendly animation. Only
transform and opacity are animated,
and will-change is applied only while an animation is actually running.
- Predictable shutdown. Timers, windows, sockets, event listeners and media
elements are all disposed on deactivation.
FAQ
Does HydraDev measure how much water I drink?
No, and it never will. It is a reminder. The statistics measure how often you
answered the reminder, which is labelled as such in the UI.
Why does the companion appear inside VS Code instead of over my desktop?
Because a desktop overlay requires an embedded windowing runtime. See
Companion modes. Running from source enables the floating
version automatically.
Will it interrupt my typing?
No. The floating companion window is explicitly non-focusable, so it never takes
keyboard focus away from your editor. Clicks outside the avatar pass straight
through to the application underneath.
Why did I get one reminder after being asleep instead of four?
By design. On waking, HydraDev recalculates its schedule and shows at most one
reminder rather than dumping every missed one on you.
Why did HydraDev stop asking after a few "not yet" answers?
To stay out of your way. When the retry limit is reached it says "I'll remind
you again later. Take care!" and returns to the normal schedule. Raise
hydraDev.maxRetries, or set it to 0 for unlimited retries.
Can I disable the sounds?
Yes — set hydraDev.soundEnabled to false. HydraDev never touches your system
volume or mute state.
Does it respect reduced motion?
Yes. Your OS prefers-reduced-motion setting is honoured automatically. You can
also force it with hydraDev.reducedMotion, which swaps walking and bouncing for
simple fades.
Where do the logs go?
Run HydraDev: Open Settings and set hydraDev.logLevel to debug, then open
the HydraDev output channel (View → Output, then pick HydraDev). Logs
never contain source code, file names or any personal data.
Something is broken — how do I report it?
Open an issue on GitHub with your
OS, VS Code version and the output-channel log at debug level.
Development
Requirements
- Node.js 20 or newer (VS Code 1.85 ships Node 20; the extension targets it).
- npm 10 or newer.
Getting started
git clone https://github.com/hydradev/hydra-dev.git
cd hydra-dev
npm install
npm run build
Then press F5 in VS Code to launch the Extension Development Host.
To see the reminder without waiting two hours, set hydraDev.reminderInterval
to 1 in the development host, or just run HydraDev: Test Reminder.
Scripts
| Script |
Description |
npm run build |
Production build (type-free, esbuild). Also used by compile. |
npm run watch |
Incremental development build. |
npm run clean |
Removes dist/, out/ and coverage/. |
npm run build:assets |
Regenerates the avatar SVGs, sound cues and the icon. |
npm run lint |
ESLint across the whole repository. |
npm run typecheck |
tsc --noEmit. |
npm test |
Runs the Vitest suite once. |
npm run test:watch |
Vitest in watch mode. |
npm run test:coverage |
Vitest with V8 coverage. |
npm run verify |
Lint + typecheck + test + build. Use this before opening a PR. |
npm run package |
Builds, then produces hydra-dev-<version>.vsix. |
Building and packaging
npm install
npm run build
npm run package
This produces hydra-dev-1.0.0.vsix in the project root, ready to install or
publish:
code --install-extension hydra-dev-1.0.0.vsix
To publish to the Marketplace you need a publisher account and an Azure DevOps
personal access token:
export VSCE_PAT=<your-token>
npx vsce publish --no-dependencies
Publishing is deliberately never automatic. The release.yml workflow only
publishes when you push a v* tag whose version matches package.json.
Architecture
VS Code extension host (src/)
│
│ events (EventManager) │ commands (CompanionHost interface)
▼ ▼
ReminderManager ──► CompanionManager ──► CompanionHost
│ ├─ FloatingCompanion (detached Electron)
└── TimerManager (named slots) └─ WebviewCompanion (in-editor)
| Path |
Responsibility |
src/core/TimerManager.ts |
The single place timers are created. Named slots make duplicates impossible. |
src/core/StateMachine.ts |
Declarative transition table for the hydration lifecycle. |
src/core/ReminderManager.ts |
The engine: scheduling, YES/NO flows, retries, snooze, quiet hours, sleep/wake. |
src/core/SettingsManager.ts |
Validated, range-checked settings. |
src/core/StateStore.ts |
Privacy-safe persistence with migration. |
src/core/SystemEvents.ts |
Sleep/wake and focus signals. |
src/companion/ |
The companion contract and its two hosts. |
src/avatar/ |
Avatar registry and the animation timing table. |
src/ui/ |
Status bar, statistics panel, welcome panel. |
companion/ |
Renderer shared by both companion hosts (DOM, animation, IPC). |
electron/ |
The floating companion's main process and preload bridge. |
The extension host never imports the avatar UI directly — it only speaks the
typed CompanionCommand / CompanionEvent protocol defined in
src/types/index.ts.
Testing
npm test
The suite covers the timer invariants, the state machine, both answer flows,
snooze, quiet hours, retry limits, sleep/wake, settings changes, persistence and
migration, statistics, the companion lifecycle (including window reuse and
destruction), the IPC framing, asset layout and the accessibility helpers.
Contributing
Contributions are welcome. Please:
- Open an issue first for anything substantial, so we can agree on the approach.
- Run
npm run verify before pushing — lint, types, tests and build must all pass.
- Keep the privacy guarantees intact: no telemetry, no network calls, no reading
anything the user did not ask about.
- Add tests for new behaviour. Timer and state-machine changes in particular
must keep the "no duplicate loops" guarantee intact.
License
MIT © HydraDev contributors
HydraDev is not medical advice. Drink water, and drink more of it if you need to.