Publishing Packages and Integrations

Purpose and Scope

Dub publishes several reusable packages from the monorepo and also maintains marketplace-style integrations that are released through vendor tooling rather than npm alone. This page explains the release surfaces that are visible in the repository: root publishing scripts for npm packages, package-level build metadata for the CLI, embeds, UI, and utils packages, and separate operational workflows for the Stripe and HubSpot app packages. The goal is to help maintainers know which command owns which artifact, what each package exposes publicly, and where integration release steps leave the pnpm/turborepo flow and move into a third-party platform.

Sources: package.json, packages/cli/package.json, packages/embeds/core/package.json, packages/embeds/react/package.json, packages/ui/package.json, packages/utils/package.json, packages/stripe-app/README.md, packages/hubspot-app/README.md

The repository is private as a monorepo package, uses pnpm as its package manager, and coordinates builds through Turborepo. That root package is not the artifact being published; instead, it provides orchestration scripts such as publish-cli, publish-embed-core, publish-embed-react, publish-ui, and publish-utils. Each publishing script first runs a filtered turbo build for the relevant package, then changes into that package directory and runs npm publish. This makes the root manifest the release command index while preserving package-specific manifests as the source of package names, output files, binaries, exports, and npm access settings.

Sources: package.json

Relevant Source Files

  • package.json — Defines monorepo-level build, test, formatting, and publish scripts, including filtered Turborepo builds followed by npm publish for public packages.
  • packages/cli/package.json — Describes the dub-cli npm package, its dub binary, build scripts, public publish configuration, and dependency set for OAuth, prompts, config storage, and Dub API access.
  • packages/embeds/core/package.json — Defines the @dub/embed-core package as the vanilla JavaScript embed core, including its dist outputs and public npm publish configuration.
  • packages/embeds/react/package.json — Defines the @dub/embed-react package, its React peer dependency contract, dependency on @dub/embed-core, preview command, and prepublish hook.
  • packages/ui/package.json — Defines the @dub/ui component package, public export map, peer dependencies, and dist/** publish files.
  • packages/utils/package.json — Defines the @dub/utils package, ESM-oriented output, shared utility dependency set, peer dependency contract, and public publish configuration.
  • packages/stripe-app/README.md — Documents the Stripe app release flow, including version incrementing, stripe apps upload, and final publication in the Stripe dashboard.
  • packages/hubspot-app/README.md — Documents HubSpot app development commands using the HubSpot CLI through pnpm.

Npm Package Publishing Flow

For npm packages, the release pattern is intentionally consistent: build only the package being released, publish from its package directory, and rely on each package manifest to define what goes to npm. The root scripts use filters such as --filter='@dub/ui' and --filter='@dub/utils', so the release command targets a package by workspace identity rather than by manually invoking that package’s local build command. A maintainer should treat the filtered Turborepo build as the release gate for generated dist artifacts, because all of the public package manifests publish dist outputs rather than TypeScript source.

Sources: package.json, packages/ui/package.json, packages/utils/package.json, packages/embeds/core/package.json, packages/embeds/react/package.json, packages/cli/package.json

The CLI package is slightly different from the library packages because its public contract includes an executable binary. Its manifest names the npm package dub-cli, exposes ./dist/index.js, declares ./dist/index.d.ts for types, and maps the dub command to ./dist/index.js. The package is marked preferGlobal, which matches its role as a terminal tool for shortening URLs with the Dub API. Before publishing, maintainers should verify that tsup has produced the expected dist entrypoint and that the version in packages/cli/package.json reflects the intended npm release.

Sources: packages/cli/package.json

The embed packages are split into a framework-neutral core and a React wrapper. @dub/embed-core is described as the vanilla JavaScript core script that embeds Dub dashboards, with CommonJS, ESM, and type outputs under dist. @dub/embed-react depends on @dub/embed-core, publishes the same style of dist/** artifacts, and declares React and React DOM as peer dependencies. Its manifest also includes a preview command using Vite and a prepublishOnly hook, so maintainers should not bypass npm publish behavior when releasing it; the manifest-level prepublish step is part of its release contract.

Sources: packages/embeds/core/package.json, packages/embeds/react/package.json

@dub/ui and @dub/utils are shared implementation packages consumed by Dub applications and, based on their public publish configuration, external consumers. The UI package exposes multiple entrypoints: the root component package, ./icons, and ./charts, each with type, ESM import, and CommonJS require targets. The utils package publishes a slimmer ESM-oriented entrypoint with shared constants and utility functions. Both packages declare dist/** as publish files and use tsup for builds, so a successful release depends on generated output matching the export map and type declarations declared in the manifests.

Sources: packages/ui/package.json, packages/utils/package.json

Integration Release Workflows

The Stripe app is released through Stripe’s app tooling, not through the root npm publish scripts. Its README identifies the package as the Stripe app for Dub Conversions and points to the Stripe Marketplace listing. The documented publication flow starts with stripe login under the Dub Technologies, Inc. account, then requires maintainers to work from packages/stripe-app, increment the version field in stripe-app.json, upload with stripe apps upload, and publish the new version from the Stripe dashboard. This is a vendor-mediated release: the repository stores the app source and instructions, while Stripe controls upload validation and marketplace publication.

Sources: packages/stripe-app/README.md

The HubSpot app package is also integration-oriented, but the supplied README emphasizes development and account operations rather than a final marketplace publish step. It identifies the package as the HubSpot app integration for Dub and shows HubSpot CLI commands run through pnpm. The workflow includes installing dependencies, uploading the project to a HubSpot account with pnpm hs project upload --account=<account-id>, starting local development with pnpm hs project dev, installing project dependencies, adding features, and listing connected accounts. Official Dub integration documentation frames HubSpot as a conversion-event integration for lead and sale workflows; the repository README gives maintainers the concrete CLI commands for working on that integration.

Sources: packages/hubspot-app/README.md

Command Reference

SurfaceRelease or development commandWhat it doesSource
CLIpnpm publish-cliBuilds @dub/cli through Turborepo filtering, enters packages/cli, and runs npm publish.package.json
Embed corepnpm publish-embed-coreBuilds @dub/embed-core, enters packages/embeds/core, and publishes to npm.package.json
Embed Reactpnpm publish-embed-reactBuilds @dub/embed-react, enters packages/embeds/react, and publishes to npm.package.json
UIpnpm publish-uiBuilds @dub/ui, enters packages/ui, and publishes to npm.package.json
Utilspnpm publish-utilsBuilds @dub/utils, enters packages/utils, and publishes to npm.package.json
Stripe appstripe apps uploadUploads an updated Stripe app version after stripe login and a stripe-app.json version increment.packages/stripe-app/README.md
Stripe app localstripe apps startRuns the Stripe app locally for development.packages/stripe-app/README.md
HubSpot app uploadpnpm hs project upload --account=<account-id>Uploads the HubSpot project to a selected HubSpot account.packages/hubspot-app/README.md
HubSpot app devpnpm hs project devStarts a HubSpot test environment for local development.packages/hubspot-app/README.md

A practical npm release checklist should start with the package manifest rather than only the root script. Confirm the package name and version, verify that publishConfig.access is public where expected, and inspect the files, main, module, types, exports, and bin fields according to the package being released. Then run the appropriate root publish script so the filtered build happens before npm publish. If the package has peer dependencies, especially the React and Next peer contracts in @dub/ui, @dub/utils, and @dub/embed-react, check compatibility before cutting the release because consumers receive those constraints as part of the published package metadata.

Sources: packages/cli/package.json, packages/embeds/react/package.json, packages/ui/package.json, packages/utils/package.json, package.json

System-to-Code Mapping

The release system separates orchestration, package contracts, and vendor operations. Orchestration lives in the root manifest and answers the question, “Which command should I run for this artifact?” Package contracts live in package manifests and answer, “What will npm consumers install and import?” Vendor operations live in integration READMEs and answer, “Which external CLI or dashboard completes the release?” Keeping those responsibilities distinct reduces accidental publishing mistakes: a root command should not redefine exports, a package manifest should not document Stripe dashboard steps, and a vendor README should not be treated as an npm package release script.

Sources: package.json, packages/stripe-app/README.md, packages/hubspot-app/README.md

The package naming also matters when reading the root scripts. The CLI manifest’s package name is dub-cli, while the root publish script filters @dub/cli. The supplied manifests show the package’s npm name and public binary contract; the root script shows how the workspace is targeted during the monorepo build. In contrast, @dub/embed-core, @dub/embed-react, @dub/ui, and @dub/utils align directly with scoped npm package names in their manifests. Maintainers should follow the existing scripts instead of inventing ad hoc publish commands, because the scripts encode the expected directory changes and package-specific publish locations.

Sources: package.json, packages/cli/package.json, packages/embeds/core/package.json, packages/embeds/react/package.json, packages/ui/package.json, packages/utils/package.json

Next Steps

Before publishing, run the package’s own quality commands when appropriate, such as build, lint, and check-types, then use the root publish script or vendor-specific CLI documented for the integration. For npm packages, verify the generated dist directory because every public package listed here publishes built artifacts. For Stripe, validate the version bump and upload under the correct Stripe account before using the dashboard to publish. For HubSpot, use the account-listing and project-development commands to confirm that you are operating against the intended HubSpot account and environment. See the CLI, embeds, UI, utils, Stripe app, and HubSpot app pages for deeper package-specific behavior.

Sources: packages/cli/package.json, packages/embeds/core/package.json, packages/embeds/react/package.json, packages/ui/package.json, packages/utils/package.json, packages/stripe-app/README.md, packages/hubspot-app/README.md