Docs
Pub needs your token on every machine that publishes or installs your packages. Start with the basic setup, then follow the guides for your editor, your agents and your CI.
For agents and LLMs: this page as markdown or llms.txt
Do this once on each computer that publishes or installs your packages. Flutter reads the same tokens as Dart, so it covers flutter pub too.
Create an account or sign in, then create a token. It stays hidden on the account page until you show it, and you can come back later to copy it again.
Run this and paste the token when pub asks for it. Pub saves it and sends it with every request to this server.
dart pub token add https://private-pub.dev
Run dart pub token list
to check that it was saved.
Set publish_to
in the package's pubspec.yaml, then publish it as usual. It starts in your personal team, so only its members can see it, unless an optional
private_pub.team
names another team you can publish to. The server checks every upload the way pub.dev does, and the
package requirements
list what it looks for.
name: my_package description: A short sentence about what the package does. version: 1.0.0 publish_to: https://private-pub.dev
dart pub publish
Choose how your apps get packages. Both ways use the token you added.
Set PUB_HOSTED_URL and every dependency comes from here, your packages and pub.dev packages alike. Add it to your shell profile, such as ~/.zshrc, so every terminal gets it.
export PUB_HOSTED_URL=https://private-pub.dev
Mark the dependencies that should come from this server with hosted, and the rest keep coming straight from pub.dev.
dependencies:
my_package:
hosted: https://private-pub.dev
version: ^1.0.0To add a private package from the command line, name this server with it. In a Flutter app, run flutter pub add
instead.
dart pub add 'my_package:{"hosted":"https://private-pub.dev"}'If a project uses the mirror, set PUB_HOSTED_URL
everywhere pub runs for it, including your editor, your agents and CI. The guides below show how.
The Dart and Flutter extensions run pub with your SDK, so they use the token from the basic setup. Dependencies marked with hosted need nothing else.
If you export PUB_HOSTED_URL
in your shell profile, restart VS Code so it picks the variable up. To set it for one project and share it with your team, put it in the workspace settings instead. The file holds no secrets, so commit it.
{
"dart.env": {
"PUB_HOSTED_URL": "https://private-pub.dev"
},
"terminal.integrated.env.osx": {
"PUB_HOSTED_URL": "https://private-pub.dev"
},
"terminal.integrated.env.linux": {
"PUB_HOSTED_URL": "https://private-pub.dev"
},
"terminal.integrated.env.windows": {
"PUB_HOSTED_URL": "https://private-pub.dev"
}
}
dart.env
covers the pub commands the extensions run, like the one after you save pubspec.yaml. The terminal settings cover the commands you type in the integrated terminal, once you trust the workspace.
If you added the token with --env-var, pub reads it from that variable every time it runs, so VS Code has to see the variable too. On your own computer, a plain
dart pub token add
is simpler.
Agents run pub in a shell, so they need what your terminal needs: your token, and PUB_HOSTED_URL if you use the mirror. They also need to know which packages live here.
Claude Code runs commands as you, so it uses the token you already added.
To use the mirror, set PUB_HOSTED_URL
in the project's settings. Every command Claude runs gets it, and cloud sessions read the same file.
With sandboxing on, Claude Code asks before a command reaches a new domain. Allow private-pub.dev
up front so pub never waits on the prompt.
{
"env": {
"PUB_HOSTED_URL": "https://private-pub.dev"
},
"sandbox": {
"network": {
"allowedDomains": ["private-pub.dev"]
}
}
}
Cloud sessions start on a fresh machine without Dart, Flutter or your token. Set them up in the cloud environment settings at claude.ai/code.
On Pro and Max plans, add an API credential with private-pub.dev
under Allowed websites and your token as the Authorization
header, with the Bearer
prefix. The proxy adds it to every request to this server, so the token never reaches the session and pub needs no setup.
On other plans, add PRIVATE_PUB_TOKEN
under Environment variables. Anyone who uses the environment can read it, so keep it in a personal environment, not a shared one. Set Network access to Custom, add
private-pub.dev
to Allowed domains, and check Also include default list of common package managers so pub.dev still works.
Either way, install Dart or Flutter in the Setup script. With the environment variable, add the token to pub there too.
#!/bin/bash set -e # Install Dart or Flutter here, then: dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
Unless the project uses the mirror, a plain dart pub add
looks for packages on pub.dev. Say where private packages live in CLAUDE.md, or in AGENTS.md for other agents.
## Private packages
Private packages are hosted on https://private-pub.dev. Add one with:
```sh
dart pub add 'package_name:{"hosted":"https://private-pub.dev"}'
```
See https://private-pub.dev/llms.txt for how to use the server.
Codex, Cursor, GitHub Codespaces and anything else that runs on a machine of its own work the same way. Store a service account token as a secret environment variable and add it to pub with
--env-var
before pub get. A personal token is fine on a machine only you use. The machine also needs to reach
private-pub.dev.
dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
In CI, pub reads the token from an environment variable, so it never goes in the repository.
In the repository on GitHub, open Settings, then Secrets and variables, then Actions. Add a repository secret called
PRIVATE_PUB_TOKEN
with a service account token.
Create a service account and add it to every team the job needs, as a reader to install or a writer to publish. One token reaches all of those teams, so CI never needs your own token, which can publish every package you can. A team key still works for a single team. The teams guide covers service accounts.
Set the secret for the whole job, not just one step, because pub reads it every time it runs.
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
PRIVATE_PUB_TOKEN: ${{ secrets.PRIVATE_PUB_TOKEN }}
PUB_HOSTED_URL: https://private-pub.dev # Only if you use the mirror
steps:
- uses: actions/checkout@v6
- uses: dart-lang/setup-dart@v1
- run: dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
- run: dart pub get
- run: dart testFor a Flutter app, set up Flutter instead and run the flutter commands:
steps:
- uses: actions/checkout@v6
- uses: subosito/flutter-action@v2
with:
channel: stable
- run: dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
- run: flutter pub get
- run: flutter testWorkflows run for pull requests from forks don't get your secrets, and neither do the ones Dependabot starts. If Dependabot updates this project, add
PRIVATE_PUB_TOKEN
as a Dependabot secret too.
Very Good Workflows run pub get before their setup
input, so they can't add the token in time. Use a job like this one for projects with private dependencies.
Run dart pub publish --force, which skips the confirmation prompt. This workflow publishes whenever you push a version tag.
name: Publish
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
env:
PRIVATE_PUB_TOKEN: ${{ secrets.PRIVATE_PUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: dart-lang/setup-dart@v1
- run: dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
- run: dart pub publish --forceCodemagic keeps the token in a secret environment variable, and your workflow adds it to pub before getting packages.
Open the app's settings in Codemagic and go to the Environment variables tab. Add a variable named PRIVATE_PUB_TOKEN
with a service account token as its value, put it in a group called private_pub, select Secret and click Add.
With codemagic.yaml, import the group and add the token before flutter pub get.
Codemagic runs each script in a shell of its own, so set PUB_HOSTED_URL
under vars, not with export.
workflows:
build:
name: Build
environment:
flutter: stable
groups:
- private_pub
vars:
PUB_HOSTED_URL: https://private-pub.dev # Only if you use the mirror
scripts:
- name: Add the Private Pub token
script: dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN
- name: Get packages
script: flutter pub get
- name: Test
script: flutter testWith the Workflow Editor, add the token command to the Post-clone script, which runs before Codemagic installs dependencies.
To use the mirror, also add PUB_HOSTED_URL
on the Environment variables tab.
#!/bin/sh set -e dart pub token add https://private-pub.dev --env-var PRIVATE_PUB_TOKEN