If GitPkg doesn't work for you, npm has an awesome feature called 'workspaces' since v7. These are your friend for managing, deploying, etc from a subfolder of your main repo. They allow you to define an npm identity for your subfolder, and to make it npm install
-able in both the local repo and in others.
Defining your workspace is as simple as defining a folder where packages will live. Name it after your GitHub org, which we'll call '@namespace'. Put your package-name
subfolder within that, and then add a single line to the package.json
at the repo root:
"workspaces": ["@namespace/package-name"],
Then, run npm init -w @namespace/package-name
to create a package.json in the subfolder/workspace. (The -w
flag defines your workspace as the 'scope' of the npm command.)
Finally, run npm install
and all this magic will result in your node_modules for the root project now symlinking to that workspace subfolder as a dependency. You can now start referencing your workspace code like any other dependency, with import { thing } from '@namespace/package-name'
.
But, your real goal was to publish it into other projects, right? Well, for local dev, you can just npm install from the repo on your local machine, by referring to that workspace, such as (for a sibling folder): npm i -D ../repo-name/@namespace/package-name
.
But, what about when you get beyond local dev? What about when you need to install dependencies in CI for deployment, or let devs install without needing the whole repo that houses the package? For that, you need an npm-compatible package directory. You can use the npmjs.com directory, of course, and it's free if your repo is public. You just npm publish -w @namespace/package-name
to publish from that workspace subfolder. If your repo is private though, publishing to npmjs.com will cost you.
The new dark-horse option: especially if you're already using a paid GitHub plan, you can publish to and install from GitHub Packages for free. The GitHub Packages docs will cover this in detail, but it basically all boils down to using your .npmrc to define which registry has control over that @namespace you defined in the package.json. Place this line in .npmrc in the home repo containing the workspace, plus in all other repos that want to install the workspace package:
@namespace:registry=https://npm.pkg.github.com
Henceforth, npm will know to publish or install any dependencies within @namespace from GitHub Packages. And you'll have accomplished publication of a sub-folder at no extra cost.
(Note: GitPkg is a wonderful community service, and I tried it before going the workspaces/GitHubPackages route. However, it's the side project of a busy graduate student, and there are currently lots of 500 errors reported by users like me who could never make it work with their repo for some reason. Great if it works for you, but otherwise the above will get it done, and perhaps more scalably.)