Status: pre-1.0 (alpha / beta). Current version: see the
VERSIONfile. Data model, config keys, permission codes and routes may still change between minor versions; a1.0.0will mark the first stable release. Pin an exact version in production and read theCHANGELOGbefore updating. Not fit for critical or regulated use yet.
Self-hosted, project-based time tracking with a live timer, an auditable booking model (client, project, task, time entry) and built-in statistics and charts. Timeminator runs on ordinary PHP shared hosting (Apache + MySQL / MariaDB) and can also run locally with zero infrastructure using SQLite.
It was built to replace weak time-tracker plugins with something defensible:
every booking keeps its origin, the schema is prepared for auditable imports
with per-batch rollback (see import_batches in schema/*.sql), and the same
clean data set feeds several views (per project or client, a time series by
day / week / month, a generic two-group comparison, and a configurable "proof"
view with an optional cutover date). A CSV import UI is not yet part of this
edition — see #16.
- Login required, role-based permissions (admin, user, and any role you add).
- Live start / stop timer plus manual bookings.
- Statistics: hours per project and client, time series, two-group comparison, and a saved, fully generic "proof" view (no project is hardwired).
- Web installer, so anyone can set it up without touching the command line.
- Update check against GitHub Releases, with a guided in-app update.
- MySQL / MariaDB for hosting, SQLite for local use, one code base.
This is the Community Edition: it is free, open source (MIT) and fully usable on its own for time tracking, clients/projects/tasks and statistics. Timeminator Pro adds Soll/Budget planning with a live progress report, an offer/quote calculator with reusable building blocks and Typst output, invoicing with accounting connectors (lexoffice and more), and unlimited custom roles. It is a separate, privately licensed codebase built on the same data model, so you are never locked in.
Issues and pull requests on this Community Edition are welcome.
- PHP 8.1 or newer with PDO.
- One database driver enabled in PHP:
pdo_mysqlfor MySQL / MariaDB (recommended for hosting), orpdo_sqlitefor the local, zero-setup mode.
- Apache with
.htaccesssupport (the shipped rules protect the config and the data directory). Nginx works too, see "Nginx" below. - Write access to the
data/directory (for SQLite and update downloads) and to the application directory during setup (so the installer can writeconfig.php).
No Composer, no build step, no external PHP dependencies.
Pick one.
A. Release archive (recommended for non-developers)
- Go to the Releases page:
https://github.com/freshNfunky/Timeminator-Community/releases - Download the latest
timeminator-community-x.y.z.zip. - Unzip it into a folder on your web space, for example
timeminator/inside your document root.
B. Git clone (for developers)
git clone https://github.com/freshNfunky/Timeminator-Community.git
cd Timeminator-Community
The installer is a guided web wizard. You do not need shell access.
- Upload / place the files so the folder is reachable in the browser, for
example
https://public.felixschaller.com/timeminator/. - Open that URL. If no configuration exists yet, you are redirected to the
installer at
.../timeminator/install.php. - Step through the wizard:
- Requirements check. The installer verifies your PHP version, the PDO
drivers, and whether it can write
config.phpand thedata/directory. Anything missing is shown with a hint before you continue. - Database. Choose MySQL / MariaDB and enter host, database name, user and password, or choose SQLite for a local file database. The installer tests the connection before proceeding.
- Schema. The correct schema (
schema/mysql.sqlorschema/sqlite.sql) is applied, and the default roles and permissions are seeded. - Admin account. You create the first administrator (username, display name, password). The password is stored only as a bcrypt hash.
- Updates and registration (optional). You can opt in to update notifications. Registration is opt-in and off by default, see "Privacy".
- Requirements check. The installer verifies your PHP version, the PDO
drivers, and whether it can write
- The installer writes
config.php, then locks itself: once a configuration exists,install.phprefuses to run again. For safety you may deleteinstall.phpafter setup.
That is it. Log in at https://public.felixschaller.com/timeminator/ with the
admin account you just created.
If you prefer to set things up by hand:
- Copy
config.sample.phptoconfig.phpand edit the database section andtimezone. Setdb_drivertomysqlorsqlite. - Create the schema:
- MySQL:
mysql -u USER -p DBNAME < schema/mysql.sql - SQLite:
sqlite3 data/timeminator.sqlite < schema/sqlite.sql
- MySQL:
- Open the app in the browser. If no users exist yet, the installer will offer to create the first admin and seed roles and permissions.
Great for trying it out or for offline use on a laptop.
cp config.sample.php config.php # db_driver is already 'sqlite'
php -S localhost:8000
Open http://localhost:8000/, finish the short setup, and you are tracking
time. The database is a single file under data/.
Timeminator can keep itself current.
- An administrator sees an "update available" notice when a newer version is published on the configured release channel (GitHub Releases by default).
- The in-app updater downloads the release archive, keeps your
config.phpand yourdata/directory untouched, replaces the application files, and runs any pending database migrations. - You are always asked before anything is changed, and the current version is recorded so an update is reproducible.
The update check and download need outbound HTTPS from the server. If your
server has no outbound access, update manually: download the new release, copy
your config.php and data/ into it, and replace the old folder.
The current version is stored in the VERSION file.
- Passwords are hashed with PHP
password_hash(bcrypt). - All forms are protected with CSRF tokens, all queries use prepared statements, and output is escaped.
config.php, thedata/directory, and the schema files are denied to the web by the shipped.htaccess. Verify this on your host: requesting.../timeminator/config.phpmust not return its contents.- Serve the app over HTTPS and set
secure_cookiestotrueinconfig.php. - The session cookie name is configurable so it does not collide with other apps on the same domain.
There is no .htaccess on Nginx. Add location blocks that deny access to
config.php, the data/ directory, and *.sql / *.sqlite files, and route
requests to index.php. A sample is in docs/nginx.conf.sample (if present),
otherwise adapt the rules from .htaccess.
Timeminator can, on an opt-in basis, register an installation (contact email, site domain, and version) with the maintainer so you can be told about updates and security notices. This is off by default, it is asked for explicitly during setup, and it can be turned off at any time in the admin area. The endpoint it talks to is configurable, so you can point it at your own service or disable it entirely. No time-tracking data ever leaves your server.
The hierarchy is client, project, task, time entry. Grouping labels ("track"),
a per-project proof flag, and saved analysis views are generic attributes, so
the reporting works for any set of projects without hardcoding. Denormalized
project and client references on each entry keep history stable and make the
statistics fast. The schema reserves an evidence field and a batch_id on
each time entry so that a future CSV import can be rolled back as a whole
batch; no import UI ships in this edition yet.
Plain PHP 8, PDO, a tiny query-string router (works without mod_rewrite), server-rendered views, vanilla JavaScript, and a small built-in canvas chart renderer (no external chart library, no CDN, works fully offline). No framework, no Composer.
MIT. See LICENSE.
Bug reports and pull requests are welcome on GitHub. Please keep the "no build step, no Composer" constraint so the tool stays trivial to self-host.