Add a Local Package as a Dependency to an App Within a pnpm Workspace

Share this video with your friends

Social Share Links

Send Tweet

Adding your local packages as dependencies in a pnpm worksapce mostly works the same way as adding external packages.

You can add them using the pnpm add command with a filter and the --workspace flag set. For example, pnpm add shared-ui --filter my-remix-app --workspace

The workspace flag ensures that it'll search for the package locally. Just make sure that you've remembered to run the build script in your package!

Instructor: [0:01] In this pnpm workspace, we now have a Remix application and we have a shared UI library which is very simple React type of library exporting a button here over the index.js file and compiling it with TypeScript. [0:15] In order to be able to use it in our Remix app, we can install it, direct Internet application. The easiest way to do so is to use a pnpm command directory so we can run pnpm, add shared UI. We can, again, use the filter command to target the My Remix app which is where we want to install it.

[0:36] We can use a -- workspace flag to make sure that this package that is being installed should be searched from some public registries such as npm, but should rather be fetch out of the local workspace. And so, once we install this, what happens is that in the Remix application, in the package.json, we get a new entry which is called here shared UI workspace.

[1:01] This workspace in front is a protocol to signal to pnpm that this is shared-ui library is something that should be installed from the local workspace. Meaning, from our packages or folders that we configured in our pnpm workspace here.

[1:17] Now that we have installed our shared-ui package here, we can go into the routes of Remix. Let's remove everything that is in here, which is just a default generated code. Let's return here, let's say, a div which uses one of our buttons that the shared-ui library exports.

[1:37] In this case, first of all, let's import that button which comes from this shared-ui library. Now down here, we can go ahead and use that button. Let's add it here on click handler just for the fun of it. Let's just console.log() out whatever gets passed. In this case, we just console.log() it here.

[1:57] As you can see, a very simple import from our shared-ui library. We use the button, we use it on the click handler that we added on our button component. We have here a "Click Me!" so this should work. Now we can again, from root of the workspace, issue a pnpm filter command. In this case, targeting my Remix app, passing the def as the command, so we want to launch it in local browser.

[2:21] What you get here is now an error. I intentionally let this happen just to show you why this is the case. The error tells us is that in that in that myRemix app Node modules, where we reference basically that shared-ui package, it cannot find the index.ts.

[2:40] The problem is that we didn't build that first. If we go here in the node modules folder, we can see the shared UI, but this is nothing than a symlink to our local package, which lists here in that packages folder shared UI.

[2:55] Actually, we don't have the disk folder because we didn't build that package first. Let's do that, pnpm --filter, shared UI build. This now creates this folder, and now again, we can run the Remix app. Now, it properly, we don't get any errors.

[3:13] Let's refresh the Remix app. We see the "click me" here. Let's open up the dev tools, and if we click, we can see it properly logs out the click handler.

[3:23] With this, we basically conclude that part, where we import a button, so a component from a shared UI Library here and this actually looks as if it was a public package, but it isn't because it just references over that package.json here.

[3:37] A local package that lives down here. We could reuse that functionality within that workspace, within that monorepo without having to first publish this, version it, and then again install it into our specific application.