I have migrated our 2025.1 CRM extension to 2025.2 and would like to make use of the new Page feature. So far we have mostly been using Cards. For that I would like to share code between the Page and Card but that doesn’t seem to be possible. Relative paths, softlinks, nothing worked. When i try to run “hs project upload” there are always errors.
Is there a good way to do this?
Hi @OStangenberg and welcome, we are so glad to have you here!
Thanks for sharing your question with the HubSpot Community!
- Can you share the specific errors you’re seeing when you run “hs project upload”?
- How are you currently attempting to share code between the Page and Card? (e.g., folder structure, symbolic links, etc.)
- Are both your Page and Card components part of the same project, or are they in separate projects?
- Which files or types of code are you trying to share (e.g., utilities, services, UI components)?
The more info, screenshots (without sensitive/confidential information), and details you can provide, the better the Community can assist.
I’d love to put you in touch with our Top Experts: Hi @nickdeckerdevs1, @anton and @sylvain_tirreau do you have suggestions to help @OStangenberg, please?
Have a fantastic day and thanks so much!
Bérangère
Both the cards and home-page are in the same project. I would ideally want to share both utility code and UI components.
I have a directory structure like this:
If I try to reference the common.tsx from the Home.tsx, via ../cards/common.tsx I get this error
RollupError: Could not resolve “../cards/common” from “../../tmp/extensions/Home.tsx”
If i set it up as a soft-link to ../cards/common.tsx i get this error instead
Error: Transform failed with 1 error:
/tmp/extensions/common.tsx:1:0: ERROR: Unexpected “.”
@OStangenberg You could try defining each element you want to reuse as an independent package and use the dependency management system to reuse them (Accounts Dashboard | HubSpot).
worst case i could probably do that but it seems like a huge pain
@OStangenberg Otherwise you put your code (JS/TS types) in a “shared” folder, you generate a local NPM tarball (npm pack ./shared) that you store in “src/app/vendor”; in “src/app/cards/package.json” and “src/app/pages/package.json” you declare the .tgz as a dependency (“@stuff/hs-shared": "file:../vendor/your-tarball.tgz”). Then hs project install-deps and hs project upload.
This does not work. When trying to upload i get an error
tarball data for extension-cards@file:/tmp/vendor/shared-0.1.0.tgz (…) seems to be corrupted
…
npm error path /tmp/vendor/shared-0.1.0.tgz
npm error errno -2
npm error enoent ENOENT: no such file or directory, open ‘/tmp/vendor/shared-0.1.0.tgz’
I also tried referencing the directory directly as dependency. In that case I can upload but the extension fails to load on the page (works fine in dev mode though)
You specify an absolute path: this makes sense locally, but on Hubspot, it doesn’t make any sense. Specify a relative path in the project root. Something like this:
project-root
shared
src
package.json
tsconfig.json
src
app
cards
package.json
vendor
hs-shared.tgz
pages
package.json
vendor
hs-shared.tgz
Then do npm pack ./shared and copy the result into both vendor folders.
Then declare your dependency in both packages (cards and pages), like this:
“hs-shared”: "file:./vendor/hs-shared.tgz"
Then:
hs project install-deps
hs project upload
Add this to the json package in the shared folder:
“peerDependencies”: {
“react”: “^18”,
“@hubspot/ui-extensions”: “*”
}
“hs-shared” used in the tgz file name and the dependency name is the value of the “name” variable in the package.json of the “shared” folder.
I am building a 2025.5 Project that houses multiple distinct applications—specifically a Settings App and a CRM Cards App.
HubSpot now supports sharing code between UI extensions using npm workspaces, so App Cards, App Home pages, and Settings pages within the same app can share common utilities, types, and components. For UI extensions within the same app, npm workspace support can now be used to share common code without duplicating it or maintaining a custom bundling pipeline.
If hs project upload could automatically resolve imports from a common directory at the project root, we could maintain a clean, DRY monorepo structure without the overhead of external bundlers. This would significantly improve the developer experience for complex, multi-app projects.
Instructions for doing custom bundles to achieve this would also be appreciated.
Moderator Note: this post was reviewed for relevancy and optimized for clarity on September 29, 2026. Thank you for your contributions to the HubSpot Community!
Hey @wmisiedjan2 and welcome, we are so glad to have you here!
Thanks for sharing your valuable feedback! I recommend that you submit it via the HubSpot Developer Feedback form.
Also, I’d love to put you in touch with our Top Experts: Hi @sylvain_tirreau, @Anton do you have any insight or suggestions to help @wmisiedjan2, please?
Thanks so much and have a wonderful day!
Bérangère