Know when you live to code, and when you don't.
Privacy-first GitHub activity analytics for the web, GitHub Actions, and the command line. Code Life Balance turns recent activity into commit timing, active hours, language distribution, repository insights, and a scored code-life balance report without requiring users to hand credentials to CodeLifeBalance.
Built with Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS v4, shadcn/ui, and Recharts.
Repository: https://github.com/alihd-tech/CodeLifeBalance
- Privacy-first GitHub Action. Runs inside the user's GitHub Actions runner and generates SVG, JSON, and Markdown without sending the token or report to CodeLifeBalance.
- Local CLI. Uses
GITHUB_TOKENor an existinggh authsession and writes the same artifacts locally. - Workflow configurator. The
/configurepage generates workflow YAML and the equivalent CLI command entirely in the browser. - Public username viewer. Public activity remains available without authorization.
- Optional GitHub App. Adds installation-scoped repository access, signed realtime webhooks, organization/team discovery, and opt-in persistent event history.
- Legacy hosted OAuth dashboard. Still available during the migration, but no longer the primary path.
- Balance score (0 to 100). Derived from weekend, after-hours, late-night, and commit-volume patterns, with actionable recommendations.
- Commit timing analysis. Hour-of-day and day-of-week distributions, peak hour and day, plus five named time sessions (Early Bird, Morning, Afternoon, Evening, Night Owl).
- Language breakdown. Primary-language distribution across your owned repositories.
- Top repositories. Ranked by stars, with forks and language.
- Event breakdown. Pushes, pull requests, issues, reviews, releases, and more.
- Streaks and totals. Current streak, longest streak, total stars and forks, average commits per day.
- Light and dark themes. A light, dark, and system toggle in the header, persisted in
localStorageand applied before first paint so there is no flash.
The recommended mode runs on GitHub's runner and keeps credentials in GitHub.
name: Code Life Balance
on:
workflow_dispatch:
schedule:
- cron: "17 3 * * 1"
permissions:
contents: write
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: alihd-tech/CodeLifeBalance@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
username: ${{ github.repository_owner }}
timezone: "UTC"
workday-start: "9"
workday-end: "18"
theme: "dark"
card-style: "detailed"
formats: "svg,json,markdown"
output-dir: "code-life-balance"
commit: "true"For private owned repositories, create a user-owned fine-grained token with only the read access you want, store it as CODE_LIFE_TOKEN, pass that secret as github-token, and set include-private: "true". Private mode verifies that the token owner matches the username being analyzed.
Once the npm package is published, run without installing:
npx code-life-balance --username octocat --timezone Europe/HelsinkiUntil the npm registry package is published, the web configurator uses the dependency-free CLI tarball attached to the stable GitHub release so its generated local command can run without cloning this repository. Repository contributors can still use pnpm cli --.
Authenticate with GitHub CLI:
gh auth loginThen run the current stable CLI release directly:
npx --yes https://github.com/alihd-tech/CodeLifeBalance/releases/download/v1.2.0/code-life-balance-1.2.0.tgz --username octocat --timezone Europe/HelsinkiPrivate mode stays on the local machine:
npx --yes https://github.com/alihd-tech/CodeLifeBalance/releases/download/v1.2.0/code-life-balance-1.2.0.tgz --include-private --timezone Europe/HelsinkiThe CLI prefers GITHUB_TOKEN, then gh auth token. Public analysis can run without credentials when a username is supplied.
Open /configure in the web app to choose timezone, work hours, theme, card style, output formats, and private/public mode. The generated GitHub Actions workflow is manual (workflow_dispatch) and the page does not request a GitHub token.
app/
page.tsx Landing page
dashboard/page.tsx Legacy hosted authenticated dashboard
configure/page.tsx Privacy-first Action and CLI configurator
integrations/github/page.tsx Optional GitHub App control center
privacy/page.tsx Product privacy model
support/page.tsx Support and security guidance
u/[username]/page.tsx Public username viewer
layout.tsx Fonts, metadata, Vercel Analytics (production only)
api/
auth/route.ts Redirects to the GitHub OAuth authorize URL
auth/callback/route.ts Exchanges the code for a token, stores it in the session
auth/logout/route.ts Destroys the session
analyze/route.ts Authenticated JSON endpoint returning the full analysis
github-app/* Optional App install, callback, webhook, status, and history routes
opengraph-image.tsx Generated 1200x630 social card
robots.ts, sitemap.ts Crawler directives and sitemap
manifest.ts Web app manifest
components/
dashboard-client.tsx Client component; fetches /api/analyze with SWR
*.tsx Individual charts and panels
ui/ shadcn/ui primitives
lib/
github.ts GitHub API transport; delegates calculations to the shared core
github-app.ts GitHub App JWT, install-token, OAuth verification, and API helpers
github-app-history.ts Opt-in minimal webhook history store
session.ts iron-session configuration and types
site.ts Canonical URL, authorship and SEO copy
theme.ts Theme storage key and the pre-paint init script
packages/
core/index.mjs Provider-agnostic analytics engine shared by every surface
github-client/index.mjs Reusable GitHub REST transport for Action and CLI
report/index.mjs Shared SVG, JSON, and Markdown report rendering
action/
index.mjs Dependency-free GitHub Action runtime
cli/
index.mjs Local privacy-first command line interface
action.yml GitHub Action metadata and inputs
The analytics engine in packages/core/index.mjs is provider-agnostic. The GitHub Action and CLI share packages/github-client for GitHub REST access and packages/report for SVG, JSON, and Markdown generation. The public and legacy hosted web views reuse the same core through lib/github.ts. The recommended private path never goes through the Next.js server.
Data sources and limits. Repositories come from GET /user/repos (owner affiliation, up to 5 pages). Activity comes from GET /users/{username}/events (up to 3 pages). The GitHub Events API only exposes roughly the last 90 days and 300 events, so all commit-timing metrics describe recent activity rather than your full history. The shared analytics core buckets timestamps in an explicit IANA timezone. The web app currently defaults to UTC; the Action exposes a timezone input.
- Node.js 20 or newer
- pnpm (a
pnpm-lock.yamlis committed)
A GitHub OAuth App is required only for the legacy hosted dashboard. A GitHub App is required only for the optional advanced integration. The Action, CLI, configurator, and public viewer do not require either.
git clone https://github.com/alihd-tech/CodeLifeBalance.gitCopy .env.example to .env.local and set only the hosted features you need.
SESSION_SECRET=a_random_string_of_at_least_32_characters
NEXT_PUBLIC_SITE_URL=http://localhost:3000For the legacy OAuth dashboard, additionally configure GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET.
For the optional GitHub App, follow docs/github-app.md and configure the App ID, client ID, client secret, private key, webhook secret, and slug.
SESSION_SECRET is mandatory for production hosted sessions. Production session creation fails closed when it is missing or too short.
Generate a session secret with:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"pnpm installpnpm devOpen http://localhost:3000 and click Analyze my GitHub.
| Command | Description |
|---|---|
pnpm dev |
Start the development server on port 3000. |
pnpm build |
Create a production build. |
pnpm start |
Serve the production build. |
pnpm lint |
Run ESLint. |
pnpm test:core |
Run provider-agnostic analytics engine tests. |
pnpm typecheck |
Run strict TypeScript validation. |
pnpm check |
Run tests, typecheck, and production build. |
pnpm cli -- --help |
Show local CLI options. |
pnpm build:npm-cli |
Build the dependency-free npm CLI package into dist/npm. |
pnpm test:npm-cli |
Build, execute, and dry-run-pack the npm CLI artifact. |
The app is a standard Next.js application and deploys to Vercel or any Node.js host without additional configuration.
- Push the repository to GitHub and import it into your hosting provider.
- Set
GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET, andSESSION_SECRETas environment variables. - Set
NEXT_PUBLIC_SITE_URLif the deployment is not on the canonical domain. - Update the OAuth App's Authorization callback URL to
https://your-domain.com/api/auth/callback.
Security headers (X-Content-Type-Options, Referrer-Policy, Strict-Transport-Security, Permissions-Policy) are applied to all routes in next.config.mjs. TypeScript errors fail the production build and the permanent CI workflow also runs tests, typecheck, build, and an Action self-test.
app/globals.css defines the light palette on :root and the dark palette on
both .dark and a prefers-color-scheme block, so the app follows the system
setting until the visitor picks a side. The header toggle writes light, dark,
or system to localStorage under clb-theme, and a small inline script in the
root layout applies it before first paint.
Contrast was checked against WCAG AA in both themes: body text is about 18:1, muted text about 7.7:1 in light and 8.7:1 in dark, and the primary green clears 4.5:1 both as text and behind button labels.
Code Life Balance now has distinct trust modes:
| Mode | Credential location | CodeLifeBalance receives token? | Private repository support |
|---|---|---|---|
| GitHub Action | GitHub Actions secret/runtime | No | Optional with user-owned fine-grained token |
| Local CLI | Local environment or gh auth |
No | Optional |
| Public viewer | None required | No | No |
| Optional GitHub App | Short-lived server-side App/user/installation tokens | Hosted App layer only | Yes, installation-scoped |
| Legacy hosted dashboard | Encrypted browser session cookie | Hosted app handles token | Yes |
The Action runtime calls GitHub's API directly and writes artifacts only into the workflow workspace. The local CLI does the same on the user's machine. The configurator never asks for credentials.
The optional GitHub App verifies webhook HMAC signatures and verifies installation ownership with a short-lived GitHub App user token before linking an installation. Installation access tokens are created only when needed and are not persisted. Minimal webhook history is opt-in through GITHUB_APP_HISTORY_PATH.
The legacy OAuth flow is retained during migration and still requests the broad repo scope. It should not be treated as the preferred privacy-first path.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router), React 19 |
| Language | TypeScript 5.7 |
| Styling | Tailwind CSS v4, tw-animate-css |
| Components | shadcn/ui, Base UI, Radix icons, Lucide |
| Charts | Recharts 3 |
| Data fetching | SWR |
| Sessions | iron-session |
Contributions are welcome. To propose a change:
- Fork the repository and create a branch from
main. - Run
pnpm lintandpnpm buildbefore opening a pull request. - Keep pull requests focused, and describe the user-visible effect of the change.
For bugs and feature ideas, open an issue at https://github.com/alihd-tech/CodeLifeBalance/issues.
Released under the MIT License. See LICENSE for details.