Skip to content

roastcodes/ttdash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

416 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

TTDash

CI npm License Node >=20

TTDash is a local-first dashboard and CLI for toktrack usage data. It runs entirely on your machine, turns raw usage exports into charts and operational summaries, and keeps your stored data, settings, and imports on local disk instead of a hosted backend.

TTDash is built around the usage data provided by toktrack. Thanks to mag123c for creating and maintaining the data source this dashboard builds on.

Keep Claude Code History

Claude Code cleans up old sessions after 30 days by default. If you want long-term cost history in toktrack and TTDash, raise or effectively disable that cleanup in ~/.claude/settings.json:

{
  "cleanupPeriodDays": 9999999999
}

TTDash dashboard screenshot

Why TTDash

  • Local-first by default: no cloud backend, no remote database, no analytics
  • Fast to try: npx and bunx work without a global install
  • Built for daily usage review, cost tracking, and model/provider breakdowns
  • Works with toktrack exports and legacy ccusage JSON
  • Can auto-import local toktrack data and run in the background

Dashboard At A Glance

Deeper cost and model analysis:

TTDash analytics screenshot

Settings, local backups, and saved defaults:

TTDash settings screenshot

Quick Start

Requirements:

  • Node.js 20+
  • A modern browser on the same machine
  • Typst CLI only if you want PDF export

Run TTDash directly from the npm registry:

npx --yes @roastcodes/ttdash@latest

Or with Bun:

bunx @roastcodes/ttdash@latest

Smoke-check the published CLI without starting the dashboard:

npx --yes @roastcodes/ttdash@latest --help
bunx @roastcodes/ttdash@latest --help

For a persistent global install:

npm install -g @roastcodes/ttdash
ttdash
bun add -g @roastcodes/ttdash
ttdash

First Run

Start the app:

ttdash

TTDash starts a local server, opens the dashboard in your browser, and automatically retries on the next free port if 3000 is already in use.

Then either:

  1. Click Auto-Import to load local toktrack data
  2. Upload a toktrack JSON file manually
  3. Upload a legacy ccusage export
  4. Open Settings to export or import local backups

The auto-import path prefers:

  1. local toktrack
  2. bunx with the exact toktrack package spec pinned by this TTDash release
  3. npx --yes with the exact toktrack package spec pinned by this TTDash release

Common Commands

Quick examples:

Run on a specific port:

ttdash --port 3010

Disable browser auto-open:

ttdash --no-open

Import local data immediately on startup:

ttdash --auto-load

Start in the background:

ttdash --background

Stop a running background instance:

ttdash stop

Combine flags when needed:

ttdash --background --port 3010 --auto-load
ttdash --background --no-open

Environment-variable equivalents:

PORT=3010 ttdash
NO_OPEN_BROWSER=1 ttdash
HOST=127.0.0.1 ttdash

CLI Reference

Usage:

ttdash [options]
ttdash stop

Options:

Option Description
-p, --port <port> Set the start port
-h, --help Show CLI help
-no, --no-open Disable browser auto-open
-al, --auto-load Run local auto-import immediately on startup
-b, --background Start TTDash as a background process

Commands:

Command Description
ttdash stop Stop one or more running background instances. If multiple instances are running, TTDash prompts for which one to stop.

Environment variables:

Variable Description
PORT Override the start port
NO_OPEN_BROWSER=1 Disable browser auto-open
HOST Override the bind host
TTDASH_ALLOW_REMOTE=1 Explicitly allow binding to a non-loopback host
TTDASH_REMOTE_TOKEN=<long-random-token> Required for non-loopback binds; use at least 24 chars

Binding to a non-loopback host such as 0.0.0.0 exposes the local dashboard API to your network, including destructive routes for local data and settings resets. TTDash refuses that bind unless you set both TTDASH_ALLOW_REMOTE=1 and a TTDASH_REMOTE_TOKEN with at least 24 characters. Only use remote token access over a trusted LAN, VPN, or SSH tunnel; for any public hostname, put TTDash behind an HTTPS reverse proxy with valid TLS termination before sending the bearer token.

Example:

TTDASH_ALLOW_REMOTE=1 TTDASH_REMOTE_TOKEN=<long-random-token> HOST=0.0.0.0 ttdash
curl -H "Authorization: Bearer $TTDASH_REMOTE_TOKEN" http://127.0.0.1:3000/api/usage

When calling the server from another device, replace 127.0.0.1 with the server's LAN, VPN, or SSH-tunneled host. For public hostnames, call an HTTPS reverse proxy URL instead; do not send the bearer token over public HTTP.

Remote API requests can authenticate with the Authorization: Bearer $TTDASH_REMOTE_TOKEN header or the equivalent X-TTDash-Remote-Token: $TTDASH_REMOTE_TOKEN header.

Features

  • Provider and model filtering across OpenAI, Anthropic, Google, and other imported providers
  • KPI sections for overall usage, today, and current month
  • Cost charts, cumulative projection, forecast, token mix, model mix, heatmap, and weekday analysis
  • Drill-down modal for per-day details
  • CSV export and PDF export
  • Command palette, keyboard shortcuts, and responsive layout
  • Settings-backed defaults, section visibility, and local backups

Local Storage and Privacy

TTDash is designed to stay local:

  • No cloud backend
  • No remote database
  • No third-party fonts, analytics, or runtime tracking
  • Imported usage data is stored on your machine
  • Settings such as language, theme, provider limits, filters, and layout are stored on your machine

Platform paths:

  • macOS: ~/Library/Application Support/TTDash/
  • Windows: %LOCALAPPDATA%\\TTDash\\ for data and %APPDATA%\\TTDash\\ for settings
  • Linux: ~/.local/share/ttdash/ for data and ~/.config/ttdash/ for settings

Backups

The Settings dialog can export and import:

  • app settings backups
  • stored usage data backups

Data-backup import is conservative by design:

  • missing days are added
  • identical days are skipped
  • conflicting existing days stay local and are reported instead of being overwritten silently

If you want to fully replace the current dataset with a fresh toktrack JSON, keep using the normal upload action in the header.

Troubleshooting

ttdash not found after install

Make sure your global package manager bin directory is in PATH.

For Bun:

echo $PATH
ls -la ~/.bun/bin/ttdash

Port already in use

TTDash automatically retries on the next port. You can also force one:

PORT=3010 ttdash

Auto-import cannot find toktrack

Install toktrack locally or ensure bunx / npx can execute it in the same terminal environment where you run ttdash.

PDF export fails

PDF export requires the Typst CLI to be installed locally.

macOS:

brew install typst

Other platforms:

  • install Typst from https://typst.app/
  • make sure typst --version works in the same terminal where you run ttdash

Installation From Source

Clone the repository and install locally:

macOS / Linux:

sh install.sh
ttdash

Windows:

install.bat
ttdash

Manual source install:

npm install
npm run build
npm install -g .
ttdash

Or with Bun:

bun install
bun run build
bun add -g "file:$(pwd)"
ttdash

Development

Run the app locally from the repo:

npm install
npm run dev
node server.js
  • Vite dev server: http://localhost:5173
  • API / production server: http://localhost:3000

Build the production bundle:

npm run build

npm run build is the gated build and runs format:check and lint before bundling. If you only want the Vite production bundle, use:

npm run build:app

Run the main local gate without Playwright:

npm run verify

For the full serial CI/release-style local gate, including coverage thresholds and Playwright, use:

npm run verify:full

On a local machine with enough CPU, the staged parallel fast path gives quicker feedback across the same main test surfaces without the coverage-instrumented pass:

PLAYWRIGHT_TEST_PORT=3016 npm run verify:full:parallel

Keep npm run verify:full or npm run test:vitest:coverage in the final validation path whenever coverage thresholds matter.

If you want to run the steps individually, use:

npm run check:deps
npm run test:architecture
npm run test:unit:coverage
npm run test:e2e:ci

To inspect the slowest suites and test cases after a Vitest run:

npm run test:timings

The Playwright suite starts an isolated local app per worker under .tmp-playwright/workers/. For stable Playwright-only validation from another base port, use the CI-style worker cap:

PLAYWRIGHT_TEST_PORT=3016 npm run test:e2e:ci

Use npm run test:e2e when you intentionally want the fresh app build plus the default local worker count.

Refresh the README screenshots:

npm run docs:screenshots

Release and Project Docs

Status

GitHub Actions now runs formatting checks, ESLint, tsc --noEmit, unit/integration coverage, the production bundle, packaged-artifact verification, and Playwright smoke tests for pull requests and pushes to main.

License

MIT. See LICENSE.