The best free and open-source automated time tracker. Cross-platform, extensible, privacy-focused. https://activitywatch.net/
  • Python 87.1%
  • Inno Setup 12.4%
  • Batchfile 0.5%
Find a file
Bob dc1371ca3d
feat: add aw-tauri CI builds alongside aw-qt (#1209)
* ci(build): modernize runners, node, cache keys for aw-qt CI

- Ubuntu 22.04 → 24.04, add macos-latest alongside macOS-13
- Node 20 → 22
- Fix macOS Python setup condition (matrix.os instead of runner.os)
- Use matrix.os in cache keys for unique per-variant caching
- Enable cargo cache on macOS (was disabled)
- Fix qt5-default → qt5-qmake + qtbase5-dev (ubuntu-24.04)
- Fix artifact upload name collision (matrix.os)
- Fix typo: 'Wether' → 'Whether'

* feat: add aw-tauri and awatcher submodules

aw-tauri is the Tauri-based replacement for aw-qt (system tray).
awatcher is used on Linux for Wayland-compatible window watching.

* feat: add aw-tauri CI workflow, Makefile support, and packaging

Add a separate build-tauri.yml CI workflow that builds aw-tauri alongside
the existing aw-qt builds. The two build pipelines coexist independently.

Makefile changes:
- TAURI_BUILD=true flag switches between aw-qt and aw-tauri submodules
- aw-server-rust builds only aw-sync in Tauri mode (not full server)
- ICON points to aw-tauri icons when TAURI_BUILD is set
- Conditional packaging: aw-tauri app bundle on macOS, Inno Setup on Windows

Packaging:
- build_app_tauri.sh: macOS .app bundle creator for Tauri
- aw-tauri.iss: Windows Inno Setup with different AppId/AppName to avoid
  colliding with existing aw-qt installations (addresses review comment)
- move-to-aw-modules.sh: Linux module discovery helper (rsync -a, proper
  line continuation)
- README.txt: Linux end-user instructions (typos fixed)
- package-all.sh: Tauri-aware zip/installer selection

Build-tauri.yml features:
- Multi-OS: ubuntu-24.04, ubuntu-24.04-arm, windows-latest, macOS-13,
  macos-latest
- Retry wrapper (nick-fields/retry) for flaky builds
- Separate artifact names (builds-tauri-*) to not collide with aw-qt
- Tauri-specific APT deps (libgtk-3-dev, libwebkit2gtk-4.1-dev, etc.)

Also updates contributor CSV files (brayo-pip → 0xbrayo).

Based on work by @0xbrayo in PR #1163.

* ci: fix macOS-13 runner label casing (macOS-13 -> macos-13)

GitHub Actions runner labels are case-sensitive. `macOS-13` (capital OS)
is not a valid runner label and causes CI failures. The correct label is
`macos-13` (all lowercase). Fix this in both build.yml and build-tauri.yml.

* ci: replace deprecated macos-13 with macos-14 runner

macos-13 (x86_64) is deprecated by GitHub Actions. Replace with macos-14
(ARM64/Apple Silicon) in both build.yml and build-tauri.yml. Also remove
the macos-13-specific Python workaround (custom pkg install for macOS 10.9
compatibility) since macos-14 uses standard actions/setup-python.

* ci: upgrade Poetry from 1.3.2 to 1.4.2 to fix Windows race condition

Poetry 1.3.x has a known Windows file-locking race condition when
installing packages (tilde-prefixed dist-info temp files cause OSError).
Version 1.4.0+ fixes this. Using 1.4.2 (last release in 1.4.x series)
to stay on same lockfile format as 1.3.x.

Fixes: Windows CI failure in jobs that run 'poetry install'

* ci: cache node_modules and aw-tauri cargo target to reduce build times

- Cache node_modules directly instead of npm global cache. The global
  cache only saves download time, but npm ci still does a full install
  into node_modules every run (~5-7 min per npm ci call). Caching
  node_modules directly skips this entirely on cache hit.

- Cache aw-tauri/src-tauri/target alongside aw-server-rust/target in
  the Tauri workflow. The Tauri Cargo release build takes ~8 min
  uncached and was not being cached previously.

- Also cache aw-tauri/node_modules in the Tauri workflow (has its own
  package-lock.json separate from aw-webui).

Expected improvement: ~15-20 min savings on cached Windows Tauri builds
(from ~34 min to ~15 min).
2026-02-22 17:41:36 +01:00
.github feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
aw-client@8f9483ddb4 build(deps): updated submodules 2025-02-03 11:16:21 +01:00
aw-core@e13c33c6d7 build(deps): updated submodules 2025-08-20 14:06:41 +02:00
aw-notify@bcea3cd1a7 build(deps): updated submodules 2025-08-20 14:06:41 +02:00
aw-qt@6ab7e3f139 build(deps): updated submodules 2025-02-03 11:16:21 +01:00
aw-server@4089343a84 build(deps): updated submodules 2025-08-20 14:06:41 +02:00
aw-server-rust@8e369e7d18 build(deps): updated submodules 2025-08-20 14:06:41 +02:00
aw-tauri@89e5ddf732 feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
aw-watcher-afk@403a331f6f build(deps): updated submodules 2025-08-20 14:06:41 +02:00
aw-watcher-input@9bb5045456 build(deps): updated submodules 2024-10-17 19:27:53 +02:00
aw-watcher-window@c80aa5adbb build(deps): updated submodules 2024-10-17 19:27:53 +02:00
awatcher@678d7fd086 feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
scripts feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
.gitattributes configured linguist to hide build scripts from language summary 2017-10-04 16:45:51 +02:00
.gitignore chore: added .python-version to gitignore 2022-08-30 11:28:30 +02:00
.gitmodules feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
.tool-versions ci: downgrade to Python 3.9 (#941) 2023-08-30 13:55:30 +02:00
aw.spec build(deps): update pyinstaller to v6.6, and set contents_directory='.' in aw.spec and submodules 2024-05-06 17:22:41 +02:00
CITATION.cff chore: bumped version to v0.13.1 in various places, including in submodules 2024-06-10 20:36:55 +02:00
CODE_OF_CONDUCT.md Create CODE_OF_CONDUCT.md 2018-10-07 02:50:18 +02:00
CONTRIBUTING.md docs: add link to docs repo in CONTRIBUTING.md (#1190) 2026-02-20 16:39:28 +01:00
diagram.svg chore: update diagram [skip ci] 2022-06-03 13:16:21 +02:00
gptme.toml chore: added gptme.toml file 2025-08-20 19:10:24 +02:00
LICENSE.txt added LICENSE 2017-03-29 23:20:26 +02:00
Makefile feat: add aw-tauri CI builds alongside aw-qt (#1209) 2026-02-22 17:41:36 +01:00
poetry.lock build(deps): updated dependencies 2024-10-17 19:29:53 +02:00
pyproject.toml build(deps): updated dependencies 2024-10-17 19:29:53 +02:00
README.md docs: improve server architecture documentation 2025-08-20 19:11:30 +02:00
SECURITY.md added SECURITY.md 2021-06-17 09:58:21 +02:00

Records what you do so that you can know how you've spent your time.
All in a secure way where you control the data.


WebsiteForumDocumentationReleases
Contributor statsCI overview



Do you want to receive email updates on major announcements?
Signup for the newsletter!

Table of Contents

About

The goal of ActivityWatch is simple: Enable the collection of as much valuable lifedata as possible without compromising user privacy.

We've worked towards this goal by creating an application for safe storage of the data on the user's local machine and as well as a set of watchers which record data such as:

  • Currently active application and the title of its window
  • Currently active browser tab and its title and URL
  • Keyboard and mouse activity, to detect if you are AFK ("away from keyboard") or not

It is up to you as user to collect as much as you want, or as little as you want (and we hope some of you will help write watchers so we can collect more).

Screenshots

You can find more (and newer) screenshots on the website.

Installation & Usage

Downloads are available on the releases page.

For instructions on how to get started, please see the guide in the documentation.

Interested in building from source? There's a guide for that too.

Is this yet another time tracker?

Yes, but we found that most time trackers lack one or more important features.

Common dealbreakers:

  • Not open source
  • The user does not own the data (common with non-open source options)
  • Lack of synchronization (and when available: it's centralized and the sync server knows everything)
  • Difficult to setup/use (most open source options tend to target programmers)
  • Low data resolution (low level of detail, does not store raw data, long intervals between entries)
  • Hard or impossible to extend (collecting more data is not as simple as it could be)

To sum it up:

  • Closed source solutions suffer from privacy issues and limited features.
  • Open source solutions aren't developed with end-users in mind and are usually not written to be easily extended (they lack a proper API). They also lack synchronization.

We have a plan to address all of these and we're well on our way. See the table below for our progress.

Feature comparison

Basics
User owns data GUI Sync Open Source
ActivityWatch WIP, decentralized
Selfspy
ulogme
RescueTime Centralized
WakaTime Centralized Clients
Platforms
Windows macOS Linux Android iOS
ActivityWatch
Selfspy
ulogme
RescueTime Limited functionality
Tracking
App & Window Title AFK Browser Extensions Editor Plugins Extensible
ActivityWatch
Selfspy
ulogme
RescueTime
WakaTime Only for text editors

For a complete list of the things ActivityWatch can track, see the page on watchers in the documentation.

Architecture

graph TD;
  aw-qt[<a href='https://github.com/ActivityWatch/aw-qt'>aw-qt</a>];
  aw-notify[<a href='https://github.com/ActivityWatch/aw-notify'>aw-notify</a>];
  aw-server[<a href='https://github.com/ActivityWatch/aw-server'>aw-server</a>];
  aw-webui[<a href='https://github.com/ActivityWatch/aw-webui'>aw-webui</a>];
  aw-watcher-window[<a href='https://github.com/ActivityWatch/aw-watcher-window'>aw-watcher-window</a>];
  aw-watcher-afk[<a href='https://github.com/ActivityWatch/aw-watcher-afk'>aw-watcher-afk</a>];
  aw-watcher-web[<a href='https://github.com/ActivityWatch/aw-watcher-web'>aw-watcher-web</a>];
  aw-sync[<a href='https://github.com/ActivityWatch/aw-server-rust/tree/master/aw-sync'>aw-sync</a>];

  aw-qt -- Manages --> aw-server;
  aw-qt -- Manages --> aw-notify -- Queries --> aw-server;
  aw-qt -- Manages --> aw-watcher-window -- Watches --> S1[Active window] -- Heartbeats --> aw-server;
  aw-qt -- Manages --> aw-watcher-afk -- Watches --> S2[AFK status] -- Heartbeats --> aw-server;
  Browser -- Manages --> aw-watcher-web -- Watches --> S3[Active tab] -- Heartbeats --> aw-server;
  SF -- Dropbox/Syncthing/etc --> SF;
  aw-server <-- Push/Pull --> aw-sync <-- Read/Write --> SF[Sync folder];
  aw-server -- Serves --> aw-webui -- Queries --> aw-server;

  %% User -- Interacts --> aw-webui;
  %% User -- Observes --> aw-notify;
  %% User -- Interacts --> aw-qt;

classDef lightMode fill:#FFFFFF, stroke:#333333, color:#333333;
classDef darkMode fill:#333333, stroke:#FFFFFF, color:#FFFFFF;

classDef lightModeLinks stroke:#333333;
classDef darkModeLinks stroke:#FFFFFF;

class A,B,C,D,E,G lightMode;
class A,B,C,D,E,G darkMode;

%% linkStyle 0 stroke:#FF4136, stroke-width:2px;
%% linkStyle 1 stroke:#1ABC9C, stroke-width:2px;

About this repository

This repo is a bundle of the core components and official modules of ActivityWatch (managed with git submodule). Its primary use is as a meta-package providing all the components in one repo; enabling easier packaging and installation. It is also where releases of the full suite are published (see releases).

Server

ActivityWatch has two server implementations:

  • aw-server (Python) - The current default implementation
  • aw-server-rust - A Rust implementation that is the planned future default

Both provide a REST API to a datastore and query engine, and serve the web interface developed in the aw-webui project (which provides the frontend).

The REST API includes:

  • Access to a datastore suitable for timeseries/timeperiod-data organized in "buckets" (containers grouping related activity data by metadata like client type or hostname)
  • Buckets API: Create, retrieve, and delete data buckets
  • Events API: Read and write timestamped events within buckets
  • Heartbeat API: Watchers use heartbeat signals to update the current state of activity (e.g., active application, AFK status)
  • Query API: simple query scripting language for filtering, merging, grouping, and transforming events
  • Client libraries: Language-specific libraries like aw-client (Python), aw-client-js, and aw-client-rust that wrap REST endpoints for programmatic access

The frontend (aw-webui) includes:

  • Data visualization: Dashboard and timeline views showing activity summaries with detailed breakdowns of app usage, web browsing, and user-defined categories
  • Query explorer: Browser-based interface for writing, executing, and debugging queries with real-time results
  • Activity browser: Navigate through historical data with filtering by date ranges, applications, websites, and custom categories
  • Raw data access: View and browse individual events from all tracking buckets with detailed metadata
  • Export functionality: Export activity data in JSON format (individual buckets or complete datasets) via web interface or REST API

Watchers

ActivityWatch comes pre-installed with two watchers:

  • aw-watcher-afk tracks the user active/inactive state from keyboard and mouse input
  • aw-watcher-window tracks the currently active application and its window title.

There are lots of other watchers for ActivityWatch which can track more types of activity. Like aw-watcher-web which tracks time spent on websites, multiple editor watchers which track spent time coding, and many more! A full list of watchers can be found in the documentation.

Libraries

  • aw-core - core library, provides no runnable modules
  • aw-client - client library, useful when writing watchers

Folder structure

Contributing

Want to help? Great! Check out the CONTRIBUTING.md file!

Questions and support

Have a question, suggestion, problem, or just want to say hi? Post on the forum!