> ## Documentation Index
> Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---
id: 653649ea-75a0-483c-aa1b-f418ebb3873b
---

# Share code between your extensions using npm workspaces

> Learn how to use npm workspaces to share code between your UI extensions.

As you build out your UI extensions, you can leverage [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces/) to share code across your [app cards](/apps/developer-platform/add-features/ui-extensions/extension-points/app-cards/create-an-app-card), [settings page](/apps/developer-platform/add-features/ui-extensions/extension-points/create-a-settings-page), [app pages](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/create-app-pages), and [serverless functions](/apps/developer-platform/add-features/serverless-functions/overview). This allows you to consolidate common logic such as formatting dates and currency, and ensure that any fixes or updates are rolled out consistently to each UI extension.

## Prerequisites

Before getting started, install the latest version of the [HubSpot CLI](/developer-tooling/local-development/hubspot-cli/install-the-cli). In a terminal window, run the following command:

```shell theme={null}
npm install -g @hubspot/cli
```

The CLI needs to be version `8.0.0` or later.

* You can check which version of the CLI you have by running `hs --version`.
* If needed, you can run the command `npm install -g @hubspot/cli@latest` to update to the latest version of the HubSpot CLI.

## Project structure

The code for your card, setting page, and home page follows the same directory structure as outlined in the [app configuration article](/apps/developer-platform/build-apps/app-configuration). The main change you'll need to make to set up code sharing between your extensions will be to add a `package.json` file at the root of your project under `src/app/`. The naming convention and scope you choose for these shared packages is entirely customizable, allowing you to use a pattern you're already comfortable with, such as `@packages/types`.

An example directory structure that demonstrates the root `package.json` location, along with the shared code for `types`, `utils`, and `components` is shown below:

```shell highlight={6-16} theme={null}
my-hubspot-project/
└── hsproject.json
└── src/
    └── app/
        └── app-hsmeta.json
        └── package.json
        └── packages/
            └── types/
                └── package.json
                └── index.ts
            └── utils/
                └── package.json
                └── index.ts
            └── components/
                └── package.json
                └── index.tsx
        └── cards/
            └── MyCard.jsx
            └── my-app-card-hsmeta.json
            └── package.json
        └── settings/
            └── Settings.tsx
            └── settings-hsmeta.json
            └── package.json
        └── pages/
            └── Home.tsx
            └── package.json
```

## Configure npm workspaces

After you create a `package.json` file in the `src/app/` directory of your project, open the `package.json` file and define the `name` and `workspaces` fields:

* `name`: the name of your project (e.g., `my-hubspot-project`).
* `workspaces`: an array that includes the UI extension directories where you plan to use your shared code, along with the directory where your shared code lives (e.g., `packages/*`).

For example, following the same directory structure shown above, the resulting `package.json` file would be:

```json theme={null}
{
 "name": "my-hubspot-project",
 "workspaces": ["cards", "settings", "pages", "packages/*"]
}
```

## Create shared packages

You can use any naming convention when defining the package scope for your shared code (e.g., `@my-hubspot-project` in the examples below).

The code blocks below provide examples for defining shared `types`, `utils`, and `components` that you can then import into your UI extensions.

### Types

The examples below define a simple `Money` type under `packages/types` in your project.

<Card>
  <Tabs>
    <Tab title="package.json">
      ```json theme={null}
        {
          "name": "@my-hubspot-project/types",
          "private": true,
          "version": "1.0.0",
          "main": "index.ts"
        }
      ```
    </Tab>

    <Tab title="index.tsx">
      ```js theme={null}
        export interface Money {
          amount: number;
          currency: 'USD' | 'EUR' | 'GBP';
        }
      ```
    </Tab>
  </Tabs>
</Card>

### Utilities

The examples below define a utility under `packages/utils` that will format data using the `Money` type from above.

<Card>
  <Tabs>
    <Tab title="package.json">
      ```json theme={null}
      {
        "name": "@my-hubspot-project/utils",
        "private": true,
        "version": "1.0.0",
        "main": "index.ts",
        "dependencies": {
          "@my-hubspot-project/types": "1.0.0"
        }
      }
      ```
    </Tab>

    <Tab title="index.tsx">
      ```js theme={null}
        import { Money } from "@my-hubspot-project/types";

        export function formatDate(date: Date | string): string {
          const d = typeof date === 'string' ? new Date(date) : date;
          return d.toLocaleDateString('en-US', {
            month: 'short',
            day: 'numeric',
            year: 'numeric',
          });
        }

        export function formatMoney(money: Money): string {
          return new Intl.NumberFormat('en-US', {
            style: 'currency',
            currency: money.currency,
          }).format(money.amount);
        }
      ```
    </Tab>
  </Tabs>
</Card>

### Components

The examples below demonstrate a shared component that lives under `packages/components`.

<Card>
  <Tabs>
    <Tab title="package.json">
      ```json theme={null}
        {
          "name": "@my-hubspot-project/components",
          "private": true,
          "version": "1.0.0",
          "main": "index.tsx",
          "dependencies": {
            "@hubspot/ui-extensions": "latest",
            "react": "^18.2.0"
          }
        }
      ```
    </Tab>

    <Tab title="index.tsx">
      ```js theme={null}
        import { Text, Flex, Divider } from "@hubspot/ui-extensions";

        interface SectionProps {
          title: string;
          children: React.ReactNode;
        }

        export const Section = ({ title, children }: SectionProps) => (
          <Flex direction="column" gap="sm">
            <Text format={{ fontWeight: "bold" }}>{title}</Text>
            <Divider />
            {children}
          </Flex>
        );
      ```
    </Tab>
  </Tabs>
</Card>

## Add dependencies to extensions

After you've defined your shared code under `packages/`, add the path to your shared packages in each of your extension's respective `package.json` files:

```json theme={null}
{
  "name": "@my-hubspot-project/my-cards",
  "dependencies": {
    "@hubspot/ui-extensions": "latest",
    "@my-hubspot-project/types": "1.0.0",
    "@my-hubspot-project/components": "1.0.0",
    "@my-hubspot-project/utils": "1.0.0"
  }
}
```

## Use shared code in your UI extensions

The following code block shows how to use your shared code within one of your UI extensions:

```jsx theme={null}
import { hubspot } from "@hubspot/ui-extensions";
import { Text } from "@hubspot/ui-extensions";
import { Money } from "@my-hubspot-project/types";
import { Section } from "@my-hubspot-project/components";
import { formatDate, formatMoney } from "@my-hubspot-project/utils";

const dealAmount: Money = { amount: 15000, currency: 'USD' };

hubspot.extend<'crm.record.tab'>(({ context }) => (
 <Section title="Deal Summary">
   <Text>Amount: {formatMoney(dealAmount)}</Text>
   <Text>Close Date: {formatDate('2024-03-15')}</Text>
 </Section>
));
```

After you've added the imports of your shared code in your UI extensions, you can proceed with the next step of installing the shared packages so the project will build.

## Install shared packages

To ensure your shared packages can be imported successfully in your UI extension, run the following command anywhere in your project:

```shell theme={null}
hs project install-deps
```

Alternatively, your shared packages will automatically be installed next time you run `hs project dev` or `hs project upload`.
