<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: quonaro</title>
    <description>The latest articles on DEV Community by quonaro (@quonaro).</description>
    <link>https://dev.to/quonaro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4186906%2Fae3e7158-6c42-4fe5-9010-3822f1ceee14.jpg</url>
      <title>DEV Community: quonaro</title>
      <link>https://dev.to/quonaro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quonaro"/>
    <language>en</language>
    <item>
      <title>Stop sending mods via Discord: self-hosted MiniMin panel + one-click sync for friends</title>
      <dc:creator>quonaro</dc:creator>
      <pubDate>Fri, 16 Oct 2026 03:45:04 +0000</pubDate>
      <link>https://dev.to/quonaro/stop-sending-mods-via-discord-self-hosted-minimin-panel-one-click-sync-for-friends-1jca</link>
      <guid>https://dev.to/quonaro/stop-sending-mods-via-discord-self-hosted-minimin-panel-one-click-sync-for-friends-1jca</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;MiniMin is a small self-hosted panel for modded Minecraft servers. Spin up a server in Docker in a couple of clicks, hit "share client build", your friend pastes one link into MiniMin Sync and gets a ready Prism Launcher instance with auto-updates. No Discord zips, no version drift.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If this resonates — clone the repos, run it, tell me what breaks first. That's the most useful feedback right now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Panel: &lt;a href="https://github.com/quonaro/minimin" rel="noopener noreferrer"&gt;https://github.com/quonaro/minimin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sync: &lt;a href="https://github.com/quonaro/minimin-sync" rel="noopener noreferrer"&gt;https://github.com/quonaro/minimin-sync&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foskk7zyul2uw3ginm05r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foskk7zyul2uw3ginm05r.png" alt="Dashboard Info" width="780" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The pain
&lt;/h2&gt;

&lt;p&gt;Every 6-12 months I get the same urge: play Minecraft with friends, with a couple hundred Fabric / Forge mods.&lt;/p&gt;

&lt;p&gt;The usual flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Someone spins up a server.&lt;/li&gt;
&lt;li&gt;Mods are copied by hand into &lt;code&gt;mods&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The client build is zipped and dropped into Discord.&lt;/li&gt;
&lt;li&gt;One friend has the wrong version, another one crashes, the third one is too lazy to update.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted this instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a panel in the browser.&lt;/li&gt;
&lt;li&gt;Create / update the server.&lt;/li&gt;
&lt;li&gt;Hit "create client archive".&lt;/li&gt;
&lt;li&gt;Send friends one link. They sync in one click.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's why I built MiniMin. Mostly for myself, no enterprise / clean-code claims. Part of the code is AI-assisted (Devin + Kimi K2.6), I was acting as a user annoyed by manual mod setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not plain Docker or Pterodactyl?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Bare server on the host&lt;/strong&gt;&lt;br&gt;
Works, but: Java versions, logs, crash reports, manual client build. OK for once, painful for regular weekend sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Docker / docker compose + itzg/minecraft-server&lt;/strong&gt;&lt;br&gt;
Better. The &lt;code&gt;itzg/minecraft-server&lt;/code&gt; image solves 80% of Java / version / EULA / memory pain. But the routine stays: drop in mods, read logs, build a client archive, send it around.&lt;/p&gt;

&lt;p&gt;I started with scripts. Then I wanted a panel: click a few buttons and be sure friends run the same build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Pterodactyl&lt;/strong&gt;&lt;br&gt;
Powerful, but huge. It's hosting infrastructure for dozens of servers with wings, users, allocations. Overkill for "1-2 modpacks for friends for the weekend".&lt;/p&gt;

&lt;p&gt;So my own bike: a tiny panel only for modded servers + a tiny desktop sync client.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works: two parts
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. MiniMin — server panel
&lt;/h3&gt;

&lt;p&gt;Single container: Go backend + embedded frontend, Caddy in front.&lt;/p&gt;

&lt;p&gt;What it does today (verified against code, no marketing):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-server&lt;/strong&gt; — several servers from one dashboard: start / stop / restart / monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker orchestration&lt;/strong&gt; — one container per server via Docker API, based on &lt;code&gt;itzg/minecraft-server&lt;/code&gt;. Host &lt;code&gt;/var/run/docker.sock&lt;/code&gt;, volumes mapped to the host. Not OK for SaaS, fine for home self-hosting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First-class engines are VANILLA / FABRIC / FORGE only.&lt;/strong&gt; &lt;code&gt;NeoForge&lt;/code&gt; is aliased to &lt;code&gt;FORGE&lt;/code&gt;, &lt;code&gt;Quilt&lt;/code&gt; to &lt;code&gt;FABRIC&lt;/code&gt;. Versions come only from Mojang + Paper + &lt;code&gt;meta.fabricmc.net&lt;/code&gt; + Forge &lt;code&gt;promotions_slim.json&lt;/code&gt;. No separate NeoForge/Quilt API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Files in the browser&lt;/strong&gt; — browse server dirs, upload, download, edit configs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live logs + RCON console&lt;/strong&gt; over WebSocket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Players&lt;/strong&gt; — online, ban, op, whitelist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mods&lt;/strong&gt; — install / remove / enable / disable server and client mods (&lt;code&gt;mods-client/*.jar&lt;/code&gt;, &lt;code&gt;resourcepacks&lt;/code&gt;, &lt;code&gt;shaderpacks&lt;/code&gt;, including &lt;code&gt;*.disabled&lt;/code&gt;). Search and metadata only via Modrinth (&lt;code&gt;modrinth&lt;/code&gt; is the only &lt;code&gt;ContentSource&lt;/code&gt;). No CurseForge API integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crash reports and resources&lt;/strong&gt; — separate tabs, no need to dig files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client archive in 4 formats&lt;/strong&gt; — &lt;code&gt;zip&lt;/code&gt;, &lt;code&gt;mrpack&lt;/code&gt;, &lt;code&gt;curseforge&lt;/code&gt;, &lt;code&gt;prism&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;zip&lt;/code&gt;: plain &lt;code&gt;mods/&lt;/code&gt;, &lt;code&gt;resourcepacks/&lt;/code&gt;, &lt;code&gt;shaderpacks/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mrpack&lt;/code&gt;: &lt;code&gt;overrides/mods/...&lt;/code&gt; + &lt;code&gt;modrinth.index.json&lt;/code&gt;, but simplified — &lt;code&gt;FormatVersion: 1&lt;/code&gt;, &lt;code&gt;VersionID: 1.0.0&lt;/code&gt;, empty &lt;code&gt;Hashes: {}&lt;/code&gt;, no dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;curseforge&lt;/code&gt;: &lt;code&gt;manifest.json&lt;/code&gt; with &lt;code&gt;minecraftModpack&lt;/code&gt; + &lt;code&gt;overrides/...&lt;/code&gt;. Export only, not CurseForge API.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prism&lt;/code&gt; (main one for Sync): &lt;code&gt;instance.cfg&lt;/code&gt; + &lt;code&gt;mmc-pack.json&lt;/code&gt; + &lt;code&gt;.minimin.json&lt;/code&gt; (&lt;code&gt;serverId, token, baseUrl&lt;/code&gt;) + files under &lt;code&gt;.minecraft/mods/...&lt;/code&gt;. Plus &lt;code&gt;/info&lt;/code&gt;, &lt;code&gt;/manifest&lt;/code&gt; (with SHA-256), &lt;code&gt;/file/{path}&lt;/code&gt; endpoints for diff sync.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled backups already exist&lt;/strong&gt; — via scheduler (&lt;code&gt;interval|cron|event&lt;/code&gt; -&amp;gt; &lt;code&gt;backup&lt;/code&gt; with &lt;code&gt;keepLast/keepDays&lt;/code&gt;). But only &lt;code&gt;world/&lt;/code&gt; is archived to &lt;code&gt;tar.gz&lt;/code&gt; + &lt;code&gt;save-off/save-all&lt;/code&gt; via RCON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No multi-user&lt;/strong&gt; — single static &lt;code&gt;ORCHESTRATOR_API_KEY&lt;/code&gt; (Bearer/cookie/query). &lt;strong&gt;No OpenWrt build.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frontend: Nuxt 4 + Vue 3 + TailwindCSS. Backend: Go + Docker SDK, REST + WebSocket.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. MiniMin Sync — desktop client for friends
&lt;/h3&gt;

&lt;p&gt;A friend doesn't need a panel. Paste a link, hit sync, play.&lt;/p&gt;

&lt;p&gt;Sync is a separate Wails app (Go + Vue 3 + Tailwind, no Electron). No button inside Prism: it launches instances externally via CLI &lt;code&gt;--launch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How it works (as in code):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works only with &lt;code&gt;?format=prism&lt;/code&gt;. Downloads the prism-zip, extracts with Zip Slip protection, writes a &lt;code&gt;.minimin.json&lt;/code&gt; marker (&lt;code&gt;serverId, token, baseUrl, lastSyncAt&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Update check — diffs local files against &lt;code&gt;/manifest&lt;/code&gt;: &lt;code&gt;missing&lt;/code&gt; / &lt;code&gt;outdated&lt;/code&gt; (size or SHA-256 mismatch) / &lt;code&gt;orphan&lt;/code&gt; (extras only in top level of &lt;code&gt;mods, resourcepacks, shaderpacks, scripts, kubejs, defaultconfigs&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Update — downloads only changed files with 4 workers, renames old ones to &lt;code&gt;.minimin-backup/&lt;/code&gt;, checks free disk space, post-verifies SHA-256, rolls back on mismatch.&lt;/li&gt;
&lt;li&gt;Background check — yes, but only while the app is open: &lt;code&gt;autoCheckLoop&lt;/code&gt; every 5 min by default. No OS autostart, no tray.&lt;/li&gt;
&lt;li&gt;Launchers — only 3 hardcoded: Prism Launcher, ElyPrismLauncher, MultiMC (standard paths + &lt;code&gt;PATH&lt;/code&gt;, &lt;code&gt;--launch &amp;lt;serverID&amp;gt;&lt;/code&gt; with fallbacks). Nothing else.&lt;/li&gt;
&lt;li&gt;Knows nothing about game / loader versions — just mirrors files from the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple idea: server side owns "how to build", client side owns "how not to break the player".&lt;/p&gt;
&lt;h2&gt;
  
  
  Run in 5 minutes
&lt;/h2&gt;

&lt;p&gt;Only Docker and Docker Compose needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;minimin &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;minimin

&lt;span class="c"&gt;# fetch compose and env template&lt;/span&gt;
curl &lt;span class="nt"&gt;-O&lt;/span&gt; https://raw.githubusercontent.com/quonaro/minimin/main/docker-compose.yml
curl &lt;span class="nt"&gt;-o&lt;/span&gt; .env https://raw.githubusercontent.com/quonaro/minimin/main/.env.example

&lt;span class="c"&gt;# edit .env — ORCHESTRATOR_API_KEY and MC_SERVERS_HOST_DIR are required&lt;/span&gt;
nano .env

docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# open http://localhost:8081&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All in one &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ORCHESTRATOR_API_KEY&lt;/code&gt; — login key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MC_SERVERS_HOST_DIR&lt;/code&gt; — host path for servers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ORCHESTRATOR_LOG_LEVEL&lt;/code&gt;, &lt;code&gt;MC_SERVERS_DIR&lt;/code&gt;, &lt;code&gt;MODRINTH_CUSTOM_URL&lt;/code&gt; — optional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For dev there is &lt;code&gt;dev.yml&lt;/code&gt; with hot reload: frontend on &lt;code&gt;:3000&lt;/code&gt;, backend on &lt;code&gt;:8081&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback needed
&lt;/h2&gt;

&lt;p&gt;This covers my flow: gather for a weekend, play, split.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;mrpack&lt;/code&gt; is simplified now (no hashes / deps). Do you need a full Modrinth format with hashes, or is &lt;code&gt;prism&lt;/code&gt; + &lt;code&gt;zip&lt;/code&gt; enough? Do you need import of foreign &lt;code&gt;mrpack&lt;/code&gt; / CurseForge packs?&lt;/li&gt;
&lt;li&gt;NeoForge is now an alias to FORGE, Quilt to FABRIC, no separate versions. Do you need honest NeoForge/Quilt with separate loader versions, or is aliasing enough?&lt;/li&gt;
&lt;li&gt;Sync is a separate window now, check every 5 min only while open, no autostart/tray, launchers only Prism/ElyPrism/MultiMC. What matters more: autostart + tray, headless daemon without GUI, or more launchers?&lt;/li&gt;
&lt;li&gt;Scheduled backups exist but only &lt;code&gt;world/&lt;/code&gt; + &lt;code&gt;keepLast/keepDays&lt;/code&gt;. Do you need full server backup (mods+configs), or is world enough? Is multi-user needed (single API key now)? Are docs for weak hardware / OpenWrt interesting?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading. I'll catch all the tomatoes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshots (Server):
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Logs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk08qwun5kffgw7oeek0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkk08qwun5kffgw7oeek0.png" alt="Logs" width="780" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Server properties:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ixtldsvgden4bx8d07w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ixtldsvgden4bx8d07w.png" alt="Properties" width="780" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  File Manager
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxbvafwshy7mirb9i4hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffxbvafwshy7mirb9i4hq.png" alt="File Manager" width="780" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Crash Report
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6hmlycb9ve197ho4ppfr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6hmlycb9ve197ho4ppfr.png" alt="Crash Report" width="780" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  RCON Console
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu4pp6jl32dh2okcox0j2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu4pp6jl32dh2okcox0j2.png" alt="RCON Console" width="780" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Players
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwcn0yx6ugvm1ndjrb4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkwcn0yx6ugvm1ndjrb4z.png" alt="Players" width="780" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Client / Server Resources (Mods)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwzx9njmzzb9mlx48a39p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwzx9njmzzb9mlx48a39p.png" alt="Mods" width="780" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Modrinth Library Integration
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1fulkypqq5ee4v3gob3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1fulkypqq5ee4v3gob3b.png" alt="Modrinth" width="572" height="696"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Export Page
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyhu06j5nzoh7f4vwvtur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyhu06j5nzoh7f4vwvtur.png" alt="Export Page" width="780" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshots (Client):
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17stx6xa2u8kaigmqj8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F17stx6xa2u8kaigmqj8s.png" alt="Sync#1" width="780" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhm5t4zh2l9asi95nue7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frhm5t4zh2l9asi95nue7.png" alt="Sync#2" width="780" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0jfogo2o2lasomfj7qqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0jfogo2o2lasomfj7qqi.png" alt="Sync#3" width="780" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumo6vm8e9c1xxns0x24h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fumo6vm8e9c1xxns0x24h.png" alt="Sync#4" width="780" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>showdev</category>
      <category>selfhosted</category>
      <category>minecraft</category>
    </item>
  </channel>
</rss>
