Tech Digest

Head to head

Forgejo vs Gitea

Feature comparisons between these two are a waste of your time. The difference that will matter to you in five years is who owns the code and what licence it carries.

Last reviewed 2 tools compared

Should you self-host Forgejo or Gitea?

If you are choosing today, pick Forgejo. It is the same software under a German nonprofit, Codeberg e.V., licensed GPL-3.0-or-later since v9.0, which structurally prevents the open core pattern that Gitea Ltd and its subsidiary CommitGo are already running against the MIT-licensed Gitea core. Stay on Gitea only if your organization's legal policy blocks GPL-3.0 code, if you want a paid support contract, or if you are already on Gitea v1.23 or newer where there is no supported one-step migration.

You can run either of these for a year and never notice which one you installed. Same single Go binary, same 150 MB idle, same port 3000, same SQLite-by-default, same GitHub-shaped issues and pull requests. The spec table will show you two rows that are nearly identical and one that is not.

The row that is not identical is the licence, and it is the whole article.

Read the matrix below for license, license_class and first_release. Everything else being equal is the point: when two products are this close on capability, the tiebreaker is structural, not technical. Note also that Forgejo shows as stable and Gitea as mature, which reflects the 2022 fork date rather than any difference in how reliably they run.

SpecificationForgejoGitea
LicenceGPL-3.0-or-later (Copyleft)MIT (Permissive)
Written inGo / TypeScriptGo / TypeScript
First release20222016
MaturityStableMature
DatastoreSQLite (default), PostgreSQL or MySQL optionalSQLite (default), PostgreSQL or MySQL optional
Services to run11
Idle memory150 MB150 MB
Memory in use450 MB450 MB
Operational load2 / 5, Light2 / 5, Light
IdentityNative OIDCNative OIDC
arm64 buildsYesYes
Default ports3000, 223000, 22
Backup shapeSQLite backupSQLite backup

What actually happened, in order#

Gitea itself is a fork. It split from Gogs in 2016 over exactly this issue: a single maintainer controlling a project the community depended on.

In October 2022 the Gitea maintainers announced that the domains and trademark had been transferred to Gitea Ltd, a newly formed for-profit company. The transfer happened before it was announced. Community contributors who had spent years on the project found that the name, the website and the trademark now belonged to a company they had no stake in, and that future contributions would carry a copyright assignment.

Within weeks a group of contributors forked the codebase to Codeberg and named it Forgejo. Governance moved to Codeberg e.V., a registered German nonprofit with published statutes and no shareholders. For the first year and a bit Forgejo was a soft fork: it tracked Gitea commit for commit, added a few patches, and functioned as a rebrand with different governance.

Two things ended that.

In February 2024 Forgejo announced it would stop rebasing on Gitea and develop independently. Forgejo v7.0 was the first genuine hard fork release. Then on 22 August 2024, Forgejo v9.0 relicensed from MIT to GPL-3.0-or-later. That second move is the one with teeth. Gitea's MIT licence plus a contributor copyright assignment is precisely the combination that lets CommitGo, Gitea Ltd's subsidiary, build a proprietary Gitea Enterprise on top of the free core. Forgejo's GPL-3.0-or-later makes the same pattern impossible against Forgejo's code, because a derivative work has to ship under the same terms.

So is Forgejo still a soft fork?#

No, and anyone still describing it that way is working from 2023 information.

The practical evidence is the migration path. Forgejo v10.0, released January 2025, was the last release able to read a Gitea v1.22 or older database directly. Forgejo is now on the v16 series while Gitea is on v1.27.x; the version numbers are not even in the same space. Database schemas, configuration keys, the moderation tooling, the code review interface and the Actions implementation have all drifted.

Forgejo still cherry-picks security fixes from Gitea where they apply, and Gitea has taken patches that originated in Forgejo. That is normal fork hygiene, not shared development.

The uncomfortable consequence: the escape hatch is closing in both directions. If you are on Gitea v1.23 or newer today, moving to Forgejo means exporting and re-importing repository by repository, and issue and pull request history does not come along unless you script the API yourself. Decide now rather than in 2029.

Pick Forgejo. Here is the cost of doing so.#

A recommendation with no downside listed is marketing, so here are the real ones.

Copyleft irritates corporate legal reviews. GPL-3.0-or-later on a network service triggers no obligation for you as an operator, but plenty of legal departments have a blanket policy against GPL-3.0 in the estate and will not read the nuance. If yours is one of them, Gitea under MIT is the pragmatic choice and you should take it without guilt.

Fewer eyes, less money. Codeberg e.V. runs on donations. Gitea Ltd has a payroll and enterprise customers. Forgejo has fewer paid full-time contributors, and on any given week the review queue is shorter and slower. The counterargument is that the licence guarantees continuity regardless of who is funding it, which is not something a payroll gives you.

Federation is still not done. ActivityPub federation has been Forgejo's headline differentiator for four years and it remains partial. Do not choose Forgejo for federation. Choose it for governance and take federation as an eventual bonus.

No commercial support contract. If a purchasing process requires a vendor to call, Gitea Ltd sells one and Codeberg e.V. does not.

None of those outweigh the structural argument for a person or team choosing today. You are picking where your entire source history will live for the next decade, and Licence drift exists because "the licence will not change" has been wrong repeatedly across this ecosystem.

Running either one: the parts that bite#

The operational surfaces are close enough to share a section.

Forgejo's official image is codeberg.org/forgejo/forgejo:16 and Gitea's is gitea/gitea:1. Both cover amd64 and arm64. Both mount a single /data volume, serve HTTP on 3000 and want an SSH story on 22. A minimal Forgejo stack:

yaml
services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:16
    environment:
      USER_UID: "1000"
      USER_GID: "1000"
      FORGEJO__server__SSH_PORT: "222"
      FORGEJO__server__ROOT_URL: "https://git.example.com/"
    volumes:
      - ./data:/data
      - /etc/timezone:/etc/timezone:ro
    ports:
      - "127.0.0.1:3000:3000"
      - "222:22"
    restart: unless-stopped

Four traps that apply identically to both:

  1. The first-run installer is unauthenticated. The setup page is served to anyone who reaches it, and the first account created becomes the instance administrator. Publish port 3000 before you finish the wizard and someone can complete it and own your forge. Bind to 127.0.0.1 as above, or pre-write app.ini with INSTALL_LOCK = true and create the admin from the CLI.
  2. Clone URLs come from config, not from Docker. The SSH URL in the web UI is built from SSH_DOMAIN and SSH_PORT in app.ini. Map host 222 to container 22 without setting SSH_PORT = 222 and every developer copies a URL that times out. Same for ROOT_URL behind Caddy or Traefik: get it wrong and webhooks, OAuth redirects and avatars all break differently.
  3. Git hooks bake in absolute paths. Every repository's hooks reference the absolute path of the binary and its config. Move the install, switch from a package to a container, or restore into a different layout, and pushes fail with an opaque hook error while the web UI looks perfectly healthy. Regenerate hooks from the admin panel after any move, which is a step Moving a service to a new machine will remind you about.
  4. Pick your database at install time. Gitea's own docs warn that converting an existing instance from SQLite to PostgreSQL is not well tested. Choose PostgreSQL up front if you expect more than a handful of active users, or accept SQLite permanently.

For backups, both ship a dump command (forgejo dump, gitea dump) that archives config, repositories, the data directory and an SQL dump into one file. The documentation is explicit that the instance should be stopped during the dump, because a live copy can catch the database and the repository files at different instants and you will not find out until a restore. Exclude gitea/indexers and gitea/queues; they rebuild in minutes. Pair it with an off-box target as Backups that actually restore describes.

Both support OIDC and LDAP natively as authentication sources, so wiring either into authentik or Pocket ID is admin-panel work rather than a plugin hunt. Single sign-on for self-hosters covers what to expect from the rest of your stack.

Verdict by situation#

Your situationPickWhy
Starting a new forge todayForgejoNonprofit governance plus copyleft, at zero feature cost
Legal policy bans GPL-3.0 in the estateGiteaMIT is the whole reason, and it is a legitimate one
Already running Gitea v1.23 or newer, happyGiteaNo supported one-step migration exists; there is no urgency to move
Already running Gitea v1.22 or olderForgejo, nowThe v10.0 bridge is the last supported route and it will not come back
You need a support contract with an SLAGiteaGitea Ltd sells one; Codeberg e.V. does not
Shipping a forge inside a commercial applianceGiteaMIT is simply cheaper to comply with when you distribute binaries
Public sector, association or grant-fundedForgejoPublished statutes and a nonprofit upstream survive procurement questions
You need CI, a registry and security scanning as one productNeitherSee Gitea vs GitLab CE, or pair a forge with Woodpecker CI and Harbor

What to do next#

Stand it up on a throwaway VM first with SQLite, push one real repository, and try the thing that actually matters: forgejo dump, destroy the VM, restore into a fresh container, and confirm the pushes still work. That single rehearsal tells you more than any feature matrix, and it is where the hook path problem surfaces before it costs you anything.

If you are moving off GitHub rather than choosing between forks, Replace GitHub covers the parts that are not the git remote: Actions, Pages, releases and the issue import. And if you want the browser editor as well, code-server next to the forge is a lighter answer than anything either project ships.

Questions#

Is Forgejo still a drop-in replacement for Gitea?

Not any more. Forgejo was a soft fork that tracked Gitea commit for commit until early 2024, when it hard forked and started developing independently. Databases, UI details, configuration keys and release numbering have diverged since. Forgejo v10.0, released January 2025, was the last version that reads a Gitea v1.22 or older database directly, and that is the whole remaining bridge.

Can you still migrate from Gitea to Forgejo?

Only from Gitea v1.22 or earlier, and only through a specific two-hop route: migrate to Forgejo v10.0.x first, then upgrade Forgejo forward to the current v16 series. From Gitea v1.23 or newer there is no official direct path. You are looking at repository-by-repository export and re-import, which loses issue history unless you script the API.

Does Forgejo's GPL-3.0 licence affect you if you just run it?

No. Running an unmodified instance, even commercially and even for paying customers, carries no source-provision obligation under GPL-3.0. The obligations appear when you distribute a modified build: shipping a patched Forgejo inside an appliance, or handing a customer a binary you changed. Anything you took from Forgejo v8 or earlier remains MIT, since the relicensing landed with v9.0 in August 2024.

Is Gitea going closed source?

The core is MIT and nothing suggests that changes. The structural point is different: Gitea Ltd holds the trademark and domains, contributors sign a copyright assignment, and the subsidiary CommitGo sells a proprietary Gitea Enterprise built on top. MIT plus a CLA means new features can go straight into the paid edition without ever landing upstream. That is legal, it is normal, and it is exactly the risk copyleft removes.

Does Forgejo federation work yet?

Partially, and it has been the headline differentiator for four years. ActivityPub-based federation lets instances follow each other and, in later stages, share stars, issues and pull requests across forges. Treat it as a reason to be interested in Forgejo's direction, not as a feature you can build a workflow on today. If cross-instance collaboration is a requirement now, it is not shipping.

Which one is lighter on a small VPS?

Neither, meaningfully. Both are single Go binaries with SQLite by default, both idle near 150 MB and settle around 450 MB in ordinary use, and both grow with the bleve issue and code indexers rather than with user count. A 2 GB VPS runs either alongside a reverse proxy and a couple of small services. The memory decision is Actions runners, which belong on a different machine.

What happens to Forgejo if Codeberg runs out of money?

That is the honest risk on this side. Codeberg e.V. is a donation-funded nonprofit with published statutes, not a company with a sales pipeline, and Forgejo has fewer paid full-time contributors than Gitea. The mitigation is the licence: GPL-3.0-or-later means anyone can pick up the code and continue, which is not true of features that end up in a proprietary edition.

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.