Finally, a good fucking clock app on linux.
  • TypeScript 87.5%
  • JavaScript 8.9%
  • CSS 2.8%
  • Shell 0.7%
  • HTML 0.1%
Find a file
Alex f4da982781 docs: record the 2026-08-06 alarm scheduling fixes in summary.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 22:10:58 +02:00
assets feat: add matugen template asset for users 2026-07-28 21:55:22 +02:00
src build: add typechecking, declare the electron bridge, pin @m3e peers 2026-08-06 21:51:46 +02:00
.gitignore fix(pkg): install desktop entry and icons to system scope 2026-08-06 21:51:37 +02:00
ATTRIBUTIONS.md Initial commit: Material Clock Electron+React app 2026-05-26 19:32:47 +02:00
claude.md Use @m3e/react switch and slider; fix FABs, nav pill, WM class 2026-05-26 21:52:30 +02:00
electron-main.cjs fix: never schedule alarms outside the running app 2026-08-06 21:51:14 +02:00
index.html Initial commit: Material Clock Electron+React app 2026-05-26 19:32:47 +02:00
package-lock.json build: add typechecking, declare the electron bridge, pin @m3e peers 2026-08-06 21:51:46 +02:00
package.json build: add typechecking, declare the electron bridge, pin @m3e peers 2026-08-06 21:51:46 +02:00
PKGBUILD fix(pkg): install desktop entry and icons to system scope 2026-08-06 21:51:37 +02:00
postcss.config.mjs Initial commit: Material Clock Electron+React app 2026-05-26 19:32:47 +02:00
preload.cjs Initial commit: Material Clock Electron+React app 2026-05-26 19:32:47 +02:00
README.md feat: add matugen template asset for users 2026-07-28 21:55:22 +02:00
summary.md docs: record the 2026-08-06 alarm scheduling fixes in summary.md 2026-08-06 22:10:58 +02:00
tsconfig.json build: add typechecking, declare the electron bridge, pin @m3e peers 2026-08-06 21:51:46 +02:00
vite.config.ts Initial commit: Material Clock Electron+React app 2026-05-26 19:32:47 +02:00

Material Clock

A Material Design 3 clock application for Linux, built with Electron + React. Adapts its color scheme from your system's Material You palette (via quickshell/material-colors.scss) for seamless desktop integration.

Material Clock icon

Features

  • Alarms — Create and manage alarms with custom labels and sounds. Persisted across sessions via ~/.config/material-clock/. Scheduled through systemd timers for reliability even when the app is closed.
  • Timers — Multiple concurrent countdown timers with circular progress indicators, custom sounds, and labels.
  • Stopwatch — Lap tracking with animated flash effect. Tray menu integration for adding laps without switching windows.
  • World Clock — Track multiple time zones at once.
  • Dynamic theming — Reads Material You colors from ~/.local/state/quickshell/user/generated/material_colors.scss and applies them live. Falls back to warm dark defaults (#1C1B17).
  • System tray — Hides to tray on close; context menu for quick alarm/timer/stopwatch access.
  • Desktop notificationsnotify-send integration with functional Snooze (+1 min) and Stop actions.
  • Single instance — Prevents duplicate windows; second-instance launches restore the existing window or trigger alarms.

Requirements

Dependency Purpose
electron ≥ 41 App runtime
mpv Alarm and timer audio
libnotify (notify-send) Desktop notifications
systemd Reliable alarm scheduling (optional)
Node.js ≥ 18 Build only

Install (Arch Linux / CachyOS)

A PKGBUILD is included and configured to build cleanly (even in a clean chroot) by utilizing a local npm cache. To build and install from source:

makepkg -si

This compiles a production build and installs the app to /opt/material-clock with a .desktop entry, system icon, and /usr/bin/material-clock launcher.

Development

npm install
npm run dev:electron   # Vite dev server + Electron with hot reload

Build

npm run build          # Vite production build → dist/
npm run dist           # Build AppImage via electron-builder

Project Structure

electron-main.cjs     Main process — window, tray, IPC, alarm scheduling, audio
preload.cjs           Context bridge exposing electronAPI to the renderer
src/
  bridge.js           Renderer-side wrapper around window.electronAPI
  main.tsx            React entry point
  app/
    App.tsx           Theme initialization + router
    routes.tsx        Hash router config
    components/
      Layout.tsx            Persistent shell: ringing overlay, bottom nav, stopwatch state
      AlarmsScreen.tsx
      TimersScreen.tsx
      StopwatchScreen.tsx
      WorldClockScreen.tsx
      TimePickerDialog.tsx  Radial time/duration picker
      AlarmCard.tsx
      AlarmDetailSheet.tsx
      SettingsDialog.tsx
      BottomNavigation.tsx
      ui/                   shadcn/ui component library
  styles/
    index.css / theme.css / fonts.css / tailwind.css
assets/               App icons (PNG + SVG)
PKGBUILD              Arch Linux package build script

Theming

Material Clock reads color tokens from one of these locations (in order of priority):

  1. Matugen: ~/.config/material-clock/colors.json
  2. Quickshell: ~/.local/state/quickshell/user/generated/material_colors.scss

If neither is present, the app falls back to a warm brown-black dark palette. See electron-main.cjs → get-theme IPC handler for the full token mapping.

Using Matugen

To theme Material Clock using matugen, copy the provided template file assets/matugen-template.json into your Matugen templates directory (e.g., ~/.config/matugen/templates/material-clock.json):

mkdir -p ~/.config/matugen/templates
cp /opt/material-clock/assets/matugen-template.json ~/.config/matugen/templates/material-clock.json

Then, add it to your matugen config (~/.config/matugen/config.toml):

[templates.material_clock]
input_path = '/home/youruser/.config/matugen/templates/material-clock.json'
output_path = '/home/youruser/.config/material-clock/colors.json'

Data Location

All user data is stored in ~/.config/material-clock/:

  • alarms.json — alarm definitions
  • timers.json — timer state
  • settings.json — volume, debug mode
  • custom_sounds.json — user-added audio files

License

See ATTRIBUTIONS.md.