Run desktop packaging workflows on Node 24 and load Vite through an ESM config so macOS, Linux, and Windows builds use a runtime compatible with Vite 7.
TimeTracker Desktop App
Electron-based desktop application for TimeTracker.
Building
Prerequisites
- Node.js 18+
- npm
Install Dependencies
npm install
Build for Current Platform
npm run build
Build for Specific Platform
# Windows
npm run build:win
# macOS
npm run build:mac
# Linux
npm run build:linux
Build for All Platforms
npm run build:all
Code Signing (Windows)
To avoid the "Unknown Publisher" warning, you need to sign the Windows executable with a code signing certificate.
Quick Setup
-
Obtain a Code Signing Certificate:
- Purchase from a CA (Sectigo, DigiCert, etc.) - $150-600/year
- Or create a self-signed certificate for testing
-
Local Build:
# Windows PowerShell $env:CSC_LINK_FILE = "path/to/certificate.pfx" $env:CSC_KEY_PASSWORD = "YourCertificatePassword" npm run build:win -
CI/CD (GitHub Actions):
- Store certificate as Base64 in GitHub Secret:
WINDOWS_CODE_SIGN_CERT - Store password in GitHub Secret:
WINDOWS_CODE_SIGN_PASSWORD - The workflow will automatically sign the executable
- Store certificate as Base64 in GitHub Secret:
For detailed instructions, see Windows Code Signing Guide.
Development
Renderer bundle
The UI is bundled from src/renderer/js/app.js into src/renderer/js/bundle.js with esbuild (npm run build:renderer). Anything the app needs at runtime (including src/renderer/js/utils/helpers.js, which sets window.Helpers) must be imported from app.js so it is included in the bundle. After changing renderer source files, run npm run build:renderer before packaging or committing an updated bundle.js.
Run in Development Mode
npm start
(npm start and every packaging script run build:renderer first so installers do not ship a stale bundle.js.)
Run with DevTools
npm run dev
Configuration
Getting an API Token
Before connecting the desktop app, you need to create an API token:
- Log in to TimeTracker Web App as an administrator
- Navigate to Admin > Security & Access > Api-tokens (
/admin/api-tokens) - Click "Create Token"
- Fill in the required information:
- Name: A descriptive name (e.g., "Desktop App - Windows")
- User: Select the user this token will authenticate as
- Scopes: Select at least the following permissions:
read:projects- View projectsread:tasks- View tasksread:time_entries- View time entries (required for timer status; the app uses this ifread:usersis not granted)write:time_entries- Create and update time entriesread:users- Recommended: lets the app verify your session withGET /api/v1/users/me(otherwise it falls back to timer status)
- Expires In: Optional expiration period (leave empty for no expiration)
- Click "Create Token"
- Important: Copy the generated token immediately - you won't be able to see it again!
- Token format:
tt_<32_random_characters> - Example:
tt_abc123def456ghi789jkl012mno345pq
- Token format:
Connecting the App
The desktop app can be configured in multiple ways:
Method 1: In-App Login (Recommended)
- Launch the desktop app
- Step 1 — Server: Enter your TimeTracker base URL (e.g.
https://your-server.comorhttp://192.168.1.10:5000). Trailing slashes are normalized away. You may omit the scheme for convenience; the app assumeshttps://when checking. - Click Test server and confirm you see a success message (the app calls
GET /api/v1/infoand checks for a TimeTracker response). - Click Continue to token.
- Step 2 — API token: Paste the
tt_…token from the web app, then Log in. The app verifies the token with the server (user profile or timer status). - If successful, the main window opens. If initial server setup is not finished in the browser,
setup_requiredin the API response is surfaced so you can complete setup first.
Method 2: Command Line
TimeTracker.exe --server-url https://your-server.com
Then enter your API token in the login screen.
Method 3: Environment Variable
# Windows
set TIMETRACKER_SERVER_URL=https://your-server.com
TimeTracker.exe
# Linux/macOS
export TIMETRACKER_SERVER_URL=https://your-server.com
./TimeTracker
Method 4: Settings Screen
- Launch the app
- Navigate to Settings tab
- Enter your Server URL and API Token
- Click "Save Settings" or "Test Connection" to verify
Connection Status
The app shows a connection status indicator in the header:
- Green dot (●): Connected and authenticated
- Red dot (●): Connection error or authentication failed
- Gray circle (○): Not connected
The connection is automatically checked every 30 seconds.
Automated tests (renderer client)
From the desktop/ directory:
npm test
Runs Node’s test runner on test/api-client.test.js (URL normalization, TimeTracker JSON shape checks, and error classification).
Troubleshooting
Login or “Test server” shows a TLS or certificate message:
- Use a certificate trusted by the OS, or for lab use only, try
http://on a trusted network if your server supports it.
Token rejected after “server OK”:
- Verify the token starts with
tt_, is not expired, and includes at leastread:time_entries(and ideallyread:users).
"Connection failed" error:
- Verify the server URL is correct and accessible
- Check your internet connection
- Ensure the server is running and the API is accessible
- For local development, use
http://localhost:5000or your local IP address - Check the connection status indicator in the header
Settings not saving:
- Ensure you have write permissions in the app's data directory
- Check that electron-store is working properly
- Try clearing settings and re-entering them
Window stuck on loading, blank content, or unstable navigation (especially Windows):
- Use the latest release or rebuild from source; older builds could mis-handle
file:navigation in the main process or ship a renderer bundle without helpers loaded. - From source, run
npm installandnpm run build:renderer, thennpm startor rebuild the installer. - See Desktop build Windows troubleshooting for environment-specific build issues.
For more details, see Desktop Settings Guide.
Project Structure
desktop/
├── src/
│ ├── main/ # Main process (Electron)
│ ├── renderer/ # Renderer process (UI)
│ └── shared/ # Shared code
├── assets/ # Icons and assets
├── scripts/ # Build scripts
└── dist/ # Build output
Version Management
The version is automatically synced from setup.py before building. The build scripts handle this automatically.
License
MIT