1---
2title: Overview
3description: One layer graph, provided once, builds the Worker and every Durable Object behind it. Each line is a decision with implementations you choose or write.
4---
5
6The examples use `Authentication` from
7[Getting Started](/git/getting-started): the application's request middleware.
8
9A git host is six decisions: what serves HTTP and who may call it,
10where refs and objects live, how names resolve, where bulk bytes go,
11what verifies a push, and which refs may move. Each is a
12[Layer](/infrastructure-as-effects/layers), and you make them in one
13graph:
14
15```typescript
16const GitLive = Git.ApiLive.pipe(
17 Layer.provide(Git.ApiHandlersLive),
18 Layer.provide(Authentication.layer),
19 Layer.provide(Git.ReposDurableObject),
20 Layer.provide(Git.RegistryDurableObject),
21 Layer.provide(Git.HasherInline),
22 Layer.provide(Git.BlobStoreR2(GitObjects)),
23);
24```
25
26One graph, one `Effect.provide`. Build it with `Layer.*` and provide it
27once.
28
29## Two runtimes, one graph
30
31A repository needs one place where a ref moves atomically. On
32Cloudflare that is a Durable Object, and the code that moves refs runs
33inside it. The graph does not know this. You write it once, the Worker
34builds its side of it at cold start, and each Durable Object builds its
35own on its first request:
36
37```
38 GitLive
39 ┌─────────────┴──────────────┐
40 Worker Repo Durable Object
41 wire, REST, GitHub facade refs, objects, pull requests
42 your middleware and policies push commit, jobs
43 BlobStore: clone bundles BlobStore: packs, spilled pushes
44```
45
46`Git.BlobStoreR2(GitObjects)` appears once and serves both sides: the
47Worker streaming a clone bundle and the Durable Object writing a pack.
48Your middleware and application policies run in the Worker request. They can
49use the same user and database services.
50
51## The blocks
52
53| Block | Decides | Ships with |
54| --- | --- | --- |
55| [HTTP routes](/git/blocks/server) | the HTTP surface: every plane as one `HttpApi` of routes you can replace, behind your middleware | `ApiHandlersLive`, `ApiLive`, `InternalApiLive` |
56| [Repository](/git/blocks/repositories) | where refs and objects live, the jobs that keep a repository small | `ReposDurableObject` |
57| [Registry](/git/blocks/registry) | how `owner/name` resolves, and listings | `RegistryDurableObject`, `RegistryD1` |
58| [Blob Store](/git/blocks/blob-store) | where packs, bundles, and large pushes go | `BlobStoreR2`, `BlobStoreS3` |
59| [Hasher](/git/blocks/hasher) | what verifies a push, and on which compute | `HasherInline`, `HasherWorkerLoader`, `HasherLambda` |
60| [Engine](/git/blocks/engine) | repository operations and scoped prepare/commit | `EngineLive` |
61| [Auth](/git/blocks/auth) | application middleware and policy functions | native Effect HTTP middleware |
62
63## Replacing a block
64
65Every block is a `Context.Service`. Swap the Layer and nothing else in
66the graph knows:
67
68```diff lang="typescript"
69const GitLive = Git.ApiLive.pipe(
70 Layer.provide(Git.ApiHandlersLive),
71 Layer.provide(Authentication.layer),
72 Layer.provide(Git.ReposDurableObject),
73- Layer.provide(Git.RegistryDurableObject),
74+ Layer.provide(Git.RegistryD1(RepoIndex)),
75 Layer.provide(Git.HasherInline),
76 Layer.provide(Git.BlobStoreR2(GitObjects)),
77);
78```
79
80Leave one out and the Worker does not compile. The graph still requires
81the service, and the compiler says which:
82
83```typescript
84const GitLive = Git.ApiLive.pipe(
85 Layer.provide(Git.ApiHandlersLive),
86 Layer.provide(Authentication.layer),
87 Layer.provide(Git.ReposDurableObject),
88 Layer.provide(Git.RegistryDurableObject),
89 Layer.provide(Git.HasherInline),
90);
91// Layer<Server, never, BlobStore>
92// ^ still required; providing it to the Worker is a type error
93```
94
95Writing your own is implementing the contract. Each block's page shows
96it, and the shape is always the same:
97
98```typescript
99const BlobStoreMine = Layer.effect(
100 Git.BlobStore,
101 Effect.gen(function* () {
102 // return a Git.BlobStoreShape
103 }),
104);
105```
106
107## Where next
108
109- [HTTP routes](/git/blocks/server) — the three planes as one `HttpApi`,
110 and replacing a route.
111- [Recipes](/git/recipes) — which lines change for which
112 requirements.