Documentation Index Fetch the complete documentation index at: https://mintlify.com/modrinth/code/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The packages/ directory contains shared libraries used across multiple applications. These packages are organized into TypeScript (frontend) and Rust (backend) libraries.
Frontend Packages (TypeScript/Vue)
@modrinth/ui
Path : packages/ui/
Description : Shared Vue component library for web and desktop app
Features
Vue 3 components (buttons, modals, cards, forms)
Cross-platform pages (used in both Nuxt and Tauri)
Composables and utilities
i18n translations (34 languages)
Dependency injection providers
Storybook component development
Structure
packages/ui/src/
├── components/ # Vue components by domain
│ ├── base/ # Base UI (Button, Input, Modal)
│ ├── project/ # Project-related components
│ ├── version/ # Version components
│ └── ...
├── pages/ # Cross-platform pages
├── composables/ # Vue composables
├── providers/ # DI context providers
├── utils/ # Utility functions
├── locales/ # Translation files (en-US.json, etc.)
├── styles/ # Tailwind utilities
└── stories/ # Storybook stories
Usage
import { Button , Modal , ProjectCard } from '@modrinth/ui'
import { injectModrinthClient , provideModrinthClient } from '@modrinth/ui'
Color System
Use semantic color variables for theme support:
Surfaces : bg-surface-1 through bg-surface-5
Text : text-contrast, text-primary, text-secondary
Brand : bg-brand, text-brand
Semantic : bg-red, bg-green, bg-orange, bg-blue
See the Frontend Web guide for complete color usage.
Storybook
Develop components in isolation:
Access at http://localhost:6006
@modrinth/api-client
Path : packages/api-client/
Description : Platform-agnostic API client for Modrinth services
Features
Multi-API support (Labrinth, Archon, Kyros, ISO3166)
Platform variants:
GenericModrinthClient - Node/browser (uses ofetch)
NuxtModrinthClient - Nuxt SSR-aware (uses $fetch)
TauriModrinthClient - Tauri (uses @tauri-apps/plugin-http)
Feature system (auth, retry, circuit breaker)
XHR upload with progress tracking
WebSocket support for real-time events
Type-safe API methods
Architecture
Request Flow:
Module Method → client.request() → Feature Chain → Platform executeRequest()
Module Structure
client . labrinth . projects_v2
client . labrinth . projects_v3
client . labrinth . versions_v3
client . labrinth . users_v2
client . archon . servers_v0
client . archon . servers_v1
client . archon . backups_v1
client . kyros . files_v0
client . iso3166 . data
Usage Example
import { NuxtModrinthClient , AuthFeature } from '@modrinth/api-client'
const client = new NuxtModrinthClient ({
userAgent: 'my-app/1.0.0' ,
features: [
new AuthFeature ({
token : async () => auth . value . token ,
}),
],
})
// Fetch project
const project = await client . labrinth . projects_v3 . get ( 'sodium' )
// Search with filters
const results = await client . labrinth . search_v3 . search ({
query: 'optimization' ,
facets: [[ 'categories:optimization' ], [ 'project_type:mod' ]],
limit: 20 ,
})
Features (Middleware)
AuthFeature : Injects Bearer token
new AuthFeature ({ token: 'mrp_...' })
new AuthFeature ({ token : async () => getToken () })
RetryFeature : Exponential backoff retry
new RetryFeature ({
maxAttempts: 3 ,
backoffStrategy: 'exponential' ,
initialDelay: 1000 ,
})
CircuitBreakerFeature : Prevents cascade failures
new CircuitBreakerFeature ({
maxFailures: 3 ,
resetTimeout: 30000 ,
})
File Uploads
const handle = client . kyros . files_v0 . uploadFile ( path , file , {
onProgress : ({ progress }) => {
uploadProgress . value = Math . round ( progress * 100 )
},
})
// Cancel if needed
handle . cancel ()
// Wait for completion
await handle . promise
@modrinth/assets
Path : packages/assets/
Description : Styling, design tokens, and auto-generated icons
Contents
Tailwind preset (tailwind-preset.ts)
CSS variables (styles/variables.scss) - theme tokens
SVG icons (auto-generated from icons/ directory)
Semantic color tokens
Adding Icons
# Add SVG file to packages/assets/icons/
pnpm icons:add my-icon.svg
# Icons are auto-generated and exported
import { MyIcon } from '@modrinth/assets'
@modrinth/utils
Path : packages/utils/
Description : Shared utility functions
import { formatNumber , debounce , formatDate } from '@modrinth/utils'
const downloads = formatNumber ( 1234567 ) // "1.2M"
const timestamp = formatDate ( new Date ()) // "2 hours ago"
@modrinth/blog
Path : packages/blog/
Description : Blog system and changelog data
Blog post rendering
Changelog parsing
Markdown processing
@modrinth/moderation
Path : packages/moderation/
Description : Moderation utilities and content filtering
Content censoring
Profanity detection
User report handling
Path : packages/tooling-config/
Description : Shared ESLint, Prettier, and TypeScript configurations
{
"prettier" : "@modrinth/tooling-config/prettier.config.cjs" ,
"eslintConfig" : {
"extends" : "@modrinth/tooling-config/eslint.config.js"
}
}
Rust Packages
theseus (app-lib)
Path : packages/app-lib/
Crate : theseus
Description : Desktop app backend library
Features
Profile management : Create and manage Minecraft instances
Mod installation : Install from Modrinth or local files
Game launching : Launch Minecraft with mods
Metadata : Minecraft, Forge, Fabric, Quilt version data
Java detection : Auto-detect and download Java runtimes
Database : SQLite for local state
Analytics : Track usage (opt-in)
Core APIs
use theseus :: profile :: Profile ;
use theseus :: pack :: install_mod;
use theseus :: launcher :: launch;
// Create profile
let profile = Profile :: create ( "My Modpack" , "1.20.1" , "fabric" ) . await ? ;
// Install mod
install_mod ( & profile . id, "sodium" , None ) . await ? ;
// Launch game
let process = launch ( & profile . id, None , None ) . await ? ;
See Desktop App for complete documentation.
daedalus
Path : packages/daedalus/
Description : Minecraft and mod loader metadata library
Features
Minecraft version manifests
Forge version data
Fabric loader and mappings
Quilt loader versions
Modpack format parsing (mrpack, CurseForge)
Usage
use daedalus :: minecraft :: VersionManifest ;
use daedalus :: modded :: LoaderVersion ;
// Get Minecraft versions
let manifest = VersionManifest :: fetch () . await ? ;
let version_1_20_1 = manifest . get_version ( "1.20.1" ) ? ;
// Get Fabric versions
let fabric_versions = LoaderVersion :: fetch_fabric ( "1.20.1" ) . await ? ;
ariadne
Path : packages/ariadne/
Description : Analytics library for tracking usage and events
Features
Event tracking
ClickHouse integration
Privacy-preserving analytics
Opt-in/opt-out support
use ariadne :: { Event , track};
track ( Event :: Download {
version_id : "abc123" ,
user_id : Some ( "user_456" ),
}) . await ? ;
modrinth-log
Path : packages/modrinth-log/
Description : Logging utilities with tracing integration
use modrinth_log :: {info, error};
info! ( "Server started on port {}" , 8000 );
error! ( "Failed to connect to database: {}" , err );
modrinth-util
Path : packages/modrinth-util/
Description : General Rust utilities
String utilities
Error handling helpers
Type conversions
modrinth-maxmind
Path : packages/modrinth-maxmind/
Description : MaxMind GeoIP integration
use modrinth_maxmind :: GeoIp ;
let geoip = GeoIp :: new ( "/path/to/GeoLite2-City.mmdb" ) ? ;
let location = geoip . lookup ( "8.8.8.8" ) ? ;
muralpay
Path : packages/muralpay/
Description : Payment processing (Stripe integration)
use muralpay :: {create_payment_intent, PaymentIntent };
let intent = create_payment_intent (
1000 , // $10.00
"usd" ,
"user_id" ,
) . await ? ;
path-util
Path : packages/path-util/
Description : Cross-platform path utilities
use path_util :: {normalize_path, get_app_data_dir};
let normalized = normalize_path ( "/foo/../bar" ); // "/bar"
let app_dir = get_app_data_dir () ? ; // OS-specific app data directory
sqlx-tracing
Path : packages/sqlx-tracing/
Description : SQLx query tracing and logging
use sqlx_tracing :: TracingExecutor ;
let executor = TracingExecutor :: new ( pool );
// Queries are automatically logged with tracing
labrinth-derive
Path : packages/labrinth-derive/
Description : Derive macros for Labrinth models
use labrinth_derive :: Queryable ;
#[derive( Queryable )]
struct Project {
id : String ,
slug : String ,
title : String ,
}
Package Dependencies
Workspace Dependencies
Packages reference each other using workspace protocol:
package.json :
{
"dependencies" : {
"@modrinth/ui" : "workspace:*" ,
"@modrinth/api-client" : "workspace:*" ,
"@modrinth/assets" : "workspace:*"
}
}
Cargo.toml :
[ dependencies ]
theseus = { path = "../packages/app-lib" }
daedalus = { path = "../packages/daedalus" }
ariadne = { path = "../packages/ariadne" }
Dependency Graph
apps/frontend/
└── @modrinth/ui
├── @modrinth/api-client
├── @modrinth/assets
└── @modrinth/utils
apps/app-frontend/
└── @modrinth/ui
├── @modrinth/api-client
└── @modrinth/assets
apps/app/
└── theseus (app-lib)
├── daedalus
├── ariadne
└── modrinth-util
apps/labrinth/
├── ariadne
├── daedalus
├── modrinth-log
├── modrinth-util
├── modrinth-maxmind
└── muralpay
Creating a New Package
TypeScript Package
Create Directory
mkdir packages/my-package
cd packages/my-package
Initialize package.json
{
"name" : "@modrinth/my-package" ,
"version" : "0.0.0" ,
"type" : "module" ,
"main" : "./dist/index.js" ,
"types" : "./dist/index.d.ts" ,
"exports" : {
"." : {
"types" : "./dist/index.d.ts" ,
"import" : "./dist/index.js"
}
},
"scripts" : {
"build" : "tsup src/index.ts --format esm --dts" ,
"lint" : "eslint ." ,
"fix" : "eslint . --fix"
},
"devDependencies" : {
"@modrinth/tooling-config" : "workspace:*" ,
"tsup" : "^8.0.0" ,
"typescript" : "^5.0.0"
}
}
Create Source Files
export function myUtility () {
return 'Hello from my package'
}
Add TypeScript Config
{
"extends" : "@modrinth/tooling-config/tsconfig.json" ,
"compilerOptions" : {
"outDir" : "./dist"
},
"include" : [ "src" ]
}
Update pnpm-workspace.yaml
Already includes packages/*, so no change needed.
Build and Test
pnpm build
# Use in another package
pnpm add @modrinth/my-package --filter @modrinth/frontend
Rust Package
Create Crate
cargo new --lib packages/my-crate
Update Cargo.toml
packages/my-crate/Cargo.toml
[ package ]
name = "my-crate"
version = "0.1.0"
edition.workspace = true
[ dependencies ]
# Add dependencies
[ lints ]
workspace = true
Add to Workspace
Edit root Cargo.toml: [ workspace ]
members = [
# ...
"packages/my-crate" ,
]
Implement Library
packages/my-crate/src/lib.rs
pub fn my_function () -> String {
"Hello from my crate" . to_string ()
}
#[cfg(test)]
mod tests {
use super ::* ;
#[test]
fn test_my_function () {
assert_eq! ( my_function (), "Hello from my crate" );
}
}
Use in Other Crates
[ dependencies ]
my-crate = { path = "../../packages/my-crate" }
Publishing
Internal Packages
Most packages are internal and not published to npm/crates.io. They’re only used within the monorepo.
Public Packages
Some packages may be published:
@modrinth/api-client - Public npm package
daedalus - May be published to crates.io
Publishing to npm :
cd packages/api-client
pnpm build
npm publish --access public
Publishing to crates.io :
cd packages/daedalus
cargo publish
Best Practices
Package Design
Single Responsibility : Each package should have a clear, focused purpose
Minimal Dependencies : Avoid heavy dependencies in shared packages
Platform Agnostic : Shared code should work across web and app (when possible)
Type Safety : Export TypeScript types for all public APIs
Documentation : Include README with usage examples
Versioning
Internal packages use workspace:* to always use the local version. Version numbers are primarily for tracking, not for dependency resolution.
Breaking Changes
When making breaking changes to a shared package:
Update all consumers in the same PR
Run full test suite: pnpm test
Ensure all apps build: pnpm build
Testing
Test packages in isolation:
# TypeScript package
pnpm --filter @modrinth/my-package test
# Rust crate
cargo test -p my-crate
Next Steps
Frontend (Web) See how packages are used in the web app
Desktop App Learn about Theseus and app integration
Backend (Labrinth) Explore Rust packages used in the backend
Code Style Follow coding standards for packages