1---
2title: Setup
3description: Connect alchemy to GitHub — account, credentials, and profiles.
4---
5
6Register the provider next to your cloud's:
7
8```typescript
9// alchemy.run.ts
10import * as GitHub from "alchemy/GitHub";
11
12providers: Layer.mergeAll(Cloudflare.providers(), GitHub.providers()),
13```
14
15Run `alchemy profile edit --add GitHub` and pick between two local options:
16
17- **`gh` CLI** — shells out to `gh auth token` (recommended).
18- **Stored PAT** — a personal access token entered interactively,
19 saved under `~/.alchemy/credentials/<profile>/`.
20
21When `CI=true`, profiles are bypassed and Alchemy reads
22`GITHUB_ACCESS_TOKEN` or `GITHUB_TOKEN` directly.
23
24See [Profiles](/environments/profiles) for how credentials are stored
25and switched.
26
27## GitHub Enterprise
28
29Both profile methods and CI environment credentials work against GitHub Enterprise Server and GitHub
30Enterprise Cloud with data residency. `alchemy profile edit
31re-configure GitHub` prompts for the host. Leave it blank for github.com, or enter your
32enterprise host (e.g. `github.example.com` or `acme.ghe.com`).
33
34The host is normalized into the REST API base URL automatically:
35
36- `github.example.com` → `https://github.example.com/api/v3` (GHES)
37- `acme.ghe.com` → `https://api.acme.ghe.com` (data residency)
38- an explicit URL like `https://github.example.com/api/v3` is used as-is
39
40Alternatively, set the host in the environment — `GITHUB_BASE_URL`,
41`GITHUB_API_URL` (set automatically on GitHub Actions runners), or
42`GH_HOST` — and every method picks it up without reconfiguring. On an
43enterprise host, CI environment resolution also honors the `gh`
44CLI's `GH_ENTERPRISE_TOKEN` / `GITHUB_ENTERPRISE_TOKEN` before falling
45back to `GITHUB_ACCESS_TOKEN` / `GITHUB_TOKEN`, and the `gh` CLI method
46runs `gh auth token --hostname <host>` (run
47`gh auth login --hostname <host>` once first).
48
49### Pin the host in code
50
51To fix the host for the whole app — independent of profile
52configuration or the environment — pass it to `providers()`:
53
54```typescript
55providers: GitHub.providers({ baseUrl: "github.example.com" }),
56```
57
58The auth provider sees the pinned host too: the configure flow stops
59prompting for it and authenticates against it directly.
60
61### Per-resource host override
62
63Every GitHub resource also takes its own `baseUrl` prop, so a single
64stack can span github.com and an enterprise instance:
65
66```typescript
67yield* GitHub.Repository("mirror", {
68 owner: "my-org",
69 name: "mirror",
70 baseUrl: "github.example.com",
71});
72```
73
74Resolution order is: resource `baseUrl` → `providers({ baseUrl })` →
75the host from the login profile or environment. Changing a resource's
76`baseUrl` replaces it — the same name on a different GitHub instance
77is a different physical resource.
78
79## Token scopes
80
81- `repo` — always required.
82- `workflow` — when you manage [Actions secrets and variables](/github/actions-config).
83- `delete_repo` — only when you opt a [repository](/github/repository)
84 into deletion via `destroy()`. Repositories default to retain on
85 removal, so most tokens never need it.
86
87## Programmatic credentials
88
89Skip profiles entirely by building the credentials layer from a token
90you already have in hand — useful in tests:
91
92```typescript
93Effect.provide(GitHub.fromToken(token))
94```
95
96`fromToken` accepts a plain string or a `Redacted` value, plus an
97optional `baseUrl` for GitHub Enterprise:
98
99```typescript
100Effect.provide(GitHub.fromToken(token, { baseUrl: "github.example.com" }))
101```
102
103To read from the environment instead, `GitHub.fromEnv()` builds the
104same layer from `GITHUB_ACCESS_TOKEN` or `GITHUB_TOKEN` (and resolves
105the enterprise host from `GITHUB_BASE_URL` / `GITHUB_API_URL` /
106`GH_HOST` when set).
107
108## Next steps
109
110- [GitHub overview](/github) — resources and compositions.