Logo georglind.dk
Strapi v5 Local Plugins Made Easy: A Guide to a Clean Monorepo Setup

Strapi v5 Local Plugins Made Easy: A Guide to a Clean Monorepo Setup

August 19, 2025
4 min read
Table of Contents
local-plugin-in-strapi-v5

If you’ve ever tried to integrate a local plugin into your Strapi v5 project, you might have felt the frustration. You want to add a custom widget or extend the admin UI, and the docs just point you toward building a plugin. But what happens next? How do you manage this new plugin alongside your main Strapi application without a clunky, manual build process?

After scouring forums and finding more questions than answers, I pieced together a solution that’s surprisingly simple and elegant. Here’s how to tame your local plugins using a clean monorepo structure.

Part 1: Creating Your Local Plugin

First, let’s get the basic plugin running. Strapi’s documentation provides a solid starting point.

  1. Scaffold a new Strapi app if you haven’t already.

    Terminal window
    npx create-strapi-app@latest my-project
  2. Generate your plugin using the official SDK. This command creates a dedicated packages/my-local-plugin folder, which is a complete Node.js project in itself.

    Terminal window
    npx @strapi/sdk-plugin init packages/my-local-plugin
  3. Register the plugin with your Strapi application. Create or edit config/plugins.ts to tell Strapi where to find it.

    config/plugins.ts
    export default {
    'my-local-plugin': {
    enabled: true,
    resolve: './packages/my-local-plugin',
    },
    };

At this point, you can cd into packages/my-local-plugin and run npm run watch to auto-rebuild the plugin as you make changes. This is great for development, but it’s not a sustainable solution for a team or for deployment.

Part 2: The Monorepo Magic

Having to manually build sub-folders is cumbersome. The answer is to treat your entire Strapi project as a monorepo. We can do this easily with npm’s built-in workspaces feature.

  1. Define your workspaces. In your main project’s package.json, tell npm where to find your sub-packages.

    package.json
    // ...existing code...
    "workspaces": [
    "packages/*"
    ],
    // ...existing code...

    Now, when you run npm install from the root, npm will also install dependencies for your local plugin. You can test this by deleting all node_modules folders and running npm install from your project’s root directory.

  2. Isolate your TypeScript configs. You don’t want the main Strapi TypeScript compiler to process your plugin’s source code; the plugin has its own build process. Add an exclude rule to your root tsconfig.json.

    tsconfig.json
    // ...existing code...
    "exclude": [
    // ...existing code...
    "packages/**",
    ]
  3. Unify the build process. This is the key step. Instead of building each piece separately, you can run a single command from the root folder to build all workspaces. The --workspaces flag tells npm to run the build script in every package defined in your workspaces array.

    Terminal window
    npm run build --workspaces

    This command will call the build script in packages/my-local-plugin, creating its dist folder.

  4. Streamline with npm scripts. To make the process even smoother, let’s add some helper scripts to the root package.json. This combines building the plugins and the main Strapi app into a single command.

    package.json
    // ...existing code...
    "scripts": {
    // ...existing code...
    "build:plugins": "npm run build --workspaces",
    "build:strapi": "strapi build",
    "build": "npm run build:plugins && npm run build:strapi",
    "dev": "strapi develop",
    "start": "strapi start",
    // ...existing code...
    },
    // ...existing code...
  5. Build and run. Now, you have a simple, unified workflow.

    For development, run Strapi as usual, but remember to build the plugin first:

    Terminal window
    npm run build:plugins
    npm run dev

    For production, the process is just as clean:

    Terminal window
    npm run build
    npm run start

That’s it! With this setup, anyone can clone your project and get it running with a familiar npm install and npm run build. No more cd-ing into sub-folders or manual build steps. Just a simple, clean, and efficient workflow.