Skip to content

Latest commit

 

History

102 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Temporal Loom (Time Tracker)

Node 18+ TypeScript 5.5 React 18 Vite Express 4 SQLite Self hosted License

Temporal Loom is a local first, self hosted time tracker built as a Clockify compatible alternative you run yourself. It lives entirely on your own machine: no account, no cloud sync, no third party server ever sees your data. It is aimed at solo use, originally built for tracking bug bounty work and personal life projects side by side, but works for any kind of time tracking. This README documents every feature that exists in the app today, how to run it, and how to use each part of it.

Table of contents

Why Temporal Loom

  • Your data stays on your machine: Everything lives in one SQLite file, with no telemetry, no analytics, and no external calls except the ones you trigger yourself, such as a Clockify import.
  • Built to replace Clockify, not just log hours: Projects, tasks, tags, goals, a scheduler, a dashboard, and exportable reports are all included.
  • Goals that adjust as you go: It tracks daily minimums and ceilings, recalculates your required pace as a month progresses, and tells you plainly if a goal is no longer realistic instead of quietly showing an unreachable number.
  • Quick to use day to day: Timers can be started with one click from several places in the app, not just the main picker.

Features

  • Timer: with a live countdown in the browser tab title, and a one click restart for any past entry
  • Projects and tasks: with colors, nested sub tasks, and an automatic fallback task so untracked time still has a home
  • Tags and sub tags: independent of project or task, that can be attached to any entry
  • Goals: for daily, weekly, monthly, and yearly periods, with per project targets and a self adjusting daily pace
  • Work Hours: an optional setting that checks whether a goal is still realistically reachable today
  • Scheduler: for planning which project you intend to work on, either weekly or on a specific date
  • Dashboard: with stacked charts and breakdowns by project over any date range
  • Reports: with drill down into entries, saved custom views, and export to CSV, HTML, or PDF
  • Calendar: view of any day's entries
  • Clockify import and export: plus a full backup and restore as a single JSON file
  • A full REST API: for scripting or extending the app

Quick start

Requirements: Node.js 18 or newer, and npm.

npm install
cp server/.env.example server/.env
npm run dev

Open http://localhost:5173. The API server runs on port 4310 and the web app on port 5173.

Other useful commands:

Command What it does
npm run dev:server Run only the API server
npm run dev:client Run only the web app
npm run build Build both workspaces for production

If you are upgrading from an older install, no manual steps are needed. Any tables or columns added since your version are created automatically the first time the server starts, and Work Hours and the Scheduler both start out turned off until you enable them in Settings.

Core concepts

Entity What it is
Project A top level bucket of work, for example Bug Bounty or Life. Has a name and a color.
Task (called an activity internally) A specific kind of work inside a project, for example Recon. Tasks can be nested under other tasks. Every project has a hidden General fallback task so time tracked without picking a task still lands somewhere.
Tag A label that can be attached to any entry, independent of project or task. Tags can also have sub tags.
Time entry A single tracked interval: a start time, an end time, a description, a project, a task, and any number of tags.
Goal A time target for one of four periods, Daily, Weekly, Monthly, or Yearly, either overall or scoped to one project. Daily also carries fixed minimum, max, and extreme caps that apply regardless of any goal.

Feature guide

  • Time Tracker: This is the home page. Pick a project and task, optionally add a description and tags, and press Start. Entries within a day are grouped by project, task, and description; if the same combination was logged more than once, they collapse into one row with a count badge. Click a group to expand it, edit any field inline, including start and end times, and reassign the project or task if needed. Every row also has a button to start a new timer with the same details.

  • Goals: Daily, Weekly, Monthly, and Yearly targets, each optionally split across projects. Monthly is the most involved: it recalculates how much time you need per remaining day based on what is left and how many days remain, and reports whether the goal is comfortable, tight, or no longer achievable as set, rather than showing a target that has quietly become impossible.

  • Work Hours: An optional setting, off by default, where you define your normal working window. Once set, the app can tell you whether a daily minimum is still reachable given the time left in that window, instead of assuming you can work indefinitely into the evening.

  • Scheduler: Also optional and off by default. Lets you plan a project for a recurring weekday or for a specific future date, with an optional time target. Whatever is scheduled for today shows up automatically on the Time Tracker under "Today's schedule."

  • Dashboard: Pick a date range, such as this week or a custom range, and see total time, the top project, a stacked daily bar chart by project, and a donut breakdown of the whole range.

  • Reports: Shows totals for a range, a by project table with optional drill down into the underlying entries, and a by activity table with nested task rollups. Any range can be saved as a named view, and reports can be exported as CSV, HTML, or PDF.

  • Projects and Tags: Managed from their own pages: create, rename, recolor, archive, and organize into sub tags or sub tasks inline.

  • Calendar: Pick a single date and see everything logged that day, grouped the same way as the Time Tracker.

Settings and feature toggles

Settings is split into five tabs: General (goals and caps), Features (the toggles below), Work Hours, Scheduler, and Import/Export.

The following are all on by default and can be turned off independently under Features:

  • Dashboard charts
  • Hierarchical task rollups in Reports
  • Drill down into entries from Reports
  • Saved report views
  • CSV, HTML, and PDF report export

Turning everything off gives a minimal tracker that only shows totals; leaving it all on gives the full analytics suite. These toggles are a per browser display preference, not synced data.

Team and Clients sidebar entries also exist as togglable placeholders. Neither has real functionality yet; they are kept for layout parity with Clockify.

Importing and backing up your data

  • Import from Clockify: Upload a Clockify CSV export. Projects, tasks, and tags are matched by name or created if missing. Timestamps are converted using your browser's timezone. Re-uploading the same file is safe, since already imported entries are detected and skipped.
  • Export to Clockify: The reverse of the above, useful if you ever want to move away from Temporal Loom.
  • Full backup and restore: One versioned JSON file covering projects, tasks, tags, entries, goals, caps, work hours, the scheduler, and saved views. Restoring the same file twice is safe and will not create duplicates.
  • App settings export: A smaller export covering configuration only: caps, goals, work hours, the scheduler, saved views, and display preferences. Useful for moving your setup to a new browser or install without re-entering everything by hand.

Running it on your network

By default, both the server and the client dev server bind to 0.0.0.0, so any device on the same network can reach the app at your machine's local IP address, for example http://192.168.1.20:5173.

There is no authentication built in. Anyone who can reach that address can read and write your data. This is fine on a trusted home network and not fine on an untrusted one. To restrict access to just this machine, set HOST=127.0.0.1 in server/.env and remove host: true from client/vite.config.ts.

What's not built yet

  • A user interface for Targets: a planned layer under project and task for tracking a specific bug bounty target. The database table exists, but there is no screen for it.
  • Per task colors: The database column exists, but there is no color picker for tasks yet.
  • A proper Calendar grid: The current Calendar page is a single day list, not a month or week view.
  • Multi user support: Team and Clients are placeholders only.
  • Saved views apply to Reports only: not to the Dashboard's date range picker.
  • Scheduler reminders: The Scheduler currently drives the Time Tracker's Daily tab only, with no notifications and no feed into the Weekly, Monthly, or Yearly tabs.

Technical reference

This section is for contributors and anyone scripting against the API.

Stack

Server: Node.js, TypeScript, Express, SQLite through better-sqlite3, and PDFKit for PDF generation.

Client: React, TypeScript, Vite, React Router, and Recharts for charts.

The two run as separate processes from one repository, using npm workspaces for server and client.

Data and privacy

All data lives in a single SQLite file at server/data/tracker.db. This file is gitignored and never sent anywhere. There is no telemetry, no analytics, and no external API calls beyond ones you explicitly trigger, such as a Clockify import.

Project structure

server/
  src/db/            schema.sql, ULID generator, sqlite client, migrations
  src/models/        workspace, project, activity, tag, goal, dailyCaps, workHours,
                      scheduleEntry, savedView, timeEntry
  src/services/      reportService, reportExportService, exportService, settingsExportService,
                      clockifyExportService, csv, importClockify, goalStatusService,
                      scheduleStatusService
  src/utils/         timezone (shared zoned time conversion, plus day of week and
                      date key helpers, used by the importer, exporter, goal engine,
                      and scheduler)
  src/routes/        one file per resource, mounted under /api/v1
  src/index.ts       app entry point
client/
  public/            favicon assets and the mascot logo image
  src/api/           typed fetch client and shared types
  src/context/       TimerContext, for global running timer state and the live tab title
  src/components/    Sidebar, Timer, ProjectTaskPicker, TagPicker, Combobox, HMInput,
                      GroupedEntryList, GoalsSummary, RangePicker, ColorDot
  src/pages/         TimeTracker, Dashboard, Reports, Calendar, Projects, Tags,
                      TimeEntries, Team, Clients, Settings (with sub-pages:
                      General, Features, WorkHours, Scheduler, DataManagement)
  src/utils/         date, range, format, colors, featurePrefs, sidebarPrefs,
                      goalPeriodPrefs, timerStart

API reference

All endpoints are under /api/v1.

Resource Endpoints
Workspaces GET /workspaces, GET /workspaces/current
Projects GET /projects, GET /projects/:id, POST /projects, PATCH /projects/:id, POST /projects/:id/archive
Activities (tasks) GET /activities, POST /activities, PATCH /activities/:id, POST /activities/:id/archive
Tags GET /tags, POST /tags, PATCH /tags/:id, DELETE /tags/:id
Time entries GET /time-entries, GET /time-entries/running, POST /time-entries/start, POST /time-entries/:id/stop, POST /time-entries, PATCH /time-entries/:id, DELETE /time-entries/:id
Reports GET /reports/summary, GET /reports/analytics, GET /reports/by-project, GET /reports/by-activity, GET /reports/export.csv, GET /reports/export.html, GET /reports/export.pdf
Goals GET /goals/status, GET /goals/caps, PUT /goals/caps, GET /goals/:period, PUT /goals/:period/overall, DELETE /goals/:period/overall, PUT /goals/:period/project/:projectId, DELETE /goals/:period/project/:projectId (:period is daily, weekly, monthly, or yearly)
Work hours GET /work-hours, PUT /work-hours
Scheduler GET /schedule, POST /schedule, PATCH /schedule/:id, DELETE /schedule/:id, GET /schedule/today, GET /schedule/settings, PUT /schedule/settings
Saved views GET /saved-views, POST /saved-views, DELETE /saved-views/:id
Imports POST /imports/clockify, POST /imports/temporal-loom, POST /imports/settings
Exports GET /exports/json, GET /exports/clockify.csv, GET /exports/settings.json

Backup file versions

  • Schema v1: the original whole workspace export, from before goals and daily caps existed. It still imports correctly.
  • Schema v2: added goals, caps, and saved views.
  • Schema v3 (current): added Work Hours and the Scheduler.
  • The app settings export has its own separate version number, currently v2.

Contributors

Languages