<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
	<title>PyGitWeb</title>
	<meta name="description" content="Self-host git repositories with boards, tasks, Smart HTTP, and metadata stored in your repo. A Python forge built with FastAPI and Tabler.">
	<script>
		document.documentElement.setAttribute(
			"data-bs-theme",
			window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
		);
		window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", function (e) {
			document.documentElement.setAttribute("data-bs-theme", e.matches ? "dark" : "light");
		});
	</script>
	<link rel="preconnect" href="https://fonts.googleapis.com">
	<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
	<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
	<link rel="stylesheet" href="tabler.min.css">
	<link rel="stylesheet" href="main.css">
	<link rel="stylesheet" href="landing.css">
	<link rel="icon" href="logo.svg" type="image/svg+xml">
	<style>
		:root {
			--tblr-font-sans-serif: "Fira Sans", system-ui, sans-serif;
			--tblr-font-monospace: "Fira Code", ui-monospace, monospace;
			--tblr-primary: var(--pgw-theme-slate, #66717e);
			--tblr-primary-fg: #fff;
			--tblr-link-color: var(--pgw-link);
			--tblr-link-hover-color: var(--pgw-link-hover);
			--tblr-body-bg: var(--pgw-bg);
			--tblr-body-color: var(--pgw-text);
			--tblr-bg-surface: var(--pgw-bg-raised);
			--tblr-bg-surface-secondary: var(--pgw-bg-muted);
			--tblr-border-color: var(--pgw-border);
			--tblr-secondary: var(--pgw-text-muted);
		}
	</style>
</head>
<body class="landing">
	<a class="skip-link" href="#main">Skip to content</a>

	<header class="navbar navbar-expand-md sticky-top landing-nav">
		<div class="container-xl">
			<a class="navbar-brand navbar-brand-autodark d-flex align-items-center" href="/">
				<img src="logo.svg" width="32" height="32" alt="" class="navbar-brand-image">
				<span class="ms-2">PyGitWeb</span>
			</a>
			<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#landing-nav" aria-controls="landing-nav" aria-expanded="false" aria-label="Toggle navigation">
				<span class="navbar-toggler-icon"></span>
			</button>
			<div class="collapse navbar-collapse" id="landing-nav">
				<ul class="navbar-nav ms-auto">
					<li class="nav-item">
						<a class="nav-link" href="#features">Features</a>
					</li>
					<li class="nav-item">
						<a class="nav-link" href="#apart">Why</a>
					</li>
					<li class="nav-item">
						<a class="nav-link" href="#start">Get started</a>
					</li>
				</ul>
				<div class="nav-item ms-md-3 mt-2 mt-md-0">
					<a class="btn btn-primary" href="https://app.pygitweb.com">Open the demo</a>
				</div>
			</div>
		</div>
	</header>

	<header class="hero" aria-labelledby="site-title">
		<div class="hero__wash" aria-hidden="true"></div>
		<div class="container-xl hero__inner">
			<img src="logo.svg" alt="" width="128" height="128" class="hero__logo">
			<p class="hero__version text-secondary">v0.3.1</p>
			<h1 id="site-title" class="hero__title">PyGitWeb</h1>
			<p class="hero__tagline">Self-hosted project hosting with git as the database</p>
			<p class="hero__lede text-secondary">
				A FastAPI-based forge for small teams: repositories, sprint boards, tasks, Smart HTTP, and OAuth -
				with merge requests and metadata living in your object store.
			</p>
			<div class="hero__actions btn-list">
				<a class="btn btn-primary btn-lg" href="https://app.pygitweb.com">See it in action</a>
				<a class="btn btn-outline-secondary btn-lg" href="#start">Install with uv</a>
			</div>
		</div>
	</header>

	<main id="main">
		<section id="what" class="section section--muted">
			<div class="container-xl">
				<div class="row justify-content-center">
					<div class="col-lg-8 text-center">
						<h2 class="section__heading">What is PyGitWeb?</h2>
						<p class="text-secondary mb-0">
							Everything you need to self-host a code forge for individuals and small or medium-sized teams with OAuth2 or local-auth flows. 
							The UI follows <a href="https://docs.tabler.io/ui">Tabler</a>, the same kit used in the app itself.
						</p>
					</div>
				</div>
			</div>
		</section>

		<section id="features" class="section">
			<div class="container-xl">
				<div class="text-center mb-5">
					<h2 class="section__heading">Built for modern workflows</h2>
					<p class="text-secondary mb-0">Current through 0.3.x - boards, Smart HTTP, plugins, and a terminal companion.</p>
				</div>
				<div class="row g-4">
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 4m0 1a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1z" /><path d="M9 8v7" /><path d="M15 8v4" /></svg>
							</span>
							<h3 class="feature__title">Sprint boards &amp; tasks</h3>
							<p class="feature__desc text-secondary mb-0">Kanban boards with Fibonacci story points, board switching, archive and delete, plus task search by tag or commit.</p>
						</div>
					</div>
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 8l-4 4l4 4" /><path d="M17 8l4 4l-4 4" /><path d="M14 4l-4 16" /></svg>
							</span>
							<h3 class="feature__title">Smart HTTP</h3>
							<p class="feature__desc text-secondary mb-0">Clone and push over HTTP with scoped keys. Ref push rules cover branches, tags, and notes.</p>
						</div>
					</div>
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 3l8 4.5l0 9l-8 4.5l-8 -4.5l0 -9l8 -4.5" /><path d="M12 12l8 -4.5" /><path d="M12 12l0 9" /><path d="M12 12l-8 -4.5" /></svg>
							</span>
							<h3 class="feature__title">Metadata in git</h3>
							<p class="feature__desc text-secondary mb-0">Settings, merge requests, comments, and tasks live in the repository object database. Discover work with a fetch - no separate DB service.</p>
						</div>
					</div>
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M12 10m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" /><path d="M6.168 18.849a4 4 0 0 1 3.832 -2.849h4a4 4 0 0 1 3.834 2.855" /></svg>
							</span>
							<h3 class="feature__title">OAuth &amp; permissions</h3>
							<p class="feature__desc text-secondary mb-0">Sign in with an identity provider or local accounts. Project read gates visibility; write grants cover branches and arbitrary refs.</p>
						</div>
					</div>
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" /><path d="M13.5 6.5l4 4" /></svg>
							</span>
							<h3 class="feature__title">Plugins &amp; blogs</h3>
							<p class="feature__desc text-secondary mb-0">Enable or disable plugins from settings with protocol checks. Render a project's markdown blog with archive, search, and assets.</p>
						</div>
					</div>
					<div class="col-md-6 col-lg-4">
						<div class="feature">
							<span class="feature__icon" aria-hidden="true">
								<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M5 7l5 5l-5 5" /><path d="M12 19l7 0" /></svg>
							</span>
							<h3 class="feature__title">pgt terminal UI</h3>
							<p class="feature__desc text-secondary mb-0">Browse repos, stage and commit, switch worktrees, run project actions, and manage tasks from the CLI - no web server required.</p>
						</div>
					</div>
				</div>
			</div>
		</section>

		<section id="apart" class="section section--muted">
			<div class="container-xl">
				<div class="row justify-content-center">
					<div class="col-lg-8">
						<h2 class="section__heading text-center">What sets it apart?</h2>
						<blockquote class="pullquote">
							<p>All project metadata is stored in-situ; discovering new merge requests and tasks is just a git fetch.</p>
						</blockquote>
						<p class="text-secondary mb-0 text-center">
							PyGit2 powers the shared tooling package, so you can script workflows without bringing up the web server.
							An ABC-based plugin model lets you extend the stack when you need to.
						</p>
					</div>
				</div>
			</div>
		</section>

		<section id="start" class="section">
			<div class="container-xl">
				<div class="row justify-content-center">
					<div class="col-lg-8">
						<h2 class="section__heading text-center">Get started</h2>
						<p class="text-secondary text-center">
							Run with uv in bash or PowerShell. By default you get local auth and an <code>admin</code> account with a random password.
						</p>
						<pre class="install-snippet"><code>uv run --with pygitweb uvicorn pygitweb.main:app</code></pre>
						<p class="text-secondary text-center small mb-3">
							PGW uses Pydantic for configs: set <code>PYGITWEB_AUTH=0</code> if all connections are trusted.
						</p>
						<div class="text-center">
							<a class="btn btn-primary" href="https://app.pygitweb.com">Try the hosted demo</a>
						</div>
					</div>
				</div>
			</div>
		</section>

		<section id="audience" class="section section--muted">
			<div class="container-xl">
				<div class="row justify-content-center">
					<div class="col-lg-8 text-center">
						<h2 class="section__heading">Design Philosophy</h2>
						<p class="text-secondary mb-0">
							PyGitWeb is built for personal projects and small teams that want a place to host repos and organize tasks.
							Designed for light, efficient workflows - so you can stay focused on the work in the repo.
						</p>
					</div>
				</div>
			</div>
		</section>
	</main>

	<footer class="footer footer-transparent landing-footer">
		<div class="container-xl">
			<div class="row text-center align-items-center flex-row-reverse">
				<div class="col-lg-auto ms-lg-auto">
					<ul class="list-inline list-inline-dots mb-0">
						<li class="list-inline-item">
							<a href="https://app.pygitweb.com" class="link-secondary">Demo</a>
						</li>
						<li class="list-inline-item">
							<a href="https://docs.tabler.io/ui" class="link-secondary">Tabler UI</a>
						</li>
					</ul>
				</div>
				<div class="col-12 col-lg-auto mt-3 mt-lg-0">
					<p class="mb-0 text-secondary">
						PyGitWeb <code>© 2026 Will Bowers &amp; Contributors</code>
					</p>
				</div>
			</div>
		</div>
	</footer>

	<script defer src="tabler.min.js"></script>
</body>
</html>