Local Hours
A Simple Local-first Timesheet App
A local-first, cross-platform time tracking app for macOS, iOS, and Android (planned). Track your hours, generate timesheets, and email them to approvers — all without accounts, servers, or data lock-in.
Learn more: Local Hours website
Screenshots
macOS Menu Bar
| Menu bar popover | Menu bar icon (timer running) |
|---|---|
![]() |
Mac app About
| About window |
|---|
![]() |
Timer
| Timer running | Timesheet preview |
|---|---|
![]() |
![]() |
Settings
| Folder & timezone | Email template | Send reminder |
|---|---|---|
![]() |
![]() |
![]() |
| Embedded timesheet email draft |
|---|
![]() |
Features
Core Functionality
- Quick Time Tracking: Start and stop the clock with a single tap or click
- Work Descriptions: Add notes when you stop the clock to capture what you worked on
- Timesheet Generation: Automatically compile tracked time into clean, ready-to-send timesheets
- Email Integration: Generate emails to approvers with embedded timesheets or attachments
- Cross-Device Sync: Keep data in a shared folder (iCloud, Google Drive, OneDrive) for seamless multi-device sync
Platform-Specific Features
- macOS: Menu bar access and notifications
- iOS: Widgets, long-press actions, and notifications
- Android: PLANNED
Cross-Device Sync
Local Hours keeps your data in sync across devices using your cloud storage folder (iCloud, Google Drive, OneDrive). Here's how sync works:
Same-Device Sync (iOS App ↔ Widget)
| Trigger | Update Speed |
|---|---|
| Start/stop timer in main app | Immediate (via WidgetKit reload) |
| Start timer from widget | Immediate (widget already knows) |
| Timeline refresh (backup) | Every 60 seconds when tracking, every 5 minutes when idle |
Cross-Device Sync (macOS ↔ iOS)
| Action | Other Device Update |
|---|---|
| Start/stop timer | 5-30 seconds (depends on cloud sync speed) |
| Edit entries | 5-30 seconds (depends on cloud sync speed) |
How it works:
- Apps poll storage files every 5 seconds to detect changes
- When a change is detected, the app updates its state automatically
- Cloud sync speed (iCloud, Google Drive, etc.) is the main factor in cross-device delay
- Both devices must be online for sync to occur
Note: Cross-device sync relies on your cloud storage provider. Sync speed varies based on network conditions, device state (active vs. background), and the provider's infrastructure. Typical delays are 5-30 seconds on the same WiFi network.
Installation
Prerequisites
For Development
- macOS 15+ with Xcode 16+
- Skip for Android support
# Install Skip brew install skiptools/skip/skip # Verify installation skip checkup
Building from Source
- Clone the repository:
git clone https://github.com/gogrinimish/LocalHours.git
cd LocalHours- Open in Xcode:
open LocalHours.xcodeproj
- Build and run:
- For macOS: Select
LocalHoursMacscheme - For iOS: Select
LocalHoursscheme - For Android: Select
LocalHoursscheme and choose Android device/emulator
- For macOS: Select
Pre-built Releases
Download the latest release from the Releases page.
Note: The releases are unsigned. For macOS, you may need to right-click and select "Open" on first launch. For iOS, you'll need to sideload using AltStore, Sideloadly, or a similar tool.
Configuration
All configuration is stored in JSON files within your chosen storage folder, enabling sync across devices:
YourTimesheetFolder/
├── config.json # App configuration
├── timesheets/ # Auto-saved period timesheets (backup; one file per period)
│ ├── period-20260203_20260209.json # Deterministic name so macOS and iOS don't both create one
│ └── ...
└── time-entries/ # Raw time entry data
└── entries.json
When your reminder time arrives for a period (e.g. Friday 5pm for a weekly timesheet), the app auto-saves that period’s timesheet into timesheets/. This gives you a backup if entries.json is ever lost, and supports future features like choosing a different period to send for approval.
Configuration Options
| Setting | Description |
|---|---|
storageFolder |
Path to the folder for storing timesheets |
timezone |
Timezone for timesheet calculations (e.g., "America/New_York") |
notificationTime |
Time to send reminder notification (e.g., "17:00") |
emailTemplate |
Custom email template for timesheet submissions (placeholders: {{userName}}, {{periodStart}}, {{periodEnd}}, {{totalHours}}, {{entriesSummary}}) |
approverEmail |
Email address of the timesheet approver |
notificationDays |
Days of week to send notifications (1=Sunday … 7=Saturday; e.g. [6] for Friday) |
Usage
macOS Menu Bar
- Click the clock icon in the menu bar
- Click "Start" to begin tracking
- When finished, click "Stop" and enter a description
- At the configured time, you'll receive a notification to send your timesheet
- Click "Send Timesheet" to email it to your approver
iOS/Android Widgets
- Add the Local Hours widget to your home screen
- Tap the play button to start tracking
- Tap the stop button to stop and add a description
- Use the app for configuration and viewing history
Privacy
Local Hours is built from the ground up to be local-first and privacy-preserving:
- Your data, your files: All data is stored as files in a folder you control
- No servers, no accounts: The app works fully offline and never requires sign-ups
- Bring your own sync: Use iCloud, Google Drive, or OneDrive to sync across devices
- No analytics, no tracking: Nothing is collected, measured, or phoned home
- Open source by design: Inspect the code and see exactly how your data is handled
Feedback & Bugs
Found a bug or have a suggestion? Please open an issue. We use issues for:
- Bug reports – describe the problem, steps to reproduce, and your environment (OS, app version).
- Feature requests – describe the feature and how you’d use it.
- General feedback – ideas, UX improvements, or documentation fixes.
Check existing issues first to avoid duplicates.
Collaborators Wanted
Local Hours is a solo project today. If you’d like to help shape the next set of features, we’re especially interested in collaborators for:
- Android & Windows apps – Extend the app to Android (e.g. via Skip) and Windows (e.g. Swift on Windows or a separate stack). Experience with cross-platform or native mobile/desktop is a plus.
- Multiple projects / timesheets – Design and implement support for multiple projects or timesheet “workspaces” (e.g. per client, per contract) with clear data model and UI.
If you’re interested, open an issue with the label collaborator or good first project, or comment on the relevant roadmap issues.
Contributing
Contributions are welcome! Please read our Contributing Guidelines before submitting a pull request.
Development Setup
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
swift test - Commit:
git commit -m 'Add amazing feature' - Push:
git push origin feature/amazing-feature - Open a Pull Request
Support the Project
If Local Hours is useful to you, you can support its development:
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built with Skip for cross-platform support
- Icons designed with accessibility in mind







