Hi! We're really excited that you're interested in contributing to Gitify!
Before submitting your contribution, please read through the following guide.
We also suggest you read the Project Philosophy in our documentation.
Tip
Optional: If you prefer to use your own OAuth credentials, you can do so by passing them as environment variables when bundling the app. This is optional as the app has some default "development" keys (use at your own discretion).
OAUTH_CLIENT_ID="123" pnpm buildTo get started:
Clone the repository and install dependencies:
pnpm installCopy the .env.template to .env and add update GITHUB_TOKEN with a GitHub Personal Access Token. This is used for fetching the latest GitHub GraphQL API schema for graphql-codegen.
GITHUB_TOKEN=<some personal access token>Start development mode (includes GraphQL codegen and hot module reload):
pnpm devTooling is unified through Vite+, which bundles the linter (oxlint), formatter (oxfmt), test runner (Vitest), and dev/build pipeline (Vite).
# Run lint, format, and type checks
pnpm check
# Auto-fix formatting and lint issues
pnpm check:fix
# Run unit tests with coverage
pnpm test
# Update vitest snapshots
pnpm test -upnpm test covers the DOM snapshots. Pixel-level regressions (colour tokens,
spacing, theme changes) are covered separately by a browser-mode project that
screenshots every route across the light, dark, accessibility, and Glass themes.
Screenshots only match when the browser build and font stack are identical, so both commands below run the suite inside a pinned Playwright container, and CI verifies against that same container. You do not need to install Playwright's browsers locally.
# Verify against the committed baselines
pnpm test:visual
# Regenerate them after an intentional UI change
pnpm test:visual:updateBoth need Docker on an arm64 host, because Chromium crashes under amd64
emulation on Apple Silicon. On any other machine, push the branch and read the
diff from the Visual Regression job's visual-regression-diffs artifact.
Do not invoke the browser [visual] project through vitest directly. Vitest
namespaces baselines per platform and creates missing ones automatically, so a
bare run on macOS writes a fresh set from your working tree and then passes
against it — reporting green even on a branch that has a real regression. A
guard fails the run outside Linux rather than letting that happen.
Note that these baselines capture the backdrop-filter fallback for Glass, not
the macOS native vibrancy material, which Chromium cannot render.
- Linting and formatting are configured in
vite.config.mts(thelintandfmtblocks). Please runpnpm checkbefore submitting a PR. - Follow existing file and folder naming conventions.
- Keep commit messages clear and descriptive.
If you encounter a bug or have a feature request, please open an issue with clear steps to reproduce or a detailed description of your idea. Check for existing issues before creating a new one.
Releases are automated with release-please. There is no release branch and no manual version bump.
- Merge changes into
main. Use Conventional Commits for PR titles (feat:,fix:,docs:,chore(deps):, ...). The commit type decides the version bump and the changelog section it lands in. - Review the release PR. release-please keeps an open
chore: release X.Y.Zpull request up to date as commits land. It bumps the version inpackage.json, regeneratesCHANGELOG.md, and updatessonar.projectVersioninsonar-project.properties. Check the Renovate Dependency Dashboard for any dependency updates you want to include first. - Merge the release PR when you are ready to ship. Merging is the "go" decision. GitHub Actions then automatically:
- builds, signs, and notarizes the app on macOS, Windows, and Linux,
- attaches the assets to the release that release-please drafted, and
- publishes the release (creating the
vX.Y.Ztag), which redeploys the website and triggers the automatic Homebrew cask bump (workflow runs ~3 hours).
- Milestones and notifications are automated.
- An open Milestone titled
Release X.Y.Zis kept in step with the release-please version, and merged pull requests are attached to it as they land. - When the release is published, the milestone is finalized: its description becomes the release URL, its due date is set to the release date, and it is closed.
- A separate job comments once on every pull request included in the release, linking contributors to the release page. Re-runs are idempotent and never post duplicate comments.
No manual milestone creation, renaming, or closing is required.
- Packaging and publication use
contents: write. - The milestone automation uses
issues: write. - Pull request notification uses
issues: write,pull-requests: write, andcontents: read. - The validation jobs (
lint,tests) remain read-only.
- Use sentence case where possible
- Use GitHub's Octicons for iconography
This project is a tool for monitoring new notifications from supported Git forges. It's not meant to be a full-featured forge client. We want to keep it simple and focused on that core functionality. We're happy to accept contributions that help us achieve that goal, but we're also happy to say no to things that don't. We're not trying to be everything to everyone.
Gitify supports notifications from multiple Git forges. New forges may be added under the following conditions:
- Adapter-based: the forge is implemented behind the
ForgeAdapterinterface insrc/renderer/utils/forges/. No forge-specific branching outside the adapter module. - Designated maintainer: every forge has at least one named maintainer in
MAINTAINERS.mdwho owns triage and CI for that adapter. - Capability-honest UI: features unsupported by a forge (e.g. mark-as-done) must hide gracefully, not silently no-op.
- No core-platform churn: Octicons, Octokit, and the Primer Design System remain in place. Octokit is scoped to the GitHub adapter; other adapters use plain
fetch.
Currently supported forges: GitHub (Cloud, Enterprise Server, Enterprise Cloud with Data Residency), Gitea (incl. Forgejo, Codeberg), Bitbucket Cloud and GitLab (Cloud and Self-Managed).
- Operating-system level features
- Do not disturb, including on schedules. #416 (comment)
- Persistent notifications like #281. e.g. macOS has Alerts, instead of Banners, which makes them persistent
- Seeing past notifications. This is a tool for monitoring new notifications, not seeing old ones, which can be seen at https://github.com/notifications.
- Specific UX/UI changes that add options and/or visual complexity for minor workflow improvements. e.g. #358, #411 and #979
- UI for something that isn't core to Gitify, and/or can be trivially done another way. e.g. #476 and #221
- Add a forge adapter without a designated maintainer who will own it long-term.