Using Shared Packages in Firebase Monorepos
Firebase breaks with file:../shared deps. Use npm pack + tarball approach: preinstall script creates .tgz locally, gets included in deploy.
In a recent project I needed to share TypeScript types and utilities between my React frontend (Firebase Hosting) and Express backend (Firebase Cloud Functions).
file:../shared
breaks Firebase deployment
I started with the obvious approach - referencing the shared package locally:
{
"dependencies": {
"@company/shared": "file:../shared"
}
}
This works perfectly in development, but Firebase Functions deployment fails. The cloud build environment can't resolve the relative path ../shared
since it only uploads your functions directory.
Use npm tarballs instead of relative paths
Use npm's tarball approach instead. In your functions package.json
:
{
"scripts": {
"preinstall": "if [ -d ../shared ]; then npm pack ../shared; fi"
},
"dependencies": {
"@company/shared": "file:./company-shared-1.0.0.tgz"
}
}
The preinstall
script creates a tarball locally (but skips in cloud via the if
check). The tarball gets included in Firebase's deployment package.
Automate pack/deploy/unpack workflow
In your API package.json:
{
"scripts": {
"shared:pack": "npm pack ../shared && npm i $(ls -t ./company-shared-*.tgz | head -n1) --save",
"shared:unpack": "npm i ../shared --save"
}
}
In your root package.json for coordinated deployment:
{
"scripts": {
"api-shared-pack": "npm run shared:pack --prefix api",
"api-shared-unpack": "npm run shared:unpack --prefix api",
"api-deploy": "npm run api-shared-pack && firebase deploy --only functions && npm run api-shared-unpack"
}
}
This automatically switches to tarball mode, deploys functions, then reverts to local development mode.