Open-source project
modrinth/code avatar
modrinth/code

modrinth/code: the monorepo behind the Modrinth website and desktop app

The Modrinth monorepo containing all code which powers Modrinth!

2,404 stars622 forksRustNOASSERTION

At a glance

What is it?
The Modrinth monorepo holds the web frontend, the desktop app and the Rust workspace that serves the API and search. This is what is actually in it, how to build it, and where it stops being the right tool.
Who is it for?
Adopt modrinth/code if you are changing the Modrinth web interface, the desktop app or the Rust services behind them, and you are ready to run Postgres, Typesense and Elasticsearch through docker-compose.yml. Do not adopt it as a mod loader, a launcher SDK or a drop-in backend for your own platform; the README points non-developers at modrinth.com and the app download instead, and the licence is per-package.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the Modrinth monorepo actually contains

The README opens by calling this repository "the primary codebase for the Modrinth web interface and app", and that sentence is the whole scope. If you are not a developer, the README sends you to the Modrinth website for the web interface and to modrinth.com/app for the latest app release. Nothing in this repository is a mod, a mod loader or a download helper for players.

Inside, there are two halves that share one checkout. The JavaScript side is a pnpm and Turbo workspace: package.json declares scripts such as web:dev and app:build that filter on @modrinth/frontend and @modrinth/app, and the frontend libraries (@modrinth/ui, @modrinth/api-client, @modrinth/utils, @modrinth/moderation, @modrinth/blog, @modrinth/assets, @modrinth/tooling-config) live under packages/. The Rust side is a Cargo workspace with members including apps/app, apps/labrinth, apps/daedalus_client, apps/app-playground, packages/app-lib, packages/daedalus, packages/modrinth-content-management and smaller crates such as packages/ariadne, packages/modrinth-log and packages/xredis.

So the audience is narrow and specific: people who want to change how Modrinth looks or behaves, or who want to run the services that back it. The README names the two packages separately and links each to its own guide, which is a useful signal. There is no single build command that produces the whole product.

How the pieces fit: Turbo for JavaScript, Cargo for Rust

The JavaScript workspace is orchestrated by Turbo. The root package.json defines build, lint, test, fix and ci as turbo run invocations with --continue, which means a failing task does not stop the rest of the graph. Two scripts are composites rather than single tasks: web:dev runs pnpm i18n:coverage and then turbo run dev --filter=@modrinth/frontend, and pages:build runs the same coverage script and then builds the frontend with NITRO_PRESET=cloudflare-pages. That preset name is the clearest statement in the repository about how the website is deployed.

There is also a prepr family of scripts. prepr:frontend targets @modrinth/frontend and @modrinth/app-frontend, while prepr:frontend:lib targets the shared libraries. The split tells you the maintainers expect contributors to run the right subset rather than everything on each change.

The Rust workspace pins the toolchain in two places: rust-toolchain.toml at the root and rust-version = "1.90.0" under [workspace.package] in Cargo.toml, with edition 2024. Dependencies are declared centrally in [workspace.dependencies], so a crate does not pick its own actix-web or chrono version. The dependency list also shows what the backend is built from: actix-web for HTTP, async-stripe for payments, aws-sdk-s3 for object storage, clickhouse for analytics, plus argon2 and cel. That is a service stack, not a library you embed.

Search is the part that surprises people. docker-compose.yml defines three separate search services under the compose project name labrinth: typesense0 running typesense/typesense:30.1 on 127.0.0.1:8108 with --api-key=modrinth, and an Elasticsearch cluster whose first node is docker.elastic.co/elasticsearch/elasticsearch:9.4.4 on 127.0.0.1:9200, with discovery.seed_hosts listing elasticsearch0, elasticsearch1 and elasticsearch2. Both engines are present in one compose file. If you only want to work on the frontend, you are still looking at a compose file that assumes you might run a three-node Elasticsearch cluster.

Installing and running it: what the README gives you

The README does not contain a step-by-step install. It points at two development guides, docs.modrinth.com/contributing/knossos/ for the website frontend and docs.modrinth.com/contributing/theseus/ for the desktop app, and at docs.modrinth.com/contributing/getting-started/ for contributing in general. Treat those pages as the install instructions; the repository itself gives you the task names and the service definitions.

What the repository does give you is the root task list. From the workspace root, the frontend dev server is started with the script the root package.json declares:

bash
pnpm web:dev

That script runs the i18n coverage step first and then turbo run dev filtered to @modrinth/frontend. The desktop app has its own equivalent, app:dev, which filters to @modrinth/app. For a production-style frontend build the root defines web:build.

Backing services come from the compose file. The database service is named postgres_db and runs postgres:15-alpine with POSTGRES_USER and POSTGRES_PASSWORD both set to labrinth, bound to 127.0.0.1:5432:

yaml
services:
  postgres_db:
    image: postgres:15-alpine
    container_name: labrinth-postgres
    ports:
      - '127.0.0.1:5432:5432'
    environment:
      POSTGRES_USER: labrinth
      POSTGRES_PASSWORD: labrinth

The search service in the same file is typesense0, with the API key passed as a command flag rather than an environment variable:

bash
docker compose up -d postgres_db typesense0

Expect the containers to report healthy before you start the application; both services define healthchecks in the compose file, and Elasticsearch sets bootstrap.memory_lock with a memlock ulimit of -1, which is a real constraint on machines that cannot raise that limit. Before opening a pull request, the repository expects the pre-PR task to pass:

bash
pnpm prepr

If you are only touching the frontend or the shared libraries, the narrower prepr:frontend and prepr:frontend:lib scripts exist so you do not have to run the whole graph.

The licence is per package, and the root says so

The repository carries a NOASSERTION licence identifier, and the README explains why: "All packages in this repository are licensed under their respective licenses. Refer to the LICENSE file in each package for more information." That is not a single-licence project. Before you copy a crate or a package into your own codebase, open the LICENSE file inside that specific package, not the repository root.

There is a second document aimed at exactly this situation. COPYING.md exists at the top level, and the README says to review it if you plan to fork the repository for your own purposes. If you intend to run a modified Modrinth, that file is the one the maintainers wrote for you, and it is the first thing to read after the per-package licence files. Nothing here is legal advice; the point is that there is no single answer to "what licence is modrinth/code".

Where the monorepo is the wrong tool

The clearest boundary is the one the README draws itself. If you are not a developer, the README tells you to use the website and download the app release, and there is no supported path in this repository for a player who just wants to install mods. The repository is the source of those products, not an alternative distribution of them.

The second boundary is operational weight. Running the whole thing means Postgres, Typesense and an Elasticsearch cluster, and the compose file configures Elasticsearch with bootstrap.memory_lock and a memlock ulimit of -1. On a machine where you cannot raise that limit, that service will not behave the way the file intends. If your goal is to read how Modrinth models projects or search, cloning the repository to read Cargo.toml and the crate list is enough; you do not need the stack running.

The third boundary is that the monorepo is not a stable integration surface. The root package.json version is 0.0.0 and marked private, and the app releases are versioned separately (v0.21.6, v0.21.5, v0.21.4 across September 2026). The packages are named with an @modrinth scope and exist to serve Modrinth's own frontends. If you want to build on Modrinth's data, the API is the interface, not this workspace. The README does not document a public API surface here, and treating these internal packages as one is a mistake the repository does not invite.

What to compare it against before you commit

The honest alternative is not another monorepo; it is not using this one. If you want a Minecraft launcher, the desktop app is distributed as a release at modrinth.com/app, and a fork of this repository means inheriting the Rust workspace, the pnpm and Turbo graph and the compose stack together. If you want a mod platform, you are comparing against building your own service on top of the Modrinth API, which the README and the repository layout treat as a separate concern from these packages.

Within the repository, the closest thing to a forkable unit is the UI library. The root scripts include storybook and build-storybook, both filtered to @modrinth/ui, and prepr:frontend:lib groups @modrinth/ui with @modrinth/moderation, @modrinth/assets, @modrinth/blog, @modrinth/api-client, @modrinth/utils and @modrinth/tooling-config. If your interest is component reuse rather than running a platform, that subset is where the boundary is drawn, and the storybook scripts are how the maintainers expect you to look at it. That is a materially different commitment from running labrinth with its database and search services.

Editorial conclusion

Adopt modrinth/code if you are changing the Modrinth web interface, the desktop app or the Rust services behind them, and you are ready to run Postgres, Typesense and Elasticsearch through docker-compose.yml. Do not adopt it as a mod loader, a launcher SDK or a drop-in backend for your own platform; the README points non-developers at modrinth.com and the app download instead, and the licence is per-package. Before your first pull request, read docs.modrinth.com/contributing/getting-started/ and COPYING.md, then run pnpm prepr so the lint and test tasks that CI runs have already passed locally.

Frequently asked questions

Is Modrinth free to use?

The README does not discuss pricing. It says that if you are not a developer you can access the web interface on the Modrinth website and download the latest release of the app from modrinth.com/app, and it directs support questions to support.modrinth.com.

Why isn't the Modrinth website or app working?

The repository does not document troubleshooting steps for the live website or the released app. The README points users to the support page at support.modrinth.com and to the Modrinth Discord server for help.

How do I join people on Modrinth?

Nothing in the README or the repository layout describes joining other users. The only community channel it names is the Discord server at discord.modrinth.com, alongside the support page.

Official sources

  1. Issues
  2. modrinth/code on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/modrinth-code.svg)](https://hysenlabs.com/projects/modrinth-code)