Update modules without redeploying your site.
Packdog is a registry for the modules that ship to your live site — widgets, embeds, mini-apps, games, anything that updates more often than your main build. Scoped tokens per developer, staging by default, instant rollback.
Founding-customer pilot: 30 days free, no card required. Pay only if it works.
$ packdog upload
✓ 3 files, 45.2 KB
✓ Published to stage: 7c91a0f3-...
$ packdog publish
✓ Promoted to stable: 7c91a0f3-...
$ packdog rollback --channel=stable
✓ Rolled back to: 4b2d5e8c-... If any of this sounds familiar
Module shipping breaks in three predictable places.
- 01
You hand a consultant a GitHub branch
Now they can see your auth code, your billing logic, your half-finished next-quarter feature. You don't want to. You do it anyway because the alternative is a Slack-and-zip-file dance.
- 02
Old keys live forever
Engagements end and people move on, but the tokens they pushed with stay alive in CI variables, environment files, and laptops that left the building. Three years in, nobody can say who currently has push access.
- 03
Something ships broken at 22:00
Your last good version is a tag in a repo. Recovering it means a redeploy, cache busts, and a five-minute apology in the customer Slack.
The model
Versions are immutable. Channels are pointers.
You’ve moved a Git branch before — the name stays put while the commit it points at can change. Packdog channels are that idea, for shipped code.
Every upload becomes an immutable version with its own URL. A channel — stable, beta, anything — is a pointer to a version. Browsers fetch whichever version the channel currently points to.
Updating means re-pointing the channel. Rolling back means re-pointing to an earlier version. That’s the whole thing.
How it works
Three commands. That's the whole loop.
- 01
Upload
Build to
dist/and runpackdog upload. The CLI creates an immutable version, auto-publishes tostage, and prints the version id. - 02
Verify, then promote
Check the new version against the
stagechannel. When happy, runpackdog publishto pointstableat it. Browser clients pick it up on the next load. - 03
Roll back atomically
Each channel has its own history chain.
packdog rollback --channel=stablesteps one version back, in milliseconds — no redeploy, no cache to bust.
Why not just use…
Packdog vs. the obvious alternatives.
Most teams reach for npm, GitHub Packages, or "stick it on S3 behind a CDN." Each works for something else.
| Capability | Packdog | npm | GitHub Packages | S3 / R2 + CDN |
|---|---|---|---|---|
| Designed for runtime browser loading | Yes | No (build-time) | No (build-time) | Yes |
| Scoped per-package access tokens | Yes | Org-wide only | Org-wide only | No |
| Per-channel rollback history | Yes | No | No | No |
| Revoke push access in seconds | Yes | Org-level only | Org-level only | Manual key rotation |
| Usage metering per customer per package | Yes | No | No | CDN-level only |
| Immutable versions, CDN-cached forever | Yes | Yes | Yes | DIY |
| Self-service organization admin | Yes | Org settings | Org settings | DIY |
| Time to first publish | Minutes | 10 min | 30 min | 1+ day setup |
What you actually get
A registry built for runtime delivery.
Ship to the live web without coupling module updates to your main deploy. Same model the platforms use for their own internals — now hosted, scoped, and metered.
Stop sharing repo access
Per-developer tokens, scoped per package. They push to staging, you promote to stable.
Revoke in one command
One CLI call. Their next push fails. Their old pushes stay tracked under their name in your audit trail.
Roll back without redeploying
One CLI call steps a channel back. No cache to bust, no main app build to wait for, no App Store review to redo.
Pay per load, not per seat
$2 per 1000 loads. No per-developer fee, no minimums. Adding a developer costs nothing until they ship traffic.
Files served from Cloudflare's edge
Immutable URLs, cached forever. The Worker only handles metadata — your modules load as fast as static assets.
See exactly what is being loaded
Every load is logged to Cloudflare Analytics Engine — queryable per package, per customer key, per developer. Use it to bill, to attribute, or just to know.
Replace your module handoff. Pay only if it works.
- 30 days of full Packdog access
- Async white-glove setup — send a folder, get tokens back
- Direct Slack line to the founder for the pilot’s duration
- $2 per 1000 loads, locked in for life
- After pilot: monthly invoice, no minimums, no commitment
No risk
30 days free, no card to start. If Packdog doesn’t replace your handoff, just don’t enable billing — there’s nothing to cancel.
Three things
- I.
A consultant should push your module
not browse your code.
- II.
A module update should be a publish
not a deploy.
- III.
Rollback should be a CLI call
not a redeploy.
FAQ
Eight questions you're probably about to ask.
What if you (Finn) get hit by a bus?
Honest answer: this is a one-person shop today. Source code is on Cloudflare and in a private GitHub repo at Jetbit AS. If something happens to me, the company has the access. The most realistic 'bus risk' mitigation is the lifetime locked-in pricing — you're not stuck on a rising bill if growth makes me hire.
Why not just use GitHub Packages or npm?
Both are designed for build-time package consumption. Packdog is for runtime browser loading: you upload once, browsers fetch from the edge on every page view, and you can roll back without a redeploy. See the comparison table above for the full diff.
How are loads counted exactly?
Every successful GET /v1/packages/{id}/channels/{channel} that resolves to a version is one load. Failed auth, 404s, and 304s don't count. Logged in real-time to Cloudflare Analytics Engine, queryable from the admin API.
What languages or frameworks does my module need to use?
None specifically. If your build process produces a directory with an index.js, Packdog accepts it. Vite, esbuild, Rollup, plain tsc, or hand-written JS — all work. ES modules, web components, plain bundles.
What happens if a developer pushes a broken version?
That's why channels exist. Set their can_publish flag to false; they upload to a stage version, you promote to stable once it's verified. If you've already promoted and a bug surfaces: packdog rollback --channel=stable steps back atomically. No redeploy.
Where is data stored, and is this GDPR-safe?
Cloudflare D1 (metadata) and Cloudflare R2 (files), in the EU region. No customer-identifiable data is required to use Packdog itself — the keys are random tokens, not user accounts. If your modules collect user data, that's your pipeline, not Packdog's.
Can my developers push from CI?
Yes. Developer tokens (dev_*) are designed for CI. Set PACKDOG_TOKEN as a CI secret; the CLI reads it. Same one-line install (npm i -g packdog) as on a laptop.
How does onboarding actually work?
Send me your dist/ folder and package names by email. I'll set up your organization, generate scoped tokens for your developers, and send back a ready-to-paste integration snippet plus your first published version on stable. Packdog is a side-project for me right now, so most onboardings happen evenings or weekends — usually within a day, never longer than three.
Five pilots. Then early-customer pricing.
Each founding-customer slot shapes what Packdog ships next. Once they’re full, the next cohort goes onto a wait list at standard pricing.