---
title: "Quick start"
description: "Read an issue, write a comment and add a second forge."
canonical_url: "https://forges.link/getting-started/quick-start"
---
# Quick start

> Read an issue, write a comment and add a second forge.

This page walks you through the main calls on GitHub and then adds Codeberg as a second forge. To follow along, you need a [GitHub personal access token](https://github.com/settings/tokens) in the `GITHUB_TOKEN` environment variable. The last steps also use a Codeberg access token in `CODEBERG_TOKEN`.

<steps level="2">

## Create a provider

Start by importing a provider function, passing it your credentials and calling `create()` on the result:

```ts
import { github } from 'forges/github'

const gh = github({
  auth: { type: 'token', token: process.env.GITHUB_TOKEN! },
}).create()
```

## Read a thread

On a forge, issues, pull requests and discussions are all conversations, and `forges` calls each of them a thread. To get one, you pass a ref, which is a plain object that names the repository and the thread:

```ts
const repo = {
  forge: 'github',
  instance: 'github.com',
  owner: 'nuxt',
  name: 'nuxt',
} as const

const thread = await gh.threads.get({
  forge: 'github',
  instance: 'github.com',
  repo,
  kind: 'issue',
  number: '1',
})
console.log(thread.title, thread.state)
```

## List threads

To go through many threads, use `list()`. It returns an async iterable that fetches the next page of results only when your loop needs it, so you can stop early without wasting requests:

```ts
for await (const issue of gh.threads.list(repo, {
  kind: 'issue',
  state: 'open',
})) {
  console.log(issue.ref.number, issue.title)
}
```

## Write a comment

Write operations take the same refs as the read operations. The following call posts a real comment, so change `repo` to a repository you own before you run it:

```ts
await gh.threads.comment(thread.ref, 'Thanks for the report.')
```

## Add a second forge

To work with more than one forge, pass a list of factories to `createForges()`. It builds a provider for each factory and sends every call to the provider that matches the ref you pass in. Listings that don't belong to a single forge, such as notifications, are collected from all of the providers:

```ts
import { createForges, forgejo, github } from 'forges'

const forges = createForges([
  github({ auth: { type: 'token', token: process.env.GITHUB_TOKEN! } }),
  forgejo({
    baseUrl: 'https://codeberg.org',
    auth: { type: 'token', token: process.env.CODEBERG_TOKEN! },
  }),
])

for await (const notification of forges.notifications.list()) {
  console.log(notification.ref.forge, notification.title)
}
```

## Check support before you write

Not every forge supports every operation. When your code runs on more than one forge, ask the provider whether it supports an operation before you call it:

```ts
if (gh.can('threads.addLabels', thread.ref.kind)) {
  await gh.threads.addLabels(thread.ref, ['triage'])
}
```

</steps>

## Next steps

- Learn [how capabilities work](https://forges.link/concepts/capabilities) to see why the check above exists.
- [Receive webhooks](https://forges.link/guides/webhooks) to react to what happens on your forges.
- Read the [provider page](https://forges.link/providers) for your forge to see how it authenticates and how it differs.


## Sitemap

See the full [sitemap](https://forges.link/sitemap.md) for all pages.
