# How to choose a developer community platform for year one

> Score Discord, Discourse, GitHub Discussions, Slack, and Zulip on search, moderation, identity, cost, and export, then commit to one platform for a year.

Source: https://voxgig.com/howto/choose-a-developer-community-platform

- Audience: devrel
- Level: beginner
- Verified: 2026-09-25
- Published: 2026-09-25

## Short answer

Score Discord, Discourse, GitHub Discussions, Slack, and Zulip on six things that decide a first year. Those are whether answers are readable without an account, moderation tooling, whether a developer can join with an account they already hold, cost, data export, and speed. Weight them for your situation, take the top score, and stay on it for the year. A forum wins on search and export, chat wins on speed, and launching on both splits the same thirty people.

---
## You will need

Node 22 or later, and an API or SDK with at least one external user, because a community with
no members is a decision with no evidence. Verified 2026-09-25 against Node 22.22.2. The scoring
is a file and a script rather than a slide, so a colleague can dispute one cell and rerun it.
Slack sits in the table because most teams already have it open, and its free plan hides
messages after 90 days.[^1]

## Approaches compared

| Approach | When it fits | What it costs you | When to pick something else |
| --- | --- | --- | --- |
| [Discord](https://docs.discord.com/developers/intro) | Users who want to talk in real time, voice included, and a team online most of the day | Every answer is invisible to a search engine, so the same question is asked and answered again each month | Search traffic matters more than presence, or nobody can moderate in the evenings |
| [Discord plus Answer Overflow](https://github.com/AnswerOverflow/AnswerOverflow) | An existing Discord whose help threads deserve to be found | A second service to run or pay for, and only threads in the channels you select reach the web | You have not launched anywhere yet, so a forum costs less than a bridge |
| [Discourse](https://meta.discourse.org/t/how-public-discourse-sites-are-indexed-by-search-engines-like-google/1184) | A small team that needs moderation to keep working while it sleeps | Hosting at 100 dollars a month or a server you run, and a slower conversation than chat | Your users are on GitHub already and the questions are about the code |
| [GitHub Discussions](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/about-discussions) | Users who already hold a GitHub account and questions that live near the code | No trust levels or limits on a new account, and an export that exists only through the GraphQL API | Your users are not on GitHub, or you may leave GitHub |
| [Slack](https://slack.com/help/articles/115002422943-Usage-limits-for-free-workspaces) | A private customer group where every member is invited by name | A separate account per workspace, and on the free plan messages leave view after 90 days | The community is public, or answers must outlive a quarter |
| [Zulip](https://zulip.com/help/public-access-option) | Chat that must also be readable by the public, on a sponsored or self-hosted plan | Web-public channels are off by default and tied to a plan, and the topic model takes explaining | Your users expect Discord or a forum, and nobody will learn a third shape |

Chat and forum are the two shapes, and the rest is detail. Discord gives the fastest
conversation and the least searchable one. Discourse gives every thread a public page and trust
levels that limit what a new account can do, at the cost of a hosting bill and a slower pace.
GitHub Discussions gives the reader an account they already have and no way out other than the
API. Answer Overflow narrows the gap for Discord without closing it.

## Score what each platform can show a search engine

The inventory is a JSON file with one entry per platform and one score per criterion, on a scale
from 0 to 3. Each score carries the reason and the page the reason was read from.

```json title="platforms.json"
      "name": "Discourse",
      "scores": {
        "search": {
          "score": 3,
          "why": "A server-rendered crawler layout with structured data, and allow_index_in_robots_txt on by default",
          "source": "https://meta.discourse.org/t/how-public-discourse-sites-are-indexed-by-search-engines-like-google/1184"
        },
        "moderation": {
          "score": 3,
          "why": "Five trust levels that limit new accounts and promote regulars automatically, plus flags and staff roles",
          "source": "https://meta.discourse.org/t/trust-level-permissions-reference/224824"
        },
```

A score without a source is an opinion, and the validator refuses it. Two scores carry the
argument. Discord scores 0 on search because its messages are read through
[the messages API](https://docs.discord.com/developers/resources/message) by a client holding
`VIEW_CHANNEL` and `READ_MESSAGE_HISTORY`, which a crawler does not hold. Discourse scores 3
because it detects a crawler by user agent and serves it a server-rendered layout with
structured data.[^2] GitHub Discussions scores 3 for a plainer reason: a discussion
[inherits its repository's visibility](https://docs.github.com/en/discussions/quickstart), so
on a public repository it is a public page.

Moderation is where the forum earns its second point. Discourse ships five trust levels, and a
new account cannot send messages, post attachments, or post more than two links until it has
read enough to leave level 0.[^3] Discord's
[AutoMod](https://discord.com/safety/auto-moderation-in-discord) blocks keywords and spam and can
make a new member wait ten minutes before posting. None of GitHub's tools, which are lock, delete,
convert, and
[block a user](https://docs.github.com/en/discussions/managing-discussions-for-your-community/moderating-discussions),
limits an account that joined this morning.

## Weight the criteria for the year you are in

The weights are the only opinion in the file, and they are written down so they can be argued
with.

```js title="score.mjs"
export const PROFILES = {
  'year one, a few hundred users, one part-time moderator': {
    search: 3, moderation: 2, identity: 2, cost: 1, export: 2, realtime: 1,
  },
  'launch week, chat first, search and export set aside': {
    search: 0, moderation: 1, identity: 1, cost: 1, export: 0, realtime: 3,
  },
}
```

Search carries 3 in year one because an answer nobody can find is an answer that gets written
again, by you. Export carries 2 because the year ends with a review, and a review that cannot
move the archive is a review with one possible outcome. Cost carries 1 because every option here
has a free path for a few hundred people, so the money is not where the cost is.

```bash
node demo.mjs
```

```text output
year one, a few hundred users, one part-time moderator
  weights search 3, moderation 2, identity 2, cost 1, export 2, realtime 1
  1. Discourse                      28/33  85%
  2. GitHub Discussions             25/33  76%
  2. Zulip                          25/33  76%
  4. Discord plus Answer Overflow   19/33  58%
  5. Discord                        14/33  42%
  6. Slack                          13/33  39%
  Discourse over GitHub Discussions: export, worth 4 points
  Discourse over Zulip: search, worth 3 points

launch week, chat first, search and export set aside
  weights search 0, moderation 1, identity 1, cost 1, export 0, realtime 3
  1. Discord                        15/18  83%
  2. Discord plus Answer Overflow   14/18  78%
  3. Slack                          13/18  72%
  3. Zulip                          13/18  72%
  5. GitHub Discussions             11/18  61%
  6. Discourse                      10/18  56%
  Discord over Discord plus Answer Overflow: cost, worth 1 point
  Discord over Slack: cost, worth 1 point
```

Read the second line under each ranking before the first. Discourse and GitHub Discussions tie
on search, and what separates them is export. A Discourse administrator downloads
[a full database backup](https://meta.discourse.org/t/create-download-and-restore-a-backup-of-your-discourse-database/122710)
that restores onto any other Discourse. A GitHub discussion leaves through
[the GraphQL API](https://docs.github.com/en/graphql/guides/using-the-graphql-api-for-discussions)
or not at all. Against Discord the gap is search, whose nine points are far more than any other
criterion contributes.

The second profile is the launch week, with search and export set to zero, and Discord wins it.
The order moved because the weights moved. Any scoring you are shown should be able to do that,
and one that cannot has the weights hidden in the scores.

## Count what a split costs

The pitfall is opening two platforms on the same day, so that nobody has to choose. Thirty
people who answer questions become fifteen and fifteen, which leaves every question seen by half a
crowd.

```js title="score.mjs"
export function seenWithinAnHour({ active, p, platforms = 1 }) {
  if (!Number.isInteger(active) || active < 0) throw new Error(`active must be a whole number, got ${active}`)
  if (!(p >= 0 && p <= 1)) throw new Error(`p must be between 0 and 1, got ${p}`)
  if (!Number.isInteger(platforms) || platforms < 1) throw new Error(`platforms must be at least 1, got ${platforms}`)
  const perPlatform = Math.floor(active / platforms)
  return 1 - Math.pow(1 - p, perPlatform)
}
```

```bash
node split.mjs
```

```text output
30 active members, each looking in 13% of hours
  1 platform   30 people each  a question is seen within the hour 98% of the time
  2 platforms  15 people each  a question is seen within the hour 87% of the time
  3 platforms  10 people each  a question is seen within the hour 74% of the time
```

The model is a model: one look per member per hour, one in eight, independent of everything.
It is not a measurement, but it is the right shape. The people are the scarce resource,
the platform is not, and a second platform spends the people twice. The moderation load doubles
in the same move, and the person who answers on both writes every answer twice.

## Check it worked

Eleven tests pin the rules, and three matter. The year-one weights rank Discourse first and the
launch weights rank Discord first, so the ranking is seen to follow the weights. Splitting
thirty people across two platforms lowers the chance a question is seen within the hour. And a
score with no source fails validation instead of ranking with a hole.

```bash
node --test score.test.mjs
```

```text output
1..11
# tests 11
# suites 0
# pass 11
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 114.243312
```

Rerun the tests after every edit to `platforms.json`. The literal `Discourse` in the year-one
test is the line to read: if it stops matching, a score changed, and the reason for the change
belongs in the cell beside it.

## When it goes wrong

Every platform scores 3 on everything. The scores were written by the person who had already
chosen. Require a source per cell, which the validator does, and have the person arguing for
the losing platform write its row.

The ranking changes when a seventh criterion is added. The new criterion is carrying an opinion
the weights were meant to carry. Keep the six, and change a weight instead, in the file, where
the change is visible.

Discord wins in the meeting. The weights in the room were launch-week weights, and the year is
not a launch week. Show both rankings, and ask which one the team will be living in by month
nine.

The forum is quiet after the move. When thirty people were moved from a place with presence to a
place without it, nobody told them what pace to expect. Publish an answer time, such as one working
day, and meet it, because a forum runs on the expectation of a reply rather than the sight of
one.

## When not to do this

Do not run this scoring when the platform has been chosen for you. A partner's Discord, a
customer's Slack Connect channel, and a company forum that already exists are constraints. The
useful work is scoring what can be done about them, such as Answer Overflow on the Discord you
were handed.

Do not launch on two platforms at once to avoid the decision. The split model is the whole
argument, and it understates the cost, because the moderation load doubles and the same three
people answer every question twice.

Do not put cost ahead of everything for a community of a few hundred people. Every option here
has a free path, and the year of evenings you spend moderating is the cost the table cannot
show.

Do not treat the year as a trial to abandon in the first quiet month. A defined year exists to
stop the re-deciding, and a platform that is quiet in month two is quiet because it is month
two. Set the review date on the day you launch, and score again on that date with the same
file.

## Related how-tos

- [Audit a DevRel program in one week](/howto/audit-a-devrel-programme-in-one-week)
- [Choose developer experience metrics for your API](/howto/choose-developer-experience-metrics-for-your-api)

## Last verified

Verified 2026-09-25 against Node 22.22.2. Every output block is what the command preceding it
printed. Each score in the inventory was read from the platform's own documentation on that
date, and the page it came from is in the cell beside it. The weights and the split model are
this page's own rather than the result of measuring any platform in use.

[^1]: Slack's [usage limits page](https://slack.com/help/articles/115002422943-Usage-limits-for-free-workspaces)
says a free workspace hides messages older than 90 days to make room for new ones, and deletes
anything older than a year. The page does not say what the room is made of. A tip one paragraph
earlier says that upgrading removes the limit, without adding any room.

[^2]: Discourse renders every public page twice.
[The indexing reference](https://meta.discourse.org/t/how-public-discourse-sites-are-indexed-by-search-engines-like-google/1184)
says a crawler, detected by its user agent, is served a separate server-rendered layout with
`DiscussionForumPosting` markup and pagination links. A browser with JavaScript switched off
gets a `noscript` copy of the same topic. The rendering built for machines is the one made of
plain HTML.

[^3]: Discourse has five trust levels, numbered 0 to 4, and its own documentation has two names
for the top one. The
[permissions reference](https://meta.discourse.org/t/trust-level-permissions-reference/224824)
lists level 4 as Inner Circle, and
[the detailed explanation](https://meta.discourse.org/t/discourse-trust-levels-a-detailed-explanation/396792)
lists it as Leader, reached by manual promotion only.
[Discourse's 2018 post](https://blog.discourse.org/2018/06/understanding-discourse-trust-levels/)
on the subject, as it reads today, adds that a site begins in bootstrap mode and grants level 1
to its first 50 accounts. The
founders of a community never meet the limits they keep for everyone who arrives later.