The modern link attribution platform. Loved by world-class engineering teams at Twilio, Zillow, Jobber, Vercel, Raycast, and more.
This report summarizes scanner evidence for dubinc/dub, a TypeScript project with 25,051 GitHub stars. SynthScan examined 255,528 lines of code across 2298 source files, recording 196 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 1.0 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 174 finding(s).
Are imports declared and package/API names verified? 12 finding(s).
Are wrappers, guards, and repeated structures necessary? 147 finding(s).
Which changes need focused human review? 196 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 196 distinct pattern matches across 8 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packages/ui/src/tooltip-advanced-link-features.tsx | 31 | export function AdvancedLinkFeaturesTooltip() { | CODE |
| LOW | packages/ui/src/hooks/use-router-stuff.ts | 16 | export function consumePendingDashboardScrollTop(): number | null { | CODE |
| LOW | packages/ui/src/rich-text-area/campaign-editor-image.ts | 132 | export function configureCampaignEditorImage( | CODE |
| LOW | packages/ui/src/rich-text-area/table-keyboard.ts | 95 | export function deleteTableStructureOnKey( | CODE |
| LOW | …kages/utils/src/constants/pricing/plan-period-utils.ts | 15 | export function getMonthlyLimitFromPeriod({ | CODE |
| LOW | packages/utils/src/constants/pricing/trial-limits.ts | 31 | export function getTrialLimitFeaturePhrase(kind: TrialLimitResource): string { | CODE |
| LOW | packages/utils/src/constants/pricing/trial-limits.ts | 35 | export function getTrialLimitResourceForOverageBanner({ | CODE |
| LOW | packages/utils/src/constants/pricing/trial-limits.ts | 49 | export function isWorkspaceBillingTrialActive( | CODE |
| LOW | …s/utils/src/functions/is-click-on-interactive-child.ts | 3 | export function isClickOnInteractiveChild(e: MouseEvent) { | CODE |
| LOW | …s/email/src/templates/folder-edit-access-requested.tsx | 17 | export default function FolderEditAccessRequested({ | CODE |
| LOW | apps/web/ui/layout/upgrade-banner.tsx | 24 | export function useUpgradeBannerVisibility() { | CODE |
| LOW | apps/web/ui/layout/sidebar/workspace-dropdown.tsx | 104 | function WorkspaceDropdownPlaceholder() { | CODE |
| LOW | apps/web/ui/modals/update-workspace-user-role.tsx | 120 | export function useWorkspaceUserRoleModal({ | CODE |
| LOW | apps/web/ui/modals/link-conversion-tracking-modal.tsx | 22 | function LinkConversionTrackingModal(props: LinkConversionTrackingModalProps) { | CODE |
| LOW | apps/web/ui/modals/link-conversion-tracking-modal.tsx | 33 | function LinkConversionTrackingModalInner({ | CODE |
| LOW | apps/web/ui/modals/link-conversion-tracking-modal.tsx | 175 | export function useLinkConversionTrackingModal({ | CODE |
| LOW | apps/web/ui/modals/trial-limit-activate-modal.tsx | 22 | function TrialLimitActivateModalInner({ | CODE |
| LOW | apps/web/ui/modals/trial-limit-activate-modal.tsx | 124 | export function useTrialLimitActivateModal() { | CODE |
| LOW | apps/web/ui/modals/domain-auto-renewal-modal.tsx | 138 | export function useDomainAutoRenewalModal({ domain }: { domain: DomainProps }) { | CODE |
| LOW | apps/web/ui/modals/remove-workspace-user-modal.tsx | 224 | export function useRemoveWorkspaceUserModal({ user }: { user: UserProps }) { | CODE |
| LOW | apps/web/ui/modals/cancel-subscription-modal.tsx | 191 | export function useCancelSubscriptionModal({ | CODE |
| LOW | apps/web/ui/modals/uninstall-integration-modal.tsx | 15 | function UninstallIntegrationModal({ | CODE |
| LOW | apps/web/ui/modals/uninstall-integration-modal.tsx | 105 | export function useUninstallIntegrationModal({ | CODE |
| LOW | apps/web/ui/modals/register-domain-success-modal.tsx | 74 | export function useRegisterDomainSuccessModal() { | CODE |
| LOW | apps/web/ui/modals/invite-workspace-user-modal.tsx | 48 | export function useInviteWorkspaceUserModal({ | CODE |
| LOW | apps/web/ui/modals/add-edit-utm-template.modal.tsx | 176 | export function useAddEditUtmTemplateModal({ | CODE |
| LOW | apps/web/ui/modals/forward-dns-instructions-modal.tsx | 20 | function ForwardDnsInstructionsModal({ | CODE |
| LOW | apps/web/ui/modals/forward-dns-instructions-modal.tsx | 108 | export function useForwardDnsInstructionsModal( | CODE |
| LOW | …i/modals/link-builder/advanced-link-features-modal.tsx | 14 | function AdvancedLinkFeaturesModal({ | CODE |
| LOW | …i/modals/link-builder/advanced-link-features-modal.tsx | 177 | export function useAdvancedLinkFeaturesModal() { | CODE |
| LOW | apps/web/ui/logs/log-utils.ts | 1 | export function getStatusCodeBadgeVariant(statusCode: number) { | CODE |
| LOW | …link-builder/controls/link-builder-folder-selector.tsx | 6 | export function LinkBuilderFolderSelector() { | CODE |
| LOW | …ps/web/ui/guides/install-stripe-integration-button.tsx | 13 | export function InstallStripeIntegrationButton() { | CODE |
| LOW | apps/web/ui/webhooks/webhook-event-details-sheet.tsx | 24 | function WebhookEventDetailsSheetContent({ | CODE |
| LOW | apps/web/ui/webhooks/webhook-trigger-selector.tsx | 46 | export function isWebhookTriggerSelectionInvalid( | CODE |
| LOW | apps/web/ui/analytics/chart-section.tsx | 149 | function ConversionTrackingPaywall() { | CODE |
| LOW | apps/web/app/password/[linkId]/page.tsx | 58 | export default async function PasswordProtectedLinkPage(props: { | CODE |
| LOW | …dub.co/embed/support-chat/dynamic-height-messenger.tsx | 5 | export function SupportChatDynamicHeightMessenger() { | CODE |
| LOW | …(auth)/oauth/authorize/authorize-workspace-context.tsx | 35 | export function AuthorizeWorkspaceProvider({ | CODE |
| LOW | …(auth)/oauth/authorize/authorize-workspace-context.tsx | 89 | function getDefaultAuthorizeWorkspace({ | CODE |
| LOW | …uth)/auth/confirm-email-change/[token]/page-client.tsx | 13 | export default function ConfirmEmailChangePageClient({ | CODE |
| LOW | …]/(ee)/settings/integrations/featured-integrations.tsx | 170 | export function FeaturedIntegrationsLoader() { | CODE |
| LOW | …settings/integrations/integrations-subpage-context.tsx | 16 | export function IntegrationsSubpageProvider({ | CODE |
| LOW | …settings/integrations/integrations-subpage-context.tsx | 42 | export function SetIntegrationsSubpageTitle({ title }: { title: string }) { | CODE |
| LOW | …)/settings/integrations/integrations-layout-client.tsx | 49 | function IntegrationsLayoutContent({ children }: { children: ReactNode }) { | CODE |
| LOW | …rd)/[slug]/(ee)/settings/integrations/enabled/page.tsx | 28 | async function EnabledIntegrationsPageRSC({ slug }: { slug: string }) { | CODE |
| LOW | ….co/(dashboard)/[slug]/(ee)/settings/tracking/page.tsx | 8 | export default function WorkspaceTrackingSettingsPage() { | CODE |
| LOW | …rd)/[slug]/(ee)/settings/notifications/page-client.tsx | 16 | export default function NotificationsSettingsPageClient() { | CODE |
| LOW | …dashboard)/[slug]/(ee)/settings/notifications/page.tsx | 3 | export default function NotificationsSettingsPage() { | CODE |
| LOW | …shboard)/[slug]/(ee)/settings/billing/upgrade/page.tsx | 56 | export default function WorkspaceBillingUpgradePage() { | CODE |
| LOW | …pp/app.dub.co/(dashboard)/[slug]/links/page-client.tsx | 75 | export function WorkspaceLinksPageControls() { | CODE |
| LOW | ….dub.co/(dashboard)/[slug]/links/utm/template-card.tsx | 195 | function TemplateCardKeyboardShortcuts({ | CODE |
| LOW | …pp.dub.co/(dashboard)/[slug]/links/utm/page-client.tsx | 22 | export default function WorkspaceUtmTemplatesClient() { | CODE |
| LOW | apps/web/app/(ee)/api/cron/workspaces/delete/utils.ts | 22 | export async function enqueueNextWorkspaceDeleteStep({ | CODE |
| LOW | apps/web/app/(ee)/api/cron/trial-emails/route.ts | 23 | async function executeTrialEmailCronBatch(startingAfter?: string) { | CODE |
| LOW | …)/api/stripe/webhook/payment-intent-requires-action.ts | 5 | export async function paymentIntentRequiresAction( | CODE |
| LOW | …e)/api/stripe/webhook/customer-subscription-deleted.ts | 16 | export async function customerSubscriptionDeleted( | CODE |
| LOW | …e)/api/stripe/webhook/customer-subscription-deleted.ts | 213 | async function voidLatestInvoiceIfPayable(subscription: Stripe.Subscription) { | CODE |
| LOW | apps/web/app/(ee)/api/stripe/webhook/charge-refunded.ts | 33 | async function processDomainRenewalInvoice({ invoice }: { invoice: Invoice }) { | CODE |
| LOW | …ps/web/app/(ee)/api/stripe/webhook/charge-succeeded.ts | 73 | async function processDomainRenewalInvoice({ invoice }: { invoice: Invoice }) { | CODE |
| 77 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 17 | // Step 1: Enter email and reveal password field | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 21 | // Step 2: Enter password and submit | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 27 | // Step 3: Verify email via OTP from MailHog | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 36 | // Step 4: Wait for redirect to onboarding after auto-submit | COMMENT |
| LOW | apps/web/guides/gtm-client-sdk.md | 3 | ## Step 1: Create a New Tag | COMMENT |
| LOW | apps/web/guides/gtm-client-sdk.md | 13 | ## Step 2: Add the Dub client-side script | COMMENT |
| LOW | apps/web/guides/gtm-client-sdk.md | 44 | ## Step 3: Configure the Trigger | COMMENT |
| LOW | apps/web/guides/gtm-client-sdk.md | 52 | ## Step 4: Save and Publish | COMMENT |
| LOW | apps/web/guides/gtm-track-sale.md | 5 | ## Step 1: Create a GTM Variable to read the dub_id Cookie | COMMENT |
| LOW | apps/web/guides/gtm-track-sale.md | 19 | ## Step 2: Tracking sale events | COMMENT |
| LOW | apps/web/guides/better-auth.md | 3 | ## Step 1: Install the @dub/better-auth plugin | COMMENT |
| LOW | apps/web/guides/better-auth.md | 14 | ## Step 2: Configure the plugin | COMMENT |
| LOW⚡ | apps/web/guides/clerk.md | 3 | ## Step 1: Add environment variables | COMMENT |
| LOW⚡ | apps/web/guides/clerk.md | 16 | ## Step 2: Add a custom claim to your Clerk session token | COMMENT |
| LOW⚡ | apps/web/guides/clerk.md | 26 | ## Step 3: Extend the `@dub/analytics` package with Clerk's `useUser` hook | COMMENT |
| LOW | apps/web/guides/clerk.md | 97 | ## Step 4: Implement the `trackLead` server action | COMMENT |
| LOW | apps/web/guides/segment-track-lead.md | 3 | ## Step 1: Add Dub (Actions) destination | COMMENT |
| LOW | apps/web/guides/segment-track-lead.md | 9 | ## Step 2: Configure Dub API Key | COMMENT |
| LOW | apps/web/guides/segment-track-lead.md | 21 | ## Step 3: Add Mapping | COMMENT |
| LOW | apps/web/guides/segment-track-lead.md | 37 | ## Step 4: Send lead events to Dub | COMMENT |
| LOW | apps/web/guides/react.md | 3 | ### Step 1: Install package | COMMENT |
| LOW | apps/web/guides/react.md | 11 | ### Step 2: Initialize package in your code | COMMENT |
| LOW | apps/web/guides/segment-track-sale.md | 5 | ## Step 1: Add Dub (Actions) destination | COMMENT |
| LOW | apps/web/guides/segment-track-sale.md | 11 | ## Step 2: Configure Dub API Key | COMMENT |
| LOW | apps/web/guides/segment-track-sale.md | 23 | ## Step 3: Add Mapping | COMMENT |
| LOW | apps/web/guides/segment-track-sale.md | 39 | ## Step 4: Send sale events to Dub | COMMENT |
| LOW | apps/web/guides/gtm-track-lead.md | 5 | ## Step 1: Create a GTM Variable to read the dub_id Cookie | COMMENT |
| LOW | apps/web/guides/gtm-track-lead.md | 19 | ## Step 2: Tracking lead events | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 30 | // ─── Constants ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 40 | // ─── Shared form body ───────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 316 | // ─── Segmented control ──────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 381 | // ─── Color section ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 418 | // ─── Style icons ────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/ui/modals/qr-code-design-fields.tsx | 590 | // ─── Download / Copy popovers ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/lib/qr/index.tsx | 159 | // ─── SVG string helpers for download ───────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/lib/qr/index.tsx | 242 | // ─── Canvas helpers for finder patterns ────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/lib/qr/index.tsx | 313 | // ─── Public download helpers ────────────────────────────────────────────────── | COMMENT |
| MEDIUM | apps/web/lib/qr/utils.tsx | 340 | // ─── SVG path helpers for compound finder-pattern shapes ───────────────────── | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | apps/web/ui/domains/add-edit-domain-form.tsx | 748 | id: "placeholder", | CODE |
| LOW | apps/web/ui/modals/add-customer-modal.tsx | 382 | placeholder="John Doe" | CODE |
| LOW | apps/web/ui/modals/edit-customer-modal.tsx | 90 | placeholder="John Doe" | CODE |
| LOW | apps/web/ui/modals/forward-dns-instructions-modal.tsx | 92 | placeholder="admin@example.com" | CODE |
| LOW | …p.dub.co/(onboarding)/[slug]/wrapped/[year]/client.tsx | 31 | item: "placeholder", | CODE |
| LOW | …p.dub.co/(onboarding)/[slug]/wrapped/[year]/client.tsx | 199 | {item === "placeholder" ? ( | CODE |
| LOW | apps/web/guides/stripe-checkout.md | 16 | email: "user@example.com", | CODE |
| LOW | apps/web/guides/manual-track-lead.md | 17 | customerName: "John Doe", | CODE |
| LOW | apps/web/guides/manual-track-lead.md | 36 | customerName: "John Doe", | CODE |
| LOW | apps/web/guides/stripe-customers.md | 10 | email: "user@example.com", | CODE |
| LOW | apps/web/guides/stripe-customers.md | 33 | email: "user@example.com", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 17 | // Step 1: Enter email and reveal password field | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 21 | // Step 2: Enter password and submit | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 27 | // Step 3: Verify email via OTP from MailHog | COMMENT |
| LOW⚡ | apps/web/playwright/workspaces/auth.setup.ts | 36 | // Step 4: Wait for redirect to onboarding after auto-submit | COMMENT |
| LOW | apps/web/lib/auth/options.ts | 368 | // If the user is not using SAML, we need to check if SAML is enforced for the email domain | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | apps/web/guides/clerk.md | 13 | DUB_API_KEY=your_api_key | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …s/email/src/templates/trial/trial-3-days-remaining.tsx | 22 | Don't forget to review your selected plan and billing details. | CODE |
| MEDIUM | apps/web/scripts/dev/data.json | 73 | "readme": "This is the official Make.com integration for Dub. Make.com lets you connect Dub with thousands of the | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | apps/web/tests/tracks/track-click.test.ts | 121 | // path: "/track/click", | COMMENT |
| LOW | apps/web/lib/openapi/mcp-document.ts | 1 | import { document } from "."; | COMMENT |