---
title: "Project Structure"
description: "The Dub project is structured as a scalable pnpm and Turborepo-orchestrated monorepo combining a core Next.js web application with a robust collection of shared internal libraries, compiler configu..."
last_updated: "2026-10-05T05:07:35.143771+00:00"
canonical_url: "https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/project-structure"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [package.json](https://github.com/blade47/dub/blob/HEAD/package.json)
- [pnpm-workspace.yaml](https://github.com/blade47/dub/blob/HEAD/pnpm-workspace.yaml)
- [apps/web/package.json](https://github.com/blade47/dub/blob/HEAD/apps/web/package.json)
- [turbo.json](https://github.com/blade47/dub/blob/HEAD/turbo.json)
- [packages/utils/tsup.config.ts](https://github.com/blade47/dub/blob/HEAD/packages/utils/tsup.config.ts)
- [apps/web/app/api/old/projects/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/route.ts)
- [packages/ui/tsup.config.ts](https://github.com/blade47/dub/blob/HEAD/packages/ui/tsup.config.ts)
- [packages/ui/package.json](https://github.com/blade47/dub/blob/HEAD/packages/ui/package.json)
- [apps/web/app/api/old/projects/slug/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/route.ts)
- [packages/hubspot-app/package.json](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/package.json)
- [apps/web/app/domain/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/%5Bdomain%5D/layout.tsx)
- [packages/email/package.json](https://github.com/blade47/dub/blob/HEAD/packages/email/package.json)
- [packages/cli/tsconfig.json](https://github.com/blade47/dub/blob/HEAD/packages/cli/tsconfig.json)
- [packages/utils/src/index.ts](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/index.ts)
- [apps/web/app/ee/app.dub.co/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/app.dub.co/layout.tsx)
- [apps/web/tsconfig.json](https://github.com/blade47/dub/blob/HEAD/apps/web/tsconfig.json)
- [packages/embeds/core/src/index.ts](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/src/index.ts)
- [packages/stripe-app/stripe-app.dev.json](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/stripe-app.dev.json)
- [packages/embeds/core/package.json](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/package.json)
- [apps/web/app/api/old/projects/slug/domains/default/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/default/route.ts)
- [apps/web/app/api/old/projects/slug/domains/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/route.ts)
- [packages/tsconfig/package.json](https://github.com/blade47/dub/blob/HEAD/packages/tsconfig/package.json)
- [apps/web/lib/auth/index.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/auth/index.ts)
- [apps/web/app/app.dub.co/marketplace/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx)
- [apps/web/ui/program-marketplace/external/marketplace-external-router.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/program-marketplace/external/marketplace-external-router.tsx)
- [apps/web/app/api/old/projects/slug/links/info/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/links/info/route.ts)
- [packages/embeds/core/tsup.config.ts](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/tsup.config.ts)
- [apps/web/app/api/old/projects/slug/domains/domain/route.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/%5Bdomain%5D/route.ts)
- [packages/cli/tsup.config.ts](https://github.com/blade47/dub/blob/HEAD/packages/cli/tsup.config.ts)
- [packages/utils/package.json](https://github.com/blade47/dub/blob/HEAD/packages/utils/package.json)
</details>

## Overview

The Dub project is structured as a scalable pnpm and Turborepo-orchestrated monorepo combining a core Next.js web application with a robust collection of shared internal libraries, compiler configurations, and specialized external micro-apps. By organizing source code into modular workspace packages under dedicated directories, the architecture streamlines multi-tenancy, build pipelines, and publishing workflows across the entire ecosystem.

Sources: [package.json:1-35](https://github.com/blade47/dub/blob/HEAD/package.json#L1-L35), [pnpm-workspace.yaml:1-6](https://github.com/blade47/dub/blob/HEAD/pnpm-workspace.yaml#L1-L6), [turbo.json:1-20](https://github.com/blade47/dub/blob/HEAD/turbo.json#L1-L20)

This layout addresses the complexity of maintaining shared utility infrastructure, robust UI component standards, enterprise routing domains, and client-side embeddable SDKs within a unified codebase. Centralized compiler options and bundler configurations ensure consistent packaging and seamless cross-workspace dependencies.

Sources: [packages/ui/package.json:1-133](https://github.com/blade47/dub/blob/HEAD/packages/ui/package.json#L1-L133), [packages/utils/package.json:1-62](https://github.com/blade47/dub/blob/HEAD/packages/utils/package.json#L1-L62), [packages/tsconfig/package.json:1-9](https://github.com/blade47/dub/blob/HEAD/packages/tsconfig/package.json#L1-L9)

## Monorepo Workspace Orchestration

### Monorepo Workspace Orchestration

### Overview

The monorepo architecture is governed at the root by `pnpm-workspace.yaml`, which defines the package discovery topology across application and library directories. The workspace spans four inclusion patterns: `apps/*`, `apps/web/.react-email`, `packages/*`, and `packages/embeds/*`. Package dependency resolution uses pnpm version `9.15.9` as specified by the `packageManager` field in the root `package.json`.

Sources: [pnpm-workspace.yaml:1-6](https://github.com/blade47/dub/blob/HEAD/pnpm-workspace.yaml#L1-L6), [package.json:34-34](https://github.com/blade47/dub/blob/HEAD/package.json#L34-L34)

### Root Workspace Configuration

The root `package.json` establishes the monorepo as a private project under the `AGPL-3.0-or-later` license. It defines global devDependencies including `@dub/tailwind-config` bound via `workspace:*`, `eslint` (`^8.48.0`), `prettier` (`^3.2.5`), `prettier-plugin-organize-imports` (`^3.2.4`), `prettier-plugin-tailwindcss` (`^0.6.0`), `tsconfig` bound via `workspace:*`, and `turbo` (`^1.12.5`). A resolutions block pins `chrono-node` to version `2.7.5`.

Sources: [package.json:1-35](https://github.com/blade47/dub/blob/HEAD/package.json#L1-L35)

> [!NOTE]
> Root devDependencies such as `tsconfig` and `@dub/tailwind-config` use the `workspace:*` protocol to ensure internal packages resolve directly to their local workspace sources rather than external registries.

Sources: [package.json:22-30](https://github.com/blade47/dub/blob/HEAD/package.json#L22-L30)

### Root Scripts and Publishing Workflows

The root scripts orchestrate Turborepo pipelines for building, developing, linting, cleaning, and testing, alongside targeted package publishing commands that filter execution by specific workspace identifiers.

| Script Name | Command | Purpose |
| :--- | :--- | :--- |
| `build` | `turbo build` | Executes the Turborepo build pipeline across the monorepo. |
| `build:packages` | `pnpm -r --filter "./packages/**" build` | Recursively builds all packages within the `./packages/` glob. |
| `dev` | `turbo dev` | Starts development servers via Turborepo with persistence enabled. |
| `lint` | `turbo lint` | Runs linting tasks across workspace packages. |
| `clean` | `turbo clean` | Cleans build artifacts and caches via Turborepo. |
| `format` | `prettier --write "**/*.{ts,tsx,md}"` | Formats all TypeScript, TSX, and Markdown files with Prettier. |
| `prettier-check` | `prettier --check "**/*.{ts,tsx,md}"` | Verifies code formatting across the repository. |
| `publish-cli` | `turbo build --filter='@dub/cli' && cd packages/cli && npm publish && cd ../../` | Builds and publishes the `@dub/cli` package. |
| `publish-embed-core` | `turbo build --filter='@dub/embed-core' && cd packages/embeds/core && npm publish && cd ../../../` | Builds and publishes the `@dub/embed-core` package. |
| `publish-embed-react` | `turbo build --filter='@dub/embed-react' && cd packages/embeds/react && npm publish && cd ../../../` | Builds and publishes the `@dub/embed-react` package. |
| `publish-tw` | `turbo build --filter='@dub/tailwind-config' && cd packages/tailwind-config && npm publish && cd ../../` | Builds and publishes `@dub/tailwind-config`. |
| `publish-ui` | `turbo build --filter='@dub/ui' && cd packages/ui && npm publish && cd ../../` | Builds and publishes the `@dub/ui` component library. |
| `publish-utils` | `turbo build --filter='@dub/utils' && cd packages/utils && npm publish && cd ../../` | Builds and publishes the `@dub/utils` helper package. |
| `script` | `echo 'Run this script in apps/web'` | Placeholder script directing developers to the web application app directory. |
| `test` | `turbo run test` | Executes test suites across the monorepo via Turborepo. |

Sources: [package.json:5-21](https://github.com/blade47/dub/blob/HEAD/package.json#L5-L21)

### Turborepo Pipeline Orchestration

Task execution is structured by `turbo.json` under schema `https://turbo.build/schema.json`. The pipeline defines global dependencies on any `.env` file (`**/.env`) across all tasks. Four primary pipeline targets dictate execution dependencies, caching rules, and output artifacts:

| Pipeline Task | `dependsOn` | `cache` | `persistent` | `outputs` |
| :--- | :--- | :--- | :--- | :--- |
| `build` | `^build` | Enabled (default) | Not set | `["!.next/cache/**", ".next/**", "dist/**"]` |
| `dev` | Not set | `false` | `true` | Not set |
| `clean` | Not set | `false` | Not set | Not set |
| `test` | `^build` | Enabled (default) | Not set | Not set |

Sources: [turbo.json:1-20](https://github.com/blade47/dub/blob/HEAD/turbo.json#L1-L20)

> [!WARNING]
> The `dev` and `clean` pipeline tasks explicitly disable Turborepo caching (`"cache": false`). Additionally, `dev` is marked as persistent (`"persistent": true`) to support long-running development watcher processes.

Sources: [turbo.json:9-15](https://github.com/blade47/dub/blob/HEAD/turbo.json#L9-L15)

## Shared Tooling and Compiler Configs

### Overview

The monorepo relies on standardized bundler configurations and TypeScript compiler options across its internal packages and applications. Bundling is handled primarily through `tsup`, leveraging esbuild for high-speed compilation, generation of declaration files (`dts`), code minification, and conditional workspace clean routines. TypeScript environments are similarly governed by base configuration packages and package-level `tsconfig.json` files that establish strict type-checking, path aliasing, and module resolution rules.

Sources: [packages/utils/tsup.config.ts:1-11](https://github.com/blade47/dub/blob/HEAD/packages/utils/tsup.config.ts#L1-L11), [packages/ui/tsup.config.ts:1-20](https://github.com/blade47/dub/blob/HEAD/packages/ui/tsup.config.ts#L1-L20)

### Tsup Bundler Standards and Options

Packages across the workspace customize `tsup` to emit specific output formats (`esm` or `cjs`), define entry points, handle banner injections, and declare external dependencies such as React.

| Package | Entry Points | Format | Minify | DTS | Clean Strategy | External / Banner |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `packages/utils` | `["src/**/*.ts"]` | `["esm"]` | `true` | `true` | `process.env.VERCEL === "1"` | External: `["react"]` |
| `packages/ui` | `index: "src/index.tsx"`, `"icons/index": "src/icons/index.tsx"`, `"charts/index": "src/charts/index.ts"` | `["esm"]` | `true` | `true` | `process.env.VERCEL === "1"` | External: `["react"]`; Banner JS: `'"use client"'` |
| `packages/embeds/core` | `"embed/script": "src/embed.ts"`, `index: "src/index.ts"` | `["cjs"]` | `true` | `true` | `true` (unconditional) | Splitting: `false`; Banner JS: `'"use client"'` |
| `packages/cli` | `["src/index.ts"]` | `["esm"]` | `true` | `true` | `true` (unconditional) | Target: `"esnext"`, Sourcemap: `true`, OutDir: `"dist"` |

Sources: [packages/utils/tsup.config.ts:1-11](https://github.com/blade47/dub/blob/HEAD/packages/utils/tsup.config.ts#L1-L11), [packages/ui/tsup.config.ts:1-20](https://github.com/blade47/dub/blob/HEAD/packages/ui/tsup.config.ts#L1-L20), [packages/embeds/core/tsup.config.ts:1-18](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/tsup.config.ts#L1-L18), [packages/cli/tsup.config.ts:1-12](https://github.com/blade47/dub/blob/HEAD/packages/cli/tsup.config.ts#L1-L12)

> [!TIP]
> Both `@dub/ui` and `@dub/embed-core` inject a `"use client"` banner via esbuild options during bundling to ensure consumer frameworks correctly treat their components as client-side modules.

Sources: [packages/ui/tsup.config.ts:10-14](https://github.com/blade47/dub/blob/HEAD/packages/ui/tsup.config.ts#L10-L14), [packages/embeds/core/tsup.config.ts:9-13](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/tsup.config.ts#L9-L13)

### TypeScript Compiler Configuration

TypeScript settings enforce strict type safety and modular workspace referencing. For instance, `packages/cli/tsconfig.json` specifies strict mode, Node module resolution, and path aliasing mapping `@/*` to `./src/*`.

```json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Default",
  "compilerOptions": {
    "composite": false,
    "declaration": true,
    "declarationMap": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "inlineSources": false,
    "isolatedModules": true,
    "moduleResolution": "node",
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveWatchOutput": true,
    "skipLibCheck": true,
    "strict": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}
```

Sources: [packages/cli/tsconfig.json:1-26](https://github.com/blade47/dub/blob/HEAD/packages/cli/tsconfig.json#L1-L26)

Application-level configurations, such as `apps/web/tsconfig.json`, extend shared base configs like `tsconfig/nextjs.json` and establish comprehensive path aliases for pages, scripts, styles, ui, and libraries alongside explicit inclusions for monorepo packages like `packages/blocks/src/event-list.tsx` and `packages/ui/src/hooks/use-pagination.ts`.

```json
{
  "extends": "tsconfig/nextjs.json",
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@/pages/*": ["pages/*"],
      "@/scripts/*": ["scripts/*"],
      "@/styles/*": ["styles/*"],
      "@/ui/*": ["ui/*"],
      "@/lib/*": ["lib/*"]
    },
    "downlevelIteration": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "strict": false,
    "strictNullChecks": true,
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts",
    "../../packages/blocks/src/event-list.tsx",
    "../../packages/ui/src/hooks/use-pagination.ts"
  ],
  "exclude": ["node_modules", "playwright"]
}
```

Sources: [apps/web/tsconfig.json:1-43](https://github.com/blade47/dub/blob/HEAD/apps/web/tsconfig.json#L1-L43)

> [!WARNING]
> Environment-conditional cleaning (`clean: process.env.VERCEL === "1"`) is used in library packages like `packages/utils` and `packages/ui` to optimize Vercel build performance, whereas standalone tools and embeds enforce unconditional directory cleaning (`clean: true`).

Sources: [packages/utils/tsup.config.ts:8-8](https://github.com/blade47/dub/blob/HEAD/packages/utils/tsup.config.ts#L8-L8), [packages/ui/tsup.config.ts:17-17](https://github.com/blade47/dub/blob/HEAD/packages/ui/tsup.config.ts#L17-L17), [packages/embeds/core/tsup.config.ts:16-16](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/tsup.config.ts#L16-L16), [packages/cli/tsup.config.ts:4-4](https://github.com/blade47/dub/blob/HEAD/packages/cli/tsup.config.ts#L4-L4)

## Core Application Architecture

### Overview

The `apps/web` Next.js application manages its routing layout structure through specialized route groups, dynamic multi-tenant domain segments, and isolated enterprise configurations. Script tasks within `apps/web/package.json` coordinate generation workflows like Prisma client generation (`prisma:generate`), concurrent development servers running Next.js with Turbopack on port `8888`, openapi generation (`generate-openapi`), and test runner suites via Vitest and Playwright.

Sources: [apps/web/package.json:5-19](https://github.com/blade47/dub/blob/HEAD/apps/web/package.json#L5-L19)

### Routing Structure and Enterprise Layouts

Multi-tenant domain routing and marketplace sub-layouts govern how page content is rendered across distinct contexts. The dynamic domain layout (`apps/web/app/[domain]/layout.tsx`) wraps child components inside a neutral background container bounded by a mobile navigation bar (`NavMobile`), standard navigation (`Nav`), and footer components (`Footer`).

```tsx
import { Footer, Nav, NavMobile } from "@dub/ui";

export default function ExternalPagesLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex min-h-screen flex-col justify-between bg-neutral-50/80">
      <NavMobile />
      <Nav maxWidthWrapperClassName="max-w-screen-lg lg:px-4 xl:px-0" />
      {children}
      <Footer className="max-w-screen-lg border-0 bg-transparent lg:px-4 xl:px-0" />
    </div>
  );
}
```

Sources: [apps/web/app/domain/layout.tsx:1-16](https://github.com/blade47/dub/blob/HEAD/apps/web/app/%5Bdomain%5D/layout.tsx#L1-L16)

Enterprise app routing maps group entry points directly, such as `apps/web/app/(ee)/app.dub.co/layout.tsx` re-exporting the layout default directly from `../../app.dub.co/layout`.

Sources: [apps/web/app/ee/app.dub.co/layout.tsx:1-2](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/app.dub.co/layout.tsx#L1-L2)

### Marketplace Sub-routing and Segment Resolution

The marketplace section under `apps/web/app/app.dub.co/marketplace/layout.tsx` integrates decorative external grid lines via `MarketplaceExternalGridLines` alongside the external marketplace header and footer.

```tsx
import { MarketplaceExternalHeader } from "@/ui/program-marketplace/external/marketplace-external-header";
import { Footer } from "@dub/ui";
import { PropsWithChildren } from "react";

export default function MarketplaceExternalLayout({
  children,
}: PropsWithChildren) {
  return (
    <div className="flex min-h-screen flex-col bg-white">
      <MarketplaceExternalHeader />
      <div className="relative flex flex-1 flex-col">
        <MarketplaceExternalGridLines />
        <main className="flex-1">{children}</main>
        <div className="relative z-10 h-px w-full bg-neutral-200" />
        <Footer className="border-t-0 md:rounded-t-none" />
      </div>
    </div>
  );
}

function MarketplaceExternalGridLines() {
  return (
    <div
      aria-hidden
      className="pointer-events-none absolute inset-0 z-0 flex justify-center"
    >
      <div className="relative h-full w-full max-w-screen-xl">
        <div className="absolute inset-y-0 left-0 w-px bg-neutral-200 [mask-image:linear-gradient(to_bottom,transparent,#000_96px)]" />
        <div className="absolute inset-y-0 right-0 w-px bg-neutral-200 [mask-image:linear-gradient(to_bottom,transparent,#000_96px)]" />
      </div>
    </div>
  );
}
```

Sources: [apps/web/app/app.dub.co/marketplace/layout.tsx:1-33](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx#L1-L33)

Dynamic segment matching inside the marketplace is handled explicitly by `MarketplaceExternalRouter`. The routing flow evaluates path segment lengths and parameter values to select appropriate page views.

```tsx
import { notFound } from "next/navigation";
import { slugToCategory } from "../utils/urls";
import { MarketplaceExternalHomePage } from "./marketplace-external-home-page";
import { MarketplaceExternalListPage } from "./marketplace-external-list-page";
import { MarketplaceExternalProgramPage } from "./marketplace-external-program-page";

export async function MarketplaceExternalRouter({
  segments,
}: {
  segments: string[];
}) {
  if (segments.length === 0) {
    return <MarketplaceExternalHomePage />;
  }

  if (segments.length === 1 && segments[0] === "all") {
    return <MarketplaceExternalListPage segments={segments} />;
  }

  if (segments.length === 2 && segments[0] === "c") {
    const category = slugToCategory(segments[1]);

    if (category) {
      return (
        <MarketplaceExternalListPage
          segments={segments}
          fixedCategory={category}
        />
      );
    }
  }

  if (segments.length === 1) {
    return <MarketplaceExternalProgramPage programSlug={segments[0]} />;
  }

  notFound();
}
```

Sources: [apps/web/ui/program-marketplace/external/marketplace-external-router.tsx:1-39](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/program-marketplace/external/marketplace-external-router.tsx#L1-L39)

> [!TIP]
> The `MarketplaceExternalRouter` call chain evaluates `segments.length === 0` to render the home page before checking explicit filters like `all` lists, category route prefixes (`c`), or falling back to single-segment program detail pages or triggering `notFound()`.

Sources: [apps/web/ui/program-marketplace/external/marketplace-external-router.tsx:12-37](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/program-marketplace/external/marketplace-external-router.tsx#L12-L37)

## Web Application API and Authentication

### Internal Authentication Modules

The authentication system index module aggregates core administrative, token-hashing, configuration, session, utility, and workspace-level modules under `apps/web/lib/auth/index.ts`. Specifically, it re-exports modules from `./admin`, `./hash-token`, `./options`, `./session`, `./utils`, and `./workspace`.

```ts
export * from "./admin";
export * from "./hash-token";
export * from "./options";
export * from "./session";
export * from "./utils";
export * from "./workspace";
```

Sources: [apps/web/lib/auth/index.ts:1-6](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/auth/index.ts#L1-L6)

> [!NOTE]
> The authentication barrel file acts as a single entry point for all sub-auth components, unifying workspace permission checks, session management, and token hashing into a consolidated namespace.

Sources: [apps/web/lib/auth/index.ts:1-6](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/auth/index.ts#L1-L6)

### Legacy Backwards-Compatibility Routing Proxies

Legacy API routing under `apps/web/app/api/(old)/projects/` provides backwards-compatibility proxies that forward historical project-level API routes to modern workspace and domain implementations. 

The base projects endpoint re-exports workspace routing handlers directly:

```ts
export * from "../../workspaces/route";
```

Sources: [apps/web/app/api/old/projects/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/route.ts#L1-L1)

Similarly, individual project slug routing proxies map project parameter endpoints to parameterized workspace routes:

```ts
export * from "../../../workspaces/[idOrSlug]/route";
```

Sources: [apps/web/app/api/old/projects/slug/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/route.ts#L1-L1)

### Domain and Link Information Proxies

Domain and link info routes under the legacy project hierarchy forward requests to canonical domain and link handlers. The domain collection route exports from the standard domains endpoint:

```ts
export * from "../../../../domains/route";
```

Sources: [apps/web/app/api/old/projects/slug/domains/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/route.ts#L1-L1)

Default domain configuration and specific domain routing proxies delegate directly to corresponding domain handlers:

```ts
export * from "../../../../../domains/default/route";
```

Sources: [apps/web/app/api/old/projects/slug/domains/default/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/default/route.ts#L1-L1)

```ts
export * from "../../../../../domains/[domain]/route";
```

Sources: [apps/web/app/api/old/projects/slug/domains/domain/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/%5Bdomain%5D/route.ts#L1-L1)

Link information routing follows the same delegation pattern, forwarding requests from the legacy project path to canonical link info endpoints:

```ts
export * from "../../../../../links/info/route";
```

Sources: [apps/web/app/api/old/projects/slug/links/info/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/links/info/route.ts#L1-L1)

| Legacy Route Path | Target Implementation Module | Purpose |
| :--- | :--- | :--- |
| `apps/web/app/api/(old)/projects/route.ts` | `../../workspaces/route` | Proxies project collection API calls to workspace collection handlers |
| `apps/web/app/api/(old)/projects/[slug]/route.ts` | `../../../workspaces/[idOrSlug]/route` | Proxies single project slug queries to workspace identifier handlers |
| `apps/web/app/api/(old)/projects/[slug]/domains/route.ts` | `../../../../domains/route` | Proxies project domain lists to canonical domain endpoints |
| `apps/web/app/api/(old)/projects/[slug]/domains/default/route.ts` | `../../../../../domains/default/route` | Proxies default domain requests |
| `apps/web/app/api/(old)/projects/[slug]/domains/[domain]/route.ts` | `../../../../../domains/[domain]/route` | Proxies specific domain management requests |
| `apps/web/app/api/(old)/projects/[slug]/links/info/route.ts` | `../../../../../links/info/route` | Proxies link information queries under legacy project namespaces |

Sources: [apps/web/app/api/old/projects/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/route.ts#L1-L1), [apps/web/app/api/old/projects/slug/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/route.ts#L1-L1), [apps/web/app/api/old/projects/slug/domains/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/route.ts#L1-L1), [apps/web/app/api/old/projects/slug/domains/default/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/default/route.ts#L1-L1), [apps/web/app/api/old/projects/slug/domains/domain/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/domains/%5Bdomain%5D/route.ts#L1-L1), [apps/web/app/api/old/projects/slug/links/info/route.ts:1-1](https://github.com/blade47/dub/blob/HEAD/apps/web/app/api/(old)/projects/%5Bslug%5D/links/info/route.ts#L1-L1)

## Shared Internal Packages

### Overview

The monorepo maintains core shared capabilities under dedicated internal packages in the `packages/` directory. These packages abstract common UI primitives, low-level utility functions, and transactional email infrastructure across web applications and micro-apps. Each package is independently versioned, utilizes `tsup` for compilation to ESM and CJS formats, and declares workspace peer dependencies to ensure consistent React and Next.js runtimes.

Sources: [packages/ui/package.json:1-133](https://github.com/blade47/dub/blob/HEAD/packages/ui/package.json#L1-L133), [packages/email/package.json:1-55](https://github.com/blade47/dub/blob/HEAD/packages/email/package.json#L1-L55), [packages/utils/package.json:1-62](https://github.com/blade47/dub/blob/HEAD/packages/utils/package.json#L1-L62)

### UI Components Package (`@dub/ui`)

The `@dub/ui` package provides the design system components, icons, and chart utilities used throughout the Dub interface. It exposes three primary entry points in its `exports` map: the root package, `./icons`, and `./charts`. 

```json
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.js"
    },
    "./icons": {
      "types": "./dist/icons/index.d.ts",
      "import": "./dist/icons/index.mjs",
      "require": "./dist/icons/index.js"
    },
    "./charts": {
      "types": "./dist/charts/index.d.ts",
      "import": "./dist/charts/index.mjs",
      "require": "./dist/charts/index.js"
    }
  },
```

Sources: [packages/ui/package.json:12-28](https://github.com/blade47/dub/blob/HEAD/packages/ui/package.json#L12-L28)

The package relies heavily on primitive libraries and headless UI components. Its dependency graph includes Floating UI for positioning, Radix UI primitives for accessible overlays and controls, Tiptap extensions for rich-text editing, and Visx packages combined with D3 arrays for charting.

| Dependency Category | Libraries / Packages | Purpose |
| :--- | :--- | :--- |
| **Overlays & Radix Primitives** | `@radix-ui/react-accordion`, `@radix-ui/react-dialog`, `@radix-ui/react-popover`, `@radix-ui/react-tooltip`, `vaul` | Accessible modals, popovers, drawers, and tooltips |
| **Rich Text Editor** | `@tiptap/react`, `@tiptap/starter-kit`, `@tiptap/extension-table`, `@tiptap/extension-link` | Advanced document editing and markdown manipulation |
| **Data Visualization** | `@visx/axis`, `@visx/shape`, `@visx/tooltip`, `d3-array` | Custom SVG charts, analytics graphs, and scales |
| **Styling & Utilities** | `class-variance-authority`, `tailwind-merge`, `motion`, `lucide-react` | Conditional class composition, animations, and icons |

Sources: [packages/ui/package.json:57-115](https://github.com/blade47/dub/blob/HEAD/packages/ui/package.json#L57-L115)

### Utility Functions Package (`@dub/utils`)

The `@dub/utils` package houses shared helper functions and constants exported from a centralized barrel file. Its source index exports all declarations from constants and functions modules:

```ts
export * from "./constants";
export * from "./functions";
```

Sources: [packages/utils/src/index.ts:1-3](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/index.ts#L1-L3)

The utility package consumes targeted helper libraries to perform slugification, date parsing, unique ID generation, and class name merging.

| Package Name | Version | Primary Utility Function |
| :--- | :--- | :--- |
| `@sindresorhus/slugify` | `^2.2.1` | Converts strings into clean URL slugs |
| `chrono-node` | `2.7.5` | Natural language date parser |
| `nanoid` | `^5.0.1` | URL-safe unique string ID generator |
| `tailwind-merge` | `^2.4.0` | Merges Tailwind CSS classes without conflict |
| `ms` | `^2.1.3` | Millisecond conversion utility |
| `punycode` | `^2.3.0` | Punycode domain name translator |

Sources: [packages/utils/package.json:34-42](https://github.com/blade47/dub/blob/HEAD/packages/utils/package.json#L34-L42)

### Email Infrastructure Package (`@dub/email`)

The `@dub/email` package manages transactional email templates and delivery pipelines using React Email and Resend or Nodemailer. It exposes granular exports for root utilities, template files, Resend wrappers, and Nodemailer transport:

```json
  "exports": {
    ".": {
      "import": "./src/index.ts",
      "require": "./src/index.ts"
    },
    "./templates/*": {
      "import": "./src/templates/*.tsx",
      "require": "./src/templates/*.tsx"
    },
    "./resend": {
      "import": "./src/resend/index.ts",
      "require": "./src/resend/index.ts"
    },
    "./resend/*": {
      "import": "./src/resend/*.ts",
      "require": "./src/resend/*.ts"
    },
    "./send-via-nodemailer": {
      "import": "./src/send-via-nodemailer.ts",
      "require": "./src/send-via-nodemailer.ts"
    }
  }
```

Sources: [packages/email/package.json:33-54](https://github.com/blade47/dub/blob/HEAD/packages/email/package.json#L33-L54)

> [!TIP]
> Run `pnpm dev` inside `packages/email` to launch the React Email preview server locally on port `3333` targeting `./src/templates`.

Sources: [packages/email/package.json:6-9](https://github.com/blade47/dub/blob/HEAD/packages/email/package.json#L6-L9)

## Embeds and External Micro-Apps

### Overview

External integrations and embeddable SDKs within the monorepo comprise specialised micro-apps and client-facing packages. These include the HubSpot application package, the Stripe development configuration, and the vanilla JavaScript dashboard embedding core (`@dub/embed-core`).

Sources: [packages/hubspot-app/package.json:1-23](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/package.json#L1-L23), [packages/stripe-app/stripe-app.dev.json:1-3](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/stripe-app.dev.json#L1-L3), [packages/embeds/core/package.json:1-45](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/package.json#L1-L45)

### Embed Core Package (`@dub/embed-core`)

The `@dub/embed-core` package provides a vanilla JavaScript core script for embedding Dub's dashboards into external web pages. Its primary export entry point aggregates constants, core embedding logic, and type definitions through a central barrel file:

```ts
export * from "./constants";
export * from "./core";
export * from "./types";
```

Sources: [packages/embeds/core/src/index.ts:1-3](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/src/index.ts#L1-L3)

The package relies on Floating UI for positioning popups or floating elements within embedded contexts, targeting Node environments alongside browser targets using tsup for bundling:

| Property / Field | Setting / Value |
| :--- | :--- |
| **Package Name** | `@dub/embed-core` |
| **Main Entry** | `./dist/index.js` |
| **Module Entry** | `./dist/index.mjs` |
| **Types Entry** | `./dist/index.d.ts` |
| **Dependencies** | `@floating-ui/dom` (`^1.6.12`) |

Sources: [packages/embeds/core/package.json:2-21](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/package.json#L2-L21)

> [!NOTE]
> The `@dub/embed-core` package is marked with `"sideEffects": false` to allow aggressive tree-shaking during bundler optimization.

Sources: [packages/embeds/core/package.json:6-6](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/package.json#L6-L6)

### HubSpot and Stripe Integration Apps

The `dub-hubspot-app` package configures the HubSpot integration workspace. It specifies a private module configuration requiring Node `>=14`, wrapping the official HubSpot CLI runner script:

```json
  "scripts": {
    "hs": "hs"
  },
  "dependencies": {
    "@hubspot/cli": "^7.6.2"
  }
```

Sources: [packages/hubspot-app/package.json:5-12](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/package.json#L5-L12)

Similarly, the Stripe integration package (`packages/stripe-app`) maintains development configuration overriding via its base extension schema:

```json
{
  "extends": "stripe-app.json"
}
```

Sources: [packages/stripe-app/stripe-app.dev.json:1-3](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/stripe-app.dev.json#L1-L3)

## Related

- [Overview](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/overview)
- [Quick Start](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/quick-start)
- [UI Component Library](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/developer-tools/ui-component-library)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/llms.txt) for all pages in this wiki.
