An offline time tracking application built with FastAPI (Python) backend, Svelte frontend, and Docker. No login required and designed to run locally on your browser with JSON file storage.
Features:
- Start/stop timer for tasks
- Manual time entry creation
- Weekly calendar view
- Weekly reports with charts
- Project and category organization
- light/dark mode
Note:
- I have not made it responsive yet, so best viewed on desktop browsers.
- Requirements
- Quick Start
- Screenshots
- Nerd Stuff
- Development
- Troubleshooting
- Future Enhancements
- License
- Credits
Windows:
# Start with dark theme (default)
.\start.bat
# Start with light theme
## .\start.bat light
# Start with dark theme (explicit)
## .\start.bat darkLinux/Mac:
# Make script executable (first time only)
chmod +x start.sh
# Start with dark theme (default)
./start.sh
# Start with light theme
## ./start.sh light
# Start with dark theme (explicit)
## ./start.sh darkNote:
- The default port is 5173 for frontend and 8000 for backend, if that port is in use or you want to change it. Consider looking to Ports
- Start/Stop Timer - Real-time timer with pause and reset
- Manual Entry - Create time entries manually with custom times
- Click to Create Entry - Click anywhere on calendar to create a new entry via modal
- Click to Edit/Delete - Click on any entry to edit or delete it
- Projects & Categories - Organize time entries by project and category
- Weekly Calendar View - Toggl-style calendar divided by week and day
- Daily Reports - Bar and pie charts showing time breakdown
- Project Overview - View all projects with expandable entry history
- Light/Dark Mode - Toggle between themes via UI or startup flag
- Custom Projects - Add and persist custom projects using localStorage
- JSON Storage - All data saved locally as JSON files (no database needed)
- Robust Data Handling - Auto-corrects total_duration if entries deleted from JSON
- Auto-updating Timer - Start time always shows current time when timer is inactive
- Responsive Design - Works on desktop and mobile browsers
- Auto Browser Launch - Automatically opens browser on startup
- Backend: FastAPI (Python 3.11)
- Frontend: Svelte 4 + Vite 5
- Charts: Chart.js
- Storage: JSON files (local) + localStorage
- Containerization: Docker & Docker Compose
time_tracking_app/
├── backend/ # FastAPI application
│ ├── main.py # Main app entry point
│ ├── routes/
│ │ └── timers.py # Timer endpoints
│ ├── models/
│ │ └── timer.py # Data models
│ ├── data/ # JSON storage directory
│ ├── requirements.txt # Python dependencies
│ └── Dockerfile
├── frontend/ # Svelte application
│ ├── src/
│ │ ├── App.svelte
│ │ ├── components/
│ │ │ ├── Sidebar.svelte
│ │ │ ├── Calendar.svelte
│ │ │ ├── Timer.svelte
│ │ │ ├── Modal.svelte # Entry creation/editing modal
│ │ │ ├── Reports.svelte
│ │ │ └── Projects.svelte
│ │ ├── styles/ # CSS modules
│ │ │ ├── theme.css # Theme variables
│ │ │ ├── calendar.css
│ │ │ ├── sidebar.css
│ │ │ ├── timer.css
│ │ │ ├── reports.css
│ │ │ └── projects.css
│ │ ├── stores/
│ │ │ └── theme.js # Theme state management
│ │ ├── utils/
│ │ │ └── storage.js # localStorage utilities
│ │ └── main.js
│ ├── package.json
│ ├── vite.config.js
│ └── Dockerfile
├── docker-compose.yml # Docker orchestration
├── start.bat # Windows startup script
└── start.sh # Linux/Mac startup script
The bat/bash script will:
- Check if Docker is running
- Build and start both containers
- Automatically open your browser to http://localhost:5173
- Display the app in your chosen theme
cd backend
pip install -r requirements.txt
python main.py
# Backend runs on http://localhost:8000cd frontend
npm install
npm run dev
# Frontend runs on http://localhost:5173To change the ports used by the Time Tracking App, simply edit the ports.conf file:
# Frontend port (default: 5173)
FRONTEND_PORT=5173
# Backend port (default: 8000)
BACKEND_PORT=8000FRONTEND_PORT=3000
BACKEND_PORT=5000After changing the ports, restart the containers:
docker-compose down
docker-compose up -dThe application will automatically use the new ports specified in ports.conf.
Themes are managed through:
- CSS custom properties in
frontend/src/styles/theme.css - Svelte store in
frontend/src/stores/theme.js - localStorage for persistence across sessions
Categories and Projects are client-side only and stored in localStorage.
POST /api/timers- Create new timer entryGET /api/timers/{date}- Get entries for a specific day (YYYY-MM-DD)GET /api/timers/week/{start_date}- Get entries for a weekPUT /api/timers/{entry_id}- Update timer entryDELETE /api/timers/{entry_id}- Delete timer entry
GET /api/stats/week/{start_date}- Get weekly statistics with project/category breakdown
All data is stored as JSON files in the backend/data/ directory:
- Files are named by date:
YYYY-MM-DD.json - Each file contains entries for that day with timestamps and durations
- Data persists between sessions
Example JSON structure:
{
"date": "2026-01-28",
"total_duration": 3600,
"entries": [
{
"id": "uuid-string",
"project": "Development",
"category": "Work",
"description": "Building features",
"start_time": "2026-01-28T09:00:00",
"end_time": "2026-01-28T10:00:00",
"duration": 3600
}
]
}Add a new timer endpoint:
- Edit
backend/routes/timers.py - Update
backend/models/timer.pyif needed
Add a new Svelte component:
- Create new file in
frontend/src/components/ - Import and use in
App.svelte
docker-compose build --no-cachePort conflicts:
- Backend: Change port 8000 in
docker-compose.yml - Frontend: Change port 5173 in
docker-compose.yml
CORS errors:
- Ensure backend is running on http://localhost:8000
- Check
API_URLin frontend environment variables
Data not persisting:
- Ensure
backend/data/directory is created - Check file permissions in the data directory
- Goal System
- Export data PDF/CSV/Excel/Whatever-i-don't-care
- Recurring tasks
- Time blocking/planning
- More Search functionality (?)
- Settings and preferences
| User | Feature |
|---|---|
|
Cola1000 |
idk |