Dartastic Pub

Pub.dev, Privately

Dartastic Pub has a familiar pub.dev feel, but your packages are private. Share your releases with your team, customers, development partners, and testers, without sharing with the world.

Dartastic Pub speaks the same protocol as pub.dev. Familiar commands like dart pub publish and flutter pub get work unchanged. Mint tokens in the Dartastic dashboard, scope them to specific packages with read or read/write privileges. Consumers register tokens with the standard dart pub token add to access your private registry. Works in CI/CD systems. No new tooling. No new mental model.

Includes
  • Your own private pub for your private Dart and Flutter packages.
  • Familiar pub.dev feel with new capabilities.
  • Team and app management.
  • Fine-grained access control with fast revocations.
  • Daily backups, dual-region storage.
  • Free with 100 MB, enough for dozens of packages.
  • Just $4/mo for 10 GB per member of your organization, pooled.
  • Dartastic Pub uses shared infrastructure. Dartastic Pub on private infrastructure is available with Dartastic Observatory and Dartastic OTel plans.

Git Tags Aren't a Package Manager.

Every Dart team starts the same way: the shared package moves to its own repo, the pubspec grows a git: ref and it works. Then the second app appears, the second team, the first partner... and the easy solution breaks down. To be fair to path: dependencies inside one repo, with melos, they're great. The trouble starts when code crosses a repo, a team, or a company boundary. That's when tags fall apart:

  • Share your packages, not your repo. There's no way to hand a customer a git dependency without handing them repo access. With Dartastic Pub you can allow access per-package, watch the access logs, and revoke access the moment the contract ends.
  • No pub, no memory. Which internal packages exist? What changed in 2.3.0? Which version supports the new SDK? With git dependencies the answer lives in Slack. A pub registry renders READMEs, changelogs, and version history. New teammates browse instead of searching or asking.
  • Your tooling goes blind. dart pub outdated and constraint-based upgrades reason over hosted version lists. Git refs are opaque to them. And packages published to pub.dev aren't allowed git dependencies at all, so internal shared code on git tags caps what you can ever ship publicly.
  • Tags move. Archives don't. A tag can be force-pushed, a branch rewritten, a repo renamed, a commit garbage-collected. Your lockfile pins a commit hash, but nothing guarantees that commit stays fetchable. A published version on a registry is an immutable archive. The build that passed yesterday fetches the same bytes next year.
  • Git dependencies are fat. Git fetches the entire history. Every branch, every experiment, every secret someone committed and "deleted" three years ago. A pub package ships the published files of one version. Nothing else.
  • One ref is not version solving. A git dependency pins exactly one commit. The solver can't try other versions. The day one package needs shared_models at v2 while another still needs v1, resolution simply fails, and you're coordinating a lockstep upgrade across every consumer. A registry gives pub a version list, so ^1.2.0 constraints resolve the way they do on pub.dev. (Dart 3.9's tag_pattern can now feed tags to the solver, credit where due. Every problem below still stands.)
  • Your lockfile is your bill of materials. An opinion we'll defend: pubspec.lock ships with the app. It is the BOM, the exact parts list of the build you released. With hosted dependencies, every entry carries a name, an exact version, and a sha256 of the archive. Auditors can verify it. You can rebuild from it. A git dependency's entry is a repo URL and a commit hash. There is no content hash of the package, and the pointer dangles the day history moves. Reviews suffer too. A hosted lock diff reads like "1.2.3 to 1.2.4", while a git lock diff swaps one forty-character hash for another. Nobody can tell a patch from a rewrite. And a checked-in lock can lull a team: one dev upgrades and forgets to commit, another pulls and skips pub get, and now two devs read the same pubspec while running different code. If the package is a library, consumers never see your lock at all. You tested a dependency set your users will never run.
  • Pub clones the repository. All of it. Resolving a git dependency fetches the repo, history included, to deliver one package. A hosted dependency downloads one small archive of one version, cached. Your CI feels the difference on every fresh run.
  • dart pub publish is a quality gate. A tag is not. Publishing validates the version bump, the changelog, the analysis; releasing is a deliberate act. Anyone can tag anything, including broken code and a pubspec whose version disagrees with the tag name.
Git tag · one pinned commit
dependencies:
  shared_models:
    git:
      url: git@github.com:acme/shared_models.git
      ref: v1.2.0   # repo creds required,
                    # no ranges, tag can move
Dartastic Pub · solves like pub.dev
dependencies:
  shared_models:
    hosted: https://pub.dartastic.io
    version: ^1.2.0   # per-package token,
                      # immutable archives

Even Dart's own documentation points teams at a package repository for collaborative work. Dartastic Pub is that repository, minus the running of it. Start free. Outgrow it for the price of a coffee.

Things git hosting can't do at all

Retract without breaking builds

Shipped a bad version? Retract it: the solver stops picking it, while builds already pinned to it keep working. Deleting a git tag does the opposite: it breaks every consumer pinned to it, immediately. When your registry is private, publishing isn't "forever."

Crash reports that name your source

Flutter apps published here ship their .symbols in the archive. The Dartastic Symbolizer auto-fetches them and turns obfuscated production stack traces into real file and line. One publish per release. A git tag carries no artifacts at all.

Run like infrastructure

Per-package publish and read tokens, access logs, revocations in seconds, daily dual-region backups. Your dependency supply chain, treated like the production system it is.

Quick start

One-time per machine: register the token. Then publish or consume like normal pub.dev. Just point at pub.dartastic.io.

# Mint a key on dartastic.io/dashboard?tab=tokens with the `pub` scope
# (the plaintext key is shown ONCE at mint time). Then paste it after you run this:
dart pub token add https://pub.dartastic.io

Don't use the interactive dart pub token add: its silent Enter secret token: prompt truncates Dartastic's long signed tokens, so it appears to hang. Pipe the token in, as above.

Publishing
# pubspec.yaml
name: my_private_package
version: 1.0.0
publish_to: https://pub.dartastic.io
dart pub publish
Consuming
# pubspec.yaml
dependencies:
  my_private_package:
    hosted: https://pub.dartastic.io
    version: ^1.0.0

Subscribe to get access

Dartastic Pub gets you the private pub server. Symbolizer adds the Dartastic Symbolizer and the OTel Dev runtime.

See Dartastic Pub plans and pricing