Algora: a self-hostable bounty board and GitHub app for paying open source contributors
Hire the top 1% OSS engineers
At a glance
- What is it?
- Algora is an Elixir and Phoenix codebase that lets a team publish bounties on GitHub issues and pull requests, route the work through a web app, and handle payouts with a payment processor. Self-hosting it means running Postgres, a GitHub app and a set of external service keys, and the licence is AGPL-3.0.
- Who is it for?
- Algora suits a team that already runs a Phoenix application, already has Postgres and Docker in its toolchain, and wants bounties on its own GitHub issues without sending candidates to a hosted job board. It is the wrong choice if you need only a tip button, if your contributors are in a country your payout processor cannot reach, or if AGPL-3.0 does not fit your distribution model.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 97 days ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three pieces in one codebase: web app, GitHub app, payment processor
Algora is not a library you add to a project. It is a full application, written in Elixir, that you either host yourself or reach through the hosted service at algora.io. The repository describes itself as consisting of three parts: a web app to publish and manage SWE jobs, contracts and bounties; a GitHub app to create bounties and reward tips on issues and pull requests; and a payment processor to handle payouts, compliance and 1099s.
That third piece is the part that shapes the whole design. A bounty system that only posts a label on an issue is a weekend project. Algora goes further and models money movement, which is why the environment file carries Stripe credentials, AWS S3 settings for uploads, and a SendGrid key for sending mail, and why the payments section of the interface is a first class screen rather than an afterthought.
The stated audience is broader than open source maintainers. The table of use cases lists an open source community that wants to reward contributors and maintainers, contractors who need to manage work and complete outcome based payments, job candidates who want to collaborate on paid projects for interviews, and teammates running an internal bounty program. The hosted version at algora.io adds automatic profile pages built from a developer's top open source contributions, automatic screening and ranking of job applicants by their open source record, and automatic matching of companies and developers on tech, budget and location preferences.
The code itself is a standard Phoenix layout. The top level entries include mix.exs, mix.lock, config/, lib/, priv/, rel/, assets/, test/, a Makefile, a Dockerfile, a fly.toml, and dotfiles such as .env.example, .credo.exs, .formatter.exs and .dialyzer_ignore.exs. The presence of .credo.exs and .dialyzer_ignore.exs tells you the project uses the standard Elixir static analysis tooling, and the rel/ directory indicates a release-style deployment rather than a purely mix phx.server workflow.
The licence is AGPL-3.0, which is the single most consequential fact for anyone considering self-hosting. It is a strong copyleft licence, and a company that modifies this code and then serves it over a network is in scope of its obligations. That is a licensing question for your own counsel rather than something this article can settle, but you should read the LICENSE file in the repository before you fork anything.
Getting from a clone to a running server with the Makefile
The setup path is documented step by step and leans on make targets rather than raw mix commands. The prerequisites are Docker, Elixir, Erlang and Node.js. The project recommends ASDF for the Erlang, Elixir, pnpm and Node.js toolchain, and the README lists the plugin commands to run from the project root:
asdf plugin add erlang
asdf plugin add elixir
asdf plugin add pnpm
asdf plugin add nodejs
asdf installThere is a .tool-versions file in the repository, which is the file ASDF reads to pin versions, so asdf install is what aligns your machine with the versions the project expects. direnv is recommended for loading environment variables and entr for watching files.
The clone step is:
git clone [email protected]:algora-io/algora.git && cd algoraThen the environment file. Copy .env.example to .env and let direnv take it:
cp .env.example .env && direnv allow .envPostgres runs in a container, and the make postgres target is the only piece of infrastructure you need for a first run. It maps the container port 15432 to 5432 and names the container algora_db:
docker run --detach -e POSTGRES_PASSWORD="postgres" -p 15432:5432 --name algora_db --volume=algora_db:/var/lib/postgresql/data postgres:latestThe remaining targets are thin wrappers over mix. install runs mix setup, server starts the Phoenix server in an IEx session, and watch recompiles on changes to lib/:
make install
make server
make watchTwo smaller targets exist for the database. make postgres-rm stops and removes the algora_db container, and make psql opens a psql session against the algora_dev database inside that container:
docker stop algora_db && docker rm algora_db
docker exec -it algora_db psql -U postgres -d algora_devNotice that the Postgres container is started with the postgres:latest tag. That is convenient for a first run and a poor choice for anything you care about, because the image version under that tag changes under you.
The .env file is really the configuration surface of the whole system
Open .env.example and you can see exactly what Algora talks to. The defaults describe a local development setup, with the app on port 4000 and Postgres on the mapped container port:
PORT=4000
LOG_LEVEL=info
DATABASE_URL="postgresql://postgres:postgres@localhost:15432/algora_dev"
TEST_DATABASE_URL="postgresql://postgres:postgres@localhost:15432/algora_test"The GitHub block is the largest, and it is the part that decides how much access you are handing to a third party. It holds a client id and secret for OAuth, an app handle, an app id, a webhook secret, a private key for server to server calls, and the state TTL and salt used to sign the OAuth state parameter:
GITHUB_CLIENT_ID=""
GITHUB_CLIENT_SECRET=""
GITHUB_APP_HANDLE=""
GITHUB_APP_ID=""
GITHUB_WEBHOOK_SECRET=""
GITHUB_PRIVATE_KEY=""
GITHUB_OAUTH_STATE_TTL=600
GITHUB_OAUTH_STATE_SALT="github-oauth-state"Payments run through Stripe, with a publishable key, a secret key and a webhook secret. Storage is S3, configured by endpoint URL, region, access key, secret key and bucket name, and the assets URLs point at either the ingest service or a Cloudflare tunnel. SendGrid handles mail, and AppSignal is wired up for observability with an OTP app name, a push API key and an app environment.
Two design choices are worth noticing. The webhook secret and the OAuth state salt are separate values, which means webhook payloads and login state can be rotated independently. And the local store has its own TTL and salt, so the session store used outside the database is not sharing key material with the login codes.
This is a lot of surface for a self-hosted deployment. Each non-empty credential is a live integration that can fail at run time, and the README says explicitly that you can skip setting up external services you do not plan to use. The flip side is that the minimal local setup, the part the Makefile targets support, is not the part most teams actually need, because bounties are meaningless without GitHub and payments are meaningless without Stripe.
Registering the GitHub app: permissions are wider than a bounty button needs
The GitHub app is where most of the complexity of running Algora yourself lands. The README walks through registering a new GitHub app and lists the fields to fill in. The URLs all point back at a local server on port 4000, which is the app's default port in .env.example:
Homepage URL: http://localhost:4000
Callback URL: http://localhost:4000/callbacks/github/oauth
Setup URL: http://localhost:4000/callbacks/github/installation
Redirect on update: YesThe webhook URL is the awkward one, because a locally running app is not reachable from GitHub's servers. The README tells you to point it at a public proxy, giving ngrok and Cloudflare Tunnel as examples, and the environment file carries a CLOUDFLARE_TUNNEL variable that suggests the tunnel route is the one the project itself uses.
Then the permissions. The app needs read and write on issues, read and write on pull requests, and read access to the account email address. Events include issues, pull requests, issue comment, pull request review and a pull request event that the source text truncates.
This is a wide grant, and it should be. The bounty flow needs to create and edit issues, attach bounty labels and amounts, react to pull request activity, and read a comment to decide that work is done. But it also means the app can write to issues and pull requests across the repositories you install it on. For an open source maintainer granting a third party service write access to their tracker, that is a decision worth making deliberately, and for a company it is a decision your security review will ask about.
The README does not document a read only mode, a dry run mode, or a way to install the app on a single repository rather than an organization. It also does not document how a bounty is marked as accepted, or what happens when a pull request is closed without payment. Those are the questions to answer with the source before you run a real bounty program.
The Dockerfile pins Elixir 1.18.1, OTP 27.3.4.6 and a Debian bookworm base
The container build is where you can see the version expectations the project holds. The Dockerfile declares its inputs as build arguments, which is a good sign, because it lets you retarget the build without editing the file:
ARG ELIXIR_VERSION=1.18.1
ARG OTP_VERSION=27.3.4.6
ARG DEBIAN_VERSION=bookworm-20260610-slim
ARG NODE_VERSION=23-bookworm-slim
ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}"
ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"
ARG NODE_IMAGE="node:${NODE_VERSION}"The build runs in three stages. A node_stage installs a pinned Chrome for Puppeteer with a dedicated cache directory, a builder stage installs build dependencies and compiles the Mix dependencies, and the runner stage is a plain Debian image that receives the compiled output.
Two details in the build are worth understanding. The comment at the top explains that Ubuntu and Debian base images are used instead of Alpine to avoid DNS resolution issues in production, which is a specific class of problem you would otherwise rediscover under load. And the dependency compile step copies config/config.exs and the environment specific config file before running mix deps.compile, with a comment explaining that this ensures a relevant config change triggers a dependency recompile. That ordering is not accidental, and it means editing the config alone can invalidate the cached dependency build.
The runtime image is Debian, not the Elixir image, so the release has to bring its own runtime. The rel/ directory in the repository layout is the Erlang release configuration that makes that possible, and the fly.toml at the top level is a deployment descriptor for Fly.io, which points to a container platform as the expected production target.
For an engineer deciding whether to self-host, the honest read is that this is a deployment story that assumes a container platform. Running it on a plain VM works, but the path of least resistance in the files is a build pushed to a registry and run as a container.
What the hosted service adds, and what self-hosting gives up
The hosted version at algora.io, run by Algora Public Benefit Corporation, is not simply a public instance of the same software. The README lists three capabilities it extends. Developers' top open source contributions are automatically displayed on their Algora profiles. Companies' job applicants are automatically screened and ranked for open source contributions. Companies and developers are automatically matched for full-time and contract work based on tech, budget and location preferences.
Those three capabilities are where the interesting data lives, and that data does not exist in a self-hosted instance. The automatic ranking depends on a corpus of contribution activity across many developers, and the matching depends on profiles and preferences from many companies. Self-hosting gives you the machinery: the web app, the GitHub app, the payment processor, the bounty board, the crowdfund view, the profile embeds. It does not give you the network.
That difference reframes the choice. If the goal is to run bounties on your own repository with your own money and your own moderation, the self-hosted code is sufficient. If the goal is to find and screen candidates, the hosted product is the product, and the open source repository is infrastructure for the hosted business rather than a substitute for it.
There is also a hiring process table that describes the hosted flow as sourcing, screening, interviewing and onboarding, with a claim that jobs are published to 50K+ developers. That number belongs to the hosted service and is not something a self-hosted instance can reproduce, since the reach comes from the accounts and contributions already on the platform.
The other half of the comparison is the payment and compliance layer, which handles payouts, compliance and 1099s. This is the part most likely to be the deciding factor. If your contributors are outside the United States, a self-hosted instance means you are running the tax and transfer mechanics yourself, with your own entity, your own Stripe account and your own compliance posture. The hosted service handles that as a product feature, and the repository only tells you it exists, not how it works.
Maintenance signals, release history and the upgrade cost of running it yourself
The repository is not archived, and the last push was on 2026-07-18. There are no GitHub releases at all, so there is no tagged version history to pin, no changelog and no upgrade path published as release notes. The project is therefore shipped as a moving main branch, which is a meaningful operational difference from a library you can depend on at a fixed version.
For a self-hosted deployment that means your upgrade story is a git pull and a rebuild, and your rollback story is whatever your own process provides. The Dockerfile supports a controlled rebuild because the version inputs are build arguments, but the application version itself is not a tagged artifact. If you care about reproducibility, you are responsible for pinning a commit.
The dependency footprint is also worth naming. The environment file shows Postgres, GitHub, Stripe, S3, SendGrid, AppSignal and Cloudflare Tunnel, and the Dockerfile adds Puppeteer with a pinned Chrome build, which is a heavy runtime dependency for a server that mostly renders text and JSON. The .tool-versions file and the mix.lock file together determine the exact dependency set you get.
On licensing, the short version is that AGPL-3.0 is the most restrictive common open source licence you are likely to meet in an internal tool, and it applies to the whole codebase, including the payment processor, which is the part most likely to need changes. Read the LICENSE file, and read it before the first commit to your own repository.
Editorial conclusion
Algora suits a team that already runs a Phoenix application, already has Postgres and Docker in its toolchain, and wants bounties on its own GitHub issues without sending candidates to a hosted job board. It is the wrong choice if you need only a tip button, if your contributors are in a country your payout processor cannot reach, or if AGPL-3.0 does not fit your distribution model. Verify first that the payment and compliance layer matches the jurisdictions you pay in, that the GitHub app permissions you grant are limited to what the bounty flow needs, and that the Makefile targets still start against a current Postgres image.
Frequently asked questions
What do I need to run Algora locally?
Docker, Elixir, Erlang and Node.js, with Postgres running in a container. The documented path is to install the ASDF plugins, copy .env.example to .env, then run make postgres, make install and make server.
Does Algora need a GitHub app to work?
Yes for the bounty and tip features, since a GitHub app is what creates bounties and rewards on issues and pull requests. The README registers a new app with callbacks on http://localhost:4000, a public webhook URL, and read and write permissions on issues and pull requests.
Can I self-host Algora and pay contributors myself?
The codebase includes a payment processor that handles payouts, compliance and 1099s, and the .env.example file expects Stripe keys. Self-hosting means supplying your own Stripe credentials and handling the tax and transfer mechanics yourself, since those are not described in the repository.
What is the difference between self-hosting Algora and using algora.io?
The hosted version at algora.io, operated by Algora Public Benefit Corporation, adds automatic profiles built from open source contributions, automatic screening and ranking of applicants, and automatic matching of companies and developers. The self-hosted code covers the web app, the GitHub app and the payment processor, but not that shared network.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/algora-io-algora)Was this useful?