This web application is a stopwatch and interval timer designed for athletes. It allows users to track workout time, record laps with color coding, switch timer modes by tapping, and receive sound notifications after each interval. All settings are saved between sessions, ensuring a seamless user experience.
demo.mp4
- Large timer
MM:SS.hhtailored for training. - Laps with color coding (cyclic palette, consecutive same-color preservation).
- Tap to switch timer mode: elapsed ↔ last lap ↔ countdown to alert.
- Sound notifications after each new lap (configurable interval).
- Keep Screen On (Wake Lock) while running.
- Themes:
lightPench,darkPench,light,dark,black. - Settings persistence across sessions.
- Accessibility: visible focus, ARIA labels, keyboard shortcuts.
- Onboarding tour with step-by-step UI guide (implemented via
driver.js).
- Sound Notification — toggle + interval.
- Change Time by Tap — switch between elapsed / last lap / countdown.
- Keep Screen On — prevents the device screen from turning off.
- Theme Color — instant apply of one of 5 themes.
- React 19 + TypeScript — strongly typed UI components.
- Redux Toolkit — predictable state management (stopwatch & settings slices).
- Sass modules — styling with theme support.
- Vite — fast dev server and optimized production build.
- PWA — installable, offline-ready with auto-updates.
- Node.js >=20 — development and build environment.
The project has been tested with:
- Node.js v20.17.0 (recommended: Node >=20)
- npm v11.4.2 (recommended: npm >=11)
- Clone the repository
git clone https://github.com/kepkame/stopwatch.git
cd stopwatch- Install dependencies
npm install- Start in development mode
npm run devAfter starting, the app will be available at http://localhost:5173
To generate an optimized production build, run:
npm run buildThe compiled assets will be available in the dist/ directory.
You can deploy this folder to any static hosting service such as Vercel, Netlify, GitHub Pages, or an Nginx server.
For local testing of the production build, use:
npm run previewBy default, the application will be available at http://localhost:4173.
| Script | Description |
|---|---|
dev |
Start Vite dev server (HMR) |
build |
TypeScript build + Vite production |
preview |
Local server to preview dist/ |
lint |
Run ESLint |
stopwatch/
├── public/ # Static public assets (icons, favicon, sounds, screenshots)
├── src/
│ ├── assets/ # Fonts (woff/woff2)
│ ├── components/ # Application UI components (controls, header, laps, settings, timer)
│ │ ├── Controls/ # Control panel (Pause, Lap, Play, Reset)
│ │ ├── Header/ # App header with logo and settings
│ │ ├── LapList/ # Lap list components and types
│ │ ├── SettingsModal/ # Settings modal with feature sections
│ │ ├── TimerDisplay/ # Animated timer display with modes
│ │ └── ui/ # Reusable UI elements (Button, Modal, Switch, etc.)
│ ├── features/ # Feature-specific modules (e.g., theme)
│ ├── hooks/ # Custom React hooks
│ ├── pages/ # Application pages (currently StopwatchPage)
│ ├── services/ # Services (sound, onboarding tour, settings persistence, wake lock)
│ ├── shared/ # Shared configuration (settings schema & defaults)
│ ├── store/ # Redux store (slices, selectors, thunks, persistence, types)
│ ├── styles/ # Global SCSS styles, variables, themes
│ ├── utils/ # Utilities (time formatting, lap swipe config, helpers)
│ ├── App.tsx # Root component
│ ├── main.tsx # Entry point, Redux and theme setup
│ └── vite-env.d.ts # Vite type declarations
├── package.json # Dependencies and scripts
├── vite.config.ts # Vite build configuration
└── tsconfig.json # TypeScript configurationConfigured in vite.config.ts:
'@': '/src',
'@assets': '/src/assets',
'@components': '/src/components',
'@hooks': '/src/hooks',
'@pages': '/src/pages',
'@services': '/src/services',
'@shared': '/src/shared',
'@store': '/src/store',
'@styles': '/src/styles',
'@types': '/src/types',
'@utils': '/src/utils'-
Configured with vite-plugin-pwa (
autoUpdate). -
Workbox caches assets via:
globPatterns: **/*.{js,css,html,ico,png,svg,webp,mp3} -
Manifest includes:
- icons (192/512, maskable & rounded),
- theme/background colors,
- install screenshots.
-
Supports installation on mobile devices and offline usage.