Skip to content

Latest commit

 

History

History
133 lines (97 loc) · 4.7 KB

File metadata and controls

133 lines (97 loc) · 4.7 KB

Contributing to YT Zero

Thanks for your interest in improving ytzero! This is a personal, self-hosted project, so contributions are welcome but kept lightweight. Please read this guide before opening an issue or pull request.

Ways to contribute

  • Report bugs — open an issue with steps to reproduce, what you expected, and what happened.
  • Suggest features — open an issue describing the use case and why it would be useful.
  • Submit code — fix a bug or implement an agreed-upon feature via a pull request (see below).

For anything non-trivial, please open an issue first so we can agree on the approach before you spend time on a PR.

Project layout

app/      # Backend — Hono on Bun, TypeScript (runtime, no build step)
ui/       # Frontend — React + Vite + TypeScript
scripts/  # setup / dev / build / start helpers
data/     # Local runtime data (SQLite + image cache), gitignored

The backend is TypeScript executed directly by Bun. The frontend is built with Vite, and in production the backend serves the static files from ui/dist.

Prerequisites

  • Bun (the only required toolchain — no Node.js needed)
  • Optionally Docker, if you want to test the container build

Getting started

# Install dependencies for both app/ and ui/
bun run setup

# Run backend (:3001) and frontend (:5173) together with hot reload
bun run dev

You can also run the halves separately with bun run dev:app and bun run dev:ui.

To test a production-like build locally:

bun run build   # builds ui/dist
bun run start   # backend serves ui/dist on :3001

Before you open a PR

Run the same checks CI runs, so nothing breaks after merge:

# Type-check both packages
cd app && bunx tsc --noEmit
cd ../ui && bunx tsc --noEmit

# Build the frontend
bun run build

Both packages use strict TypeScript — please keep the build type-clean.

Database schema changes

The files in CANONICAL_SCHEMA_FILES in app/src/databaseMigrations.ts describe the current schema for new installations. Any change to one must add the next versioned entry to app/src/databaseMigrations.ts, with explicit sqlite and postgres implementations and updated schema fingerprints. Never add a new one-off startup migration to db.ts.

Run bun run check:database-migrations after changing the schema. The same check is part of check:validate and CI, and rejects schema changes that do not include migration paths for both supported database engines.

Pull request workflow

main is protected. All changes go through a pull request:

  1. Branch off main (e.g. fix/live-detection, feat/playlist-import).
  2. Make your change and keep commits focused.
  3. Make sure type-checks and the build pass locally.
  4. Open a PR against main with a clear description of what and why.

Notes:

  • PRs are squash-merged, so the final commit on main is your PR title and description. A clean per-commit history on your branch is appreciated but not required — it gets squashed anyway.
  • History on main is linear; force-pushes and direct pushes to main are blocked.

Release versioning

YT Zero product releases use calendar versions in the form YYYY.MM.N, and the Git tag is the version itself without a v prefix. The month is always zero-padded (01 through 12), while N is a positive, non-padded release counter that starts at 1 each month. For example, the first two releases in August 2026 are 2026.08.1 and 2026.08.2; the first September release is 2026.09.1.

Pushing a valid release tag builds the GitHub release assets and publishes container tags for the exact release, its month and year channels, and latest (for example 2026.08.1, 2026.08, 2026, and latest). The private app/package.json and ui/package.json versions are package-manager metadata and are intentionally independent from the product release tag.

Coding style

  • Match the surrounding code — naming, structure, and comment density.
  • Keep changes scoped; avoid unrelated refactors in the same PR.
  • User-facing UI text is translated via ui/src/i18n.tsx. When you add new copy, provide a string for every language defined there (the Language type lists the currently supported locales) so no language falls back to a missing key.
  • Use icons from lucide-react rather than emoji in the UI.

License

By contributing, you agree that your contributions are licensed under the project's GNU Affero General Public License v3.0 only (AGPL-3.0-only), the same license as the rest of the project. See the full text in LICENSE.