<?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: Timophei Lemeshchenko</title>
    <description>The latest articles on DEV Community by Timophei Lemeshchenko (@another1dd).</description>
    <link>https://dev.to/another1dd</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%2F4051093%2F0ec7c31b-9dd6-4f59-8a17-4550e000795c.jpg</url>
      <title>DEV Community: Timophei Lemeshchenko</title>
      <link>https://dev.to/another1dd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/another1dd"/>
    <language>en</language>
    <item>
      <title>Sharing private Flutter packages shouldn't cost this much (so I built a free registry)</title>
      <dc:creator>Timophei Lemeshchenko</dc:creator>
      <pubDate>Tue, 28 Jul 2026 10:39:05 +0000</pubDate>
      <link>https://dev.to/another1dd/sharing-private-flutter-packages-shouldnt-cost-this-much-so-i-built-a-free-registry-4k3j</link>
      <guid>https://dev.to/another1dd/sharing-private-flutter-packages-shouldnt-cost-this-much-so-i-built-a-free-registry-4k3j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; I built &lt;a href="https://publy.dev" rel="noopener noreferrer"&gt;Publy&lt;/a&gt;, the tool this post ends up recommending. It started as a fix for my own problem, not a product — and this is the honest version of how it happened.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you've ever tried to share private Dart or Flutter code across more than one repo, you already know the two roads in front of you, and you already know both of them hurt.&lt;/p&gt;

&lt;p&gt;Road one: a &lt;strong&gt;paid private pub registry&lt;/strong&gt;. It works, &lt;code&gt;dart pub&lt;/code&gt; is happy, and the bill climbs every time your team or your package count grows.&lt;/p&gt;

&lt;p&gt;Road two: &lt;strong&gt;git dependencies&lt;/strong&gt;. It's free, and it quietly turns your &lt;code&gt;pubspec.yaml&lt;/code&gt; into a minefield.&lt;/p&gt;

&lt;p&gt;I spent a long time on both. Here's what actually went wrong, and what I did about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The git-dependency trap
&lt;/h2&gt;

&lt;p&gt;For a while my team went the free route — pull internal packages straight from git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app_core&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;git&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git@github.com:our-org/app-core.git&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks fine on day one. It falls apart on week three.&lt;/p&gt;

&lt;p&gt;The moment you reference a package &lt;strong&gt;by branch or tag instead of a version&lt;/strong&gt;, you throw away everything &lt;code&gt;pub&lt;/code&gt;'s version solver does for you. There are no version constraints — &lt;code&gt;^1.4.0&lt;/code&gt; means nothing when you're pinned to &lt;code&gt;ref: main&lt;/code&gt;. Two apps depending on the same internal package at two different commits? The solver can't reconcile that, because as far as it's concerned they're the same unversioned thing.&lt;/p&gt;

&lt;p&gt;So you end up doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependency_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app_core&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;git&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git@github.com:our-org/app-core.git&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;a3f9c21&lt;/span&gt;   &lt;span class="c1"&gt;# the "known good" commit, do not touch, nobody remembers why&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dependency_overrides&lt;/code&gt; is meant to be a temporary, local escape hatch. When it becomes the &lt;em&gt;only&lt;/em&gt; way your dependency graph resolves, that's not a workaround anymore — that's your architecture, and it's a bad one. Every new package multiplied the pain. Across two internal SDK monorepos we had &lt;strong&gt;50+ packages&lt;/strong&gt; depending on each other, and the git approach turned every version bump into a manual archaeology dig through commit hashes.&lt;/p&gt;

&lt;p&gt;The whole point of semantic versioning and &lt;code&gt;pub&lt;/code&gt;'s solver is that you &lt;em&gt;don't&lt;/em&gt; do this. Git dependencies opt you out of the one thing that makes Dart's package management good.&lt;/p&gt;

&lt;h2&gt;
  
  
  The paid-registry trap
&lt;/h2&gt;

&lt;p&gt;So we did the sensible thing and moved to a hosted private registry. And it was genuinely better — real versions, &lt;code&gt;dart pub publish&lt;/code&gt;, the solver working again.&lt;/p&gt;

&lt;p&gt;Then the invoice showed up.&lt;/p&gt;

&lt;p&gt;I won't name numbers, but the pricing scaled per seat, and even with a &lt;strong&gt;small team of 3 developers plus CI/CD&lt;/strong&gt;, hosting our internal packages had become one of those line items you keep meaning to "look into." For a handful of private packages that just needed a place to live, the cost-to-value ratio stopped making sense. I was also paying out of pocket to host packages for my own side projects — and &lt;em&gt;that&lt;/em&gt; math was even harder to justify.&lt;/p&gt;

&lt;p&gt;I did not want a fancy product. I wanted the boring thing: a place to &lt;code&gt;dart pub publish&lt;/code&gt; internal packages, with real versions, that didn't charge me per human.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I built Publy
&lt;/h2&gt;

&lt;p&gt;I'm a Flutter dev, not a SaaS founder, and I built this because the alternatives annoyed me — so it's deliberately small. &lt;a href="https://publy.dev" rel="noopener noreferrer"&gt;Publy&lt;/a&gt; is a private Dart &amp;amp; Flutter package registry that implements the &lt;a href="https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md" rel="noopener noreferrer"&gt;standard pub hosted repository spec&lt;/a&gt;. That last part matters: there's no custom CLI, no plugin, no wrapper. &lt;code&gt;dart pub publish&lt;/code&gt; and &lt;code&gt;dart pub get&lt;/code&gt; work exactly like they do against pub.dev, because to &lt;code&gt;dart&lt;/code&gt; it &lt;em&gt;is&lt;/em&gt; just a hosted registry.&lt;/p&gt;

&lt;p&gt;Setup is three commands and one &lt;code&gt;pubspec&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Authenticate the CLI&lt;/strong&gt; (after signing in with GitHub and creating an org + token):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub token add https://publy.dev/o/your-org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Tell a package where to publish&lt;/strong&gt; — in that package's &lt;code&gt;pubspec.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;publish_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://publy.dev/o/your-org&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dart pub publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Consume it from another repo&lt;/strong&gt; like any hosted dependency — real version constraints, back at last:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app_core&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;hosted&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://publy.dev/o/your-org&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.4.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;^1.4.0&lt;/code&gt; is the whole reason this exists. The solver is doing its job again. No &lt;code&gt;ref&lt;/code&gt;, no commit hash, no &lt;code&gt;dependency_overrides&lt;/code&gt; graveyard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is and isn't
&lt;/h2&gt;

&lt;p&gt;Being honest about scope, since I hate posts that oversell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's free.&lt;/strong&gt; Not free-trial, not free-tier-with-an-asterisk — the plan you'd use for a small team costs nothing. I built it so I'd stop paying for this, so charging small teams would defeat the point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth is GitHub OAuth&lt;/strong&gt; for the web UI and &lt;strong&gt;bearer tokens&lt;/strong&gt; for the CLI / CI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versions are immutable&lt;/strong&gt; — republishing the same &lt;code&gt;name@version&lt;/code&gt; is a 409, never a silent overwrite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's young.&lt;/strong&gt; No per-package ACLs, no download analytics, no billing gymnastics. If you need enterprise compliance features today, this isn't that yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're a small-to-medium Flutter team quietly bleeding money on a private registry, or worse, drowning in git-dependency overrides — this is aimed squarely at you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;You can be publishing in about five minutes: &lt;a href="https://publy.dev" rel="noopener noreferrer"&gt;publy.dev&lt;/a&gt;, and the &lt;a href="https://publy.dev/docs/getting-started" rel="noopener noreferrer"&gt;getting-started guide&lt;/a&gt; is the same three commands above with pictures.&lt;/p&gt;

&lt;p&gt;If you try it and something's broken or missing, tell me — genuinely. It exists because I hit a wall, and the fastest way to make it good is other people hitting different walls.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's your current setup for private Flutter packages — paid registry, git deps, or something cleverer? Curious what everyone else landed on.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>devops</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
