WordPress.org

WordPress Developer Blog

Implementing namespaces and coding standards in WordPress plugin development

Implementing namespaces and coding standards in WordPress plugin development

As WordPress projects grow in complexity, organizing your codebase becomes essential. Whether you’re building a plugin, theme, or block library, a clean and scalable architecture makes development faster, onboarding easier, and long-term maintenance far less painful.

In Refactoring the Multi-Block Plugin: Build Smarter, Register Cleaner, Scale Easier, I walked through setting up a flexible structure for managing multiple static, dynamic, and interactive blocks within a single plugin. That setup serves as the foundation for this guide.

Here, we’ll take things a step further by introducing PHP namespaces, autoloading with Composer, and enforcing consistent coding standards across JavaScript, CSS, and PHP. These aren’t just best practices — they’re practical steps for maintaining quality and scaling your code as your project grows.

We’ll walk through:

  • Setting up PSR-4 autoloading with Composer
  • Structuring plugin functionality into reusable, purpose-driven classes
  • Enforcing consistent styles with automated linting and formatting tools

This workflow is flexible enough for solo developers, yet robust enough to support team collaboration on large-scale projects.

Pre-requisites

This article builds on Refining a Multi-Block Plugin. If you’ve already followed that guide to scaffold a plugin with static, dynamic, and interactive blocks, you’re ready to dive into this next step.

Prefer to skip the setup? The full plugin built in this article is available on GitHub with each section of this article is represented in a branch.

Want to follow along but don’t want to build the multi-block start point? You can clone the multi-block repo, run npm install and start from there.

Either approach will give you a ready-to-use starting point with namespacing, Composer autoloading, and linting already wired up.

Namespacing and classes

As the plugin grows, it’s important to keep the code organized and easy to manage. I use PHP namespaces and split functionality into classes so each part of the plugin has a clear purpose. This helps avoid naming conflicts and makes the codebase easier to scale and maintain.

Composer and autoloading

To streamline how classes are loaded, I use Composer with PSR-4 autoloading. This means I don’t need to manually include files, Composer automatically loads classes based on the namespace and folder structure I define.

In this setup, I use the namespace Advanced_Multi_Block to group all plugin-related classes. This acts like a prefix, helping avoid naming conflicts and keeping everything contained within the plugin’s scope.

I start by creating a composer.json file in the plugin root and adding the following:

{
  "name": "multi-block/namespacing-coding-standards",
  "description": "An advanced multi block plugin with custom functionality.",
  "type": "wordpress-plugin",
  "license": "GPL-2.0-or-later",
  "autoload": {
      "psr-4": {
          "Advanced_Multi_Block\\": "Functions/"
      }
  }
}

Then I run: composer install. This generates the vendor folder and an autoloader that I can include in the main plugin file.

Files and classes

With autoloading in place, I organize all class-based PHP files into a Functions folder inside the plugin. This keeps everything in one place and makes it easier to manage as the plugin grows.

Each class handles a specific piece of functionality and is namespaced under Advanced_Multi_Block. This structure helps keep responsibilities clear and avoids naming conflicts across the codebase.

Plugin Paths
This class provides helper methods for getting the plugin’s base path and URL. I use it throughout the plugin to avoid repeating logic or relying on hardcoded values.

Inside the Functions directory I create Plugin_Paths.php and paste in the following code:

<?php

namespace Advanced_Multi_Block;

if ( ! defined( 'ABSPATH' ) ) {
  exit;
}

class Plugin_Paths {
  public static function plugin_url() {
      return plugin_dir_url( dirname( __FILE__ ) );
  }
  public static function plugin_path() {
      return plugin_dir_path( dirname( __FILE__ ) );
  }
}

Register Blocks
This class handles the logic for finding and registering blocks. I hook into the init action in the constructor, and use Plugin_Paths to get the plugin’s path.

The register_blocks() method loops through each block directory, checks for a block.json file, and registers the block. If the block includes a viewScriptModule field, it adds a filter so WordPress loads the required assets for interactive blocks.

Inside the Functions directory I create Register_Blocks.php and paste in the following code:

<?php

namespace Advanced_Multi_Block;

use Advanced_Multi_Block\Plugin_Paths;

if ( ! defined( 'ABSPATH' ) ) {
  exit;
}

class Register_Blocks {
  public function __construct() {
      add_action( 'init', array( $this, 'register_blocks' ) );
  }

  public function register_blocks() {
      if ( function_exists( 'wp_register_block_types_from_metadata_collection' ) ) {
          wp_register_block_types_from_metadata_collection( Plugin_Paths::plugin_path() . 'build/blocks', Plugin_Paths::plugin_path() . '/build/blocks-manifest.php' );
          return;
      }

      if ( function_exists( 'wp_register_block_metadata_collection' ) ) {
          wp_register_block_metadata_collection( Plugin_Paths::plugin_path() . 'build/blocks', Plugin_Paths::plugin_path() . '/build/blocks-manifest.php' );
      }

      $manifest_data = include Plugin_Paths::plugin_path() . 'build/blocks-manifest.php';
      foreach ( array_keys( $manifest_data ) as $block_type ) {
          register_block_type( Plugin_Paths::plugin_path() . "build/blocks/{$block_type}" );
      }
  }
}

Enqueue
This class registers two global asset entry points, one for the editor and one for the frontend. These scripts are separate from block-specific scripts and are useful for features like block variations, editor UI enhancements, or global behavior that spans multiple blocks.

Each script uses its corresponding .asset.php file to ensure dependencies and versioning are handled correctly. I use the Plugin_Paths helper to reference the correct paths and URLs.

Inside the Functions directory, I create a file named Enqueues.php and add the following code:

<?php

namespace Advanced_Multi_Block;

use Advanced_Multi_Block\Plugin_Paths;

if ( ! defined( 'ABSPATH' ) ) {
  exit;
}

class Enqueues {
  public function __construct() {
      add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_assets' ) );
      add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) );
  }

  /**
    * Enqueues the block assets for the editor
    */
  public function enqueue_block_assets() {
      $asset_file = include Plugin_Paths::plugin_path() . 'build/editor-script.asset.php';

      wp_enqueue_script(
          'editor-script-js',
          Plugin_Paths::plugin_url() . 'build/editor-script.js',
          $asset_file['dependencies'],
          $asset_file['version'],
          false
      );
  }

  /**
    * Enqueues the block assets for the frontend
    */
  public function enqueue_frontend_assets() {
      $asset_file = include Plugin_Paths::plugin_path() . 'build/frontend-script.asset.php';

      wp_enqueue_script(
          'frontend-script-js',
          Plugin_Paths::plugin_url() . 'build/frontend-script.js',
          $asset_file['dependencies'],
          $asset_file['version'],
          true
      );
  }
}

Updating main plugin file

With the classes and autoloading in place, I update the main plugin file to load everything properly. First, I check for the Composer autoload file and require it. Then I instantiate the core classes so their functionality is registered with WordPress.

This setup keeps the main file clean and focused while letting each class handle its own responsibilities.

<?php

if (! defined('ABSPATH') ) {
  exit;
}

// Include Composer's autoload file.
if ( file_exists( plugin_dir_path( __FILE__ ) . 'vendor/autoload.php' ) ) {
  require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
} else {
  wp_trigger_error( 'Advanced Multi Block Plugin: Composer autoload file not found. Please run `composer install`.', E_USER_ERROR );
  return;
}

// Instantiate the classes.
$advanced_multi_block_classes = array(
  \Advanced_Multi_Block\Plugin_Paths::class,
  \Advanced_Multi_Block\Register_Blocks::class,
  \Advanced_Multi_Block\Enqueues::class,
);

foreach ( $advanced_multi_block_classes as $advanced_multi_block_class ) {
  new $advanced_multi_block_class();
}

Coding standards

Keeping code consistent is one of the easiest ways to improve collaboration and long-term maintainability, especially in larger or shared codebases. This section shows how I set up JavaScript, CSS, and PHP linting and formatting for this plugin using WordPress’s recommended tools.

Note: This isn’t meant to be a strict rule set. It’s a working starting point you can use as-is or adapt to fit your team’s preferences.

Add linting for JS

To enforce consistent code across my JavaScript files, I set up linting with ESLint and formatting with Prettier using the WordPress recommended configurations.

I install the required development dependencies:

npm install --save-dev @wordpress/eslint-plugin eslint-config-prettier @wordpress/prettier-config eslint-config-prettier

Then I create a .eslintrc.json file at the root of the plugin with the following configuration. It extends the recommended rules from the WordPress ESLint plugin and sets up a few environment and parser options:

{
  "extends": ["plugin:@wordpress/eslint-plugin/recommended"],
  "env": {
      "browser": true,
      "es6": true,
      "jquery": true
  },
  "parserOptions": {
      "requireConfigFile": false,
      "ecmaVersion": 2021,
      "sourceType": "module"
  },
  "rules": {
      "@wordpress/no-global-active-element": "warn",
      "@wordpress/no-unsafe-wp-apis": "warn"
  }
}

I also add a .eslintignore file to prevent linting of compiled and third-party files:

/build/
/vendor/
/node_modules/
*.css
*.scss

To handle code formatting, I create a .prettierrc file with my preferred style rules:

{
  "tabWidth": 4,
  "useTabs": true,
  "printWidth": 100,
  "singleQuote": true,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "arrowParens": "avoid",
  "semi": true,
  "bracketSameLine": false,
  "jsxSingleQuote": false,
  "jsxBracketSameLine": false
}

I also create a .prettierignore file to exclude generated and dependency directories:

build
node_modules
vendor

In package.json, I add the following scripts to lint and format JS files. These replace any existing lint:js or format:js entries:

"lint:js": "wp-scripts lint-js --max-warnings=0",
"format:js": "wp-scripts lint-js --fix",

I can now run npm run lint:js or npm run format:js to lint and fix JavaScript files.

Add linting for CSS

To ensure consistency and catch potential issues in my SCSS files, I configure Stylelint using WordPress’s recommended configuration for SCSS.

I install the necessary development dependencies:

npm install --save-dev @wordpress/stylelint-config stylelint stylelint-scss

Then I create a .stylelintrc.json file at the root of the plugin with the following configuration. This extends the WordPress SCSS rules and disables a couple of rules to match my preferred style:

{
  "extends": ["@wordpress/stylelint-config/scss"],
  "rules": {
      "at-rule-no-unknown": null,
      "selector-class-pattern": null,
      "scss/at-rule-no-unknown": true
  }
}

I also create a .stylelintignore file to exclude compiled and vendor files:

build/
node_modules/
vendor/
*.min.css
*.min.scss

In package.json, I add the following scripts to lint and fix SCSS files. These replace any existing lint:css or format:css entries:

"lint:css": "stylelint \"**/*.scss\" --max-warnings=0",
"format:css": "stylelint \"**/*.scss\" --fix",

I can now run npm run lint:css or npm run format:css to lint and fix CSS files.

Add linting for PHP

To enforce WordPress coding standards in my PHP files, I use PHP_CodeSniffer with the WordPress Coding Standards (WPCS) ruleset. This setup helps catch common issues and maintain consistency across the plugin.

I start by creating a phpcs.xml.dist file in the plugin root with the following configuration:

<?xml version="1.0"?>
<ruleset name="WordPress Plugin Coding Standards">
  <description>A custom set of rules to check for a WordPress plugin</description>

  <!-- What to scan -->
  <file>.</file>
  <exclude-pattern>/build/</exclude-pattern>
  <exclude-pattern>/node_modules/</exclude-pattern>
  <exclude-pattern>/vendor/</exclude-pattern>
  <exclude-pattern>src/blocks-manifest.php</exclude-pattern>
  <exclude-pattern>build/*.asset.php</exclude-pattern>

  <!-- How to scan -->
  <arg value="sp"/>
  <arg name="basepath" value="."/>
  <arg name="colors"/>
  <arg name="extensions" value="php"/>
  <arg name="parallel" value="4"/>

  <!-- Rules: WordPress Coding Standards -->
  <config name="minimum_supported_wp_version" value="6.6"/>
 
  <rule ref="WordPress">
      <exclude name="Generic.Arrays.DisallowShortArraySyntax"/>
      <exclude name="Generic.Functions.CallTimePassByReference"/>
      <exclude name="WordPress.PHP.YodaConditions.NotYoda"/>
  </rule>
 
  <rule ref="WordPress.Arrays.MultipleStatementAlignment">
      <properties>
          <property name="maxColumn" value="80"/>
      </properties>
  </rule>

  <rule ref="WordPress.NamingConventions.PrefixAllGlobals">
      <properties>
          <property name="prefixes" type="array">
              <element value="Advanced_Multi_Block"/>
          </property>
      </properties>
  </rule>

  <rule ref="WordPress.WP.I18n">
      <properties>
          <property name="text_domain" type="array">
              <element value="advanced-multi-block"/>
          </property>
      </properties>
  </rule>
</ruleset>

This is a starting point based on the official WordPress standards. I’d recommend reviewing the full WPCS documentation if you want to customize it further.

Next, I update my composer.json file to install the required dependencies and define scripts for linting and formatting:

{
  "name": "wp-dev-blog/refactor-multi-block-plugin",
  "description": "An advanced multi block plugin with custom functionality.",
  "type": "wordpress-plugin",
  "license": "GPL-2.0-or-later",
  "autoload": {
      "psr-4": {
          "Advanced_Multi_Block\\": "Functions/"
      }
  },
  "require-dev": {
      "wp-coding-standards/wpcs": "^3.1"
  },
  "config": {
      "allow-plugins": {
          "dealerdirect/phpcodesniffer-composer-installer": true
      }
  },
  "scripts": {
      "format": "./vendor/bin/phpcbf --report-summary --report-source || true",
      "lint": "./vendor/bin/phpcs"
  }
}

Then I run: composer update to install the new packages.

In package.json, I add the following scripts to lint and fix PHP files. These replace any existing lint:php or format:php entries:

"lint:php": "composer run lint",
"format:php": "phpcbf --standard=phpcs.xml.dist -v",

I can now run npm run lint:php or npm run format:php to lint and fix PHP files.

Global commands

To keep all linting commands consistent across environments, I add the following to package.json:

"lint": "npm run lint:js && npm run lint:php && npm run lint:css",
"format": "npm run format:js && npm run format:php && npm run format:css",

Autoloading with Composer

With Composer’s PSR-4 autoloading defined in composer.json, you don’t need manual require statements for your classes. The main plugin file loads the generated vendor/autoload.php, and Composer handles the rest.

Whenever you add, move, or rename classes, run: composer dump-autoload

This step refreshes the class map so new or updated files are discoverable. It’s an easy but important habit that prevents “class not found” errors and keeps your plugin’s structure in sync with your namespaces.

Conclusion

By adding namespacing, Composer autoloading, and clear coding standards, you create a foundation that’s built to last. Your code becomes easier to reason about, test, and extend — and it stays that way as your plugin or theme grows.

Each component of this setup plays a part:

  • Namespaces and classes separate concerns and reduce conflicts
  • Composer autoloading eliminates boilerplate and scales effortlessly
  • Linting and formatting tools keep your code clean and consistent across the entire stack

This approach isn’t just about polish, it’s about building with confidence and avoiding slowdowns as your codebase evolves. Whether you’re building for clients, teams, or yourself, these practices help ensure the project remains maintainable, performant, and collaborative.

As always, feedback is welcome. If you have suggestions, questions, or want to share how you’re structuring your own projects, I’d love to hear from you.

Props to @meszarosrob and @milana_cap for reviewing this article and offering feedback.

14 responses to “Implementing namespaces and coding standards in WordPress plugin development”

  1. K. Adam White Avatar

    This is an excellent tutorial, and namespaces are a key element of how we and many other larger-scale WordPress agencies organize our code; I strongly encourage all plugin developers to give this a try.

    If the syntax above seems intimidating, I’d also suggest that the Class-based code organization isn’t strictly necessary. If you have a function in a namespace (outside a class — imagine a PHP file with a namespace declaration at the top, and then a normal function some_name() {} definition down below), you can bind that to an action easily by using the __NAMESPACE__ magic constant.

    add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\enqueue_block_assets' );

    You can therefore omit the wrapper class entirely whenever it isn’t needed to keep track of dynamic values. I personally find this makes the overall plugin easier to skim through. The class file can instead become a sub-namespace like Advanced_Multi_Block\Enqueues, and the constructor can become a bootstrap function that you call directly from the plugin entrypoint as Advanced_Multi_Block\Enqueues\bootstrap(); rather than instantiating classes.

    Classes are excellent for data encapsulation, but if you find them intimidating or overly verbose to set up functional hooks like this, you can use namespaces on their own to simplify your plugin’s codebase!

    1. Troy Chaplin Avatar

      Thank you for the kind words and great feedback, K. Adam. I’ve worked on and currently manage a large-scale WP project that we’ve been evolving over the last 15 years and approaches like this are used throughout our code as well.

  2. Dennis Ploetner Avatar

    Thanks for sharing this! I’ve got a small doubt though: isn’t it a bit verbose to define `–standard=phpcs.xml.dist` in the scripts? From what I understand, PHPCS will automatically pick up phpcs.xml.dist (or phpcs.xml) in the project root.

    Also, wouldn’t it be safer to call the binaries from `vendor/bin/` instead of relying on the global path? That way you’re always using the project’s installed version.

    Curious to hear your thoughts, maybe I’m missing a reason why you prefer the explicit approach.

    1. Troy Chaplin Avatar

      Thanks for the feedback Dennis. You’re correct on the not needing to define the phpcs file. I actually did not know this, I was always shown the setup this way and while I’ve improved other areas since learning, this was not one of them. So thanks for pointing this out.

      I originally did have the paths set to ./vendor/bin, but I got some other feedback earlier and when I updated the article I inadvertently removed those pieces. Thanks for point that out.

      I’ve updated the article based on the feedback.

  3. mb00 Avatar
    mb00

    Thank you for a great article covering modern development practices but there are a few things that really should be pointed out:

    1. Avoid enqueuing front-end assets (scripts/styles) site wide. Plugin should register asset first and only enqueue it on pages where it is consumed. There is no easy one fix for all kind of uses cases but this should always be a priority.

    2. It’s been a while since wp_register_script()/ wp_enqueue_script() has been updated to accept array as last argument instead of old style $in_footer = true/false. Set strategy. It’s not that hard.

    3. You did not want to include individual files one by one manually, but now you listing all classes and then looping to initialize them. Would you be doing this with 100 class files as well? Pointing this out only because that’s what a large majority of junior developers will end up doing.

    4. Not every single function have to be wrapped in class. It’s not a crime to have helper functions file, heck, have a few files of helper functions if you have large plugin.

    5. Add links to WordPress coding standards pages. A lot of people don’t understand why things are done in one way or another and some of them never even heard of coding standards. Those pages explain in details do’s and don’ts and will make sense why linting is useful.

    1. Troy Chaplin Avatar

      Thanks for taking the time to share your thoughts. While I don’t necessarily agree with all of your points, or the way they were framed, I do appreciate you contributing your perspective and highlighting areas where developers often take different approaches.

      One thing I completely agree on is the value of pointing readers to official resources like the WordPress coding standards. That’s something I plan to add in a follow-up update.

  4. Kaspars Avatar

    This is a great tutorial on implementing some of the more advanced features of WordPress development. However, the examples used in this article (specifically for the configuration files) seem to be a bit verbose and opinionated to potentially distract from the main story of how to get started with these features.

    1. The PSR-4 standard isn’t compatible with the WordPress coding standards which require that PHP class filenames have the following format class-name-of-class.php where class- is a generic prefix and name-of-class maps to the actual class name Name_Of_Class (unless those are test files which require PSR-4 now). To match that requirement, consider using the Composer classmap autoloader instead. The only downside is that you need to run composer dump-autoload whenever you add a new class file while PSR-4 is fully dynamic (unless an optimized autoloader is used).

    2. Plugins and themes installed using Composer already handle the autoloading at the project level so requiring vendor/autoload.php should be done only if a known class can’t be resolved (since it might be already loaded by the project-wide autoloader):

    if ( ! class_exists( Advanced_Multi_Block\Plugin_Paths::class ) && file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
    require_once __DIR__ . '/vendor/autoload.php';
    }

    with an optional error if it still failed to load:

    if ( ! class_exists( Advanced_Multi_Block\Plugin_Paths::class ) ) {
    wp_trigger_error( 'Advanced Multi Block Plugin: Composer autoload file not found. Please run `composer install`.', E_USER_ERROR );
    return;
    }

    3. The @wordpress/scripts package handles automatic configuration for both eslint and stylelint. Would it be better to rely on the bundled configuration instead of maintaining custom configs which often get out of date or break as the associated tools are updated?

    4. The suggested phpcs.xml.dist is making opinioned decisions about allowing short array syntax not requiring the yoda conditionals from the default WordPress ruleset. Should we call out that it makes the code not fully compliant with the WordPress coding standards, and should be done only based on project needs/preference?

    5. The && command chaining referenced in npm run lint:js && npm run lint:php && npm run lint:css is only available in unix shells and not Windows. Should we suggest using the npm-run-all helper similar to how Gutenberg project does it?

    6. The PHP class examples use constructors for running WP hooks which is considered a bad practice since (1) it doesn’t allow for conditional logic that depends on other class logic and (2) requires classes to be instantiated in a specific order if they do depend on other classes, and also (3) makes them harder to test. It would be better to introduce an init() or register() method which does all the integration with WP lifecycle while the constructor is reserved for lightweight bootstraping and accepting dependencies/configuration.

    1. Troy Chaplin Avatar

      Wow, thank you for such a thorough and constructive comment, Kaspars. You not only raised excellent points here, but also went the extra mile by submitting a PR with detailed notes explaining the changes and their benefits. That’s above and beyond.

      I really appreciate the care you put into this. My plan is to review your PR closely, both to learn from your suggestions and to update the article so it provides an even stronger resource for future readers.

      Thanks again for helping make this a better resource for the community.

  5. Andry Avatar

    Good recommendations, the only thing I completely disagree with is the formation of the CSS. I believe that absolutely all block components should by default provide an optimized and minimized format for clients, and how exactly it is stylized is absolutely irrelevant.

    I see in your recommendations to create .min.css files for components, but I don’t see where exactly you use them.

    1. Troy Chaplin Avatar

      Thanks for your comments! I’m not sure what you mean here, as this article doesn’t cover the creation of build files. The CSS setup comes from the prior article that this one builds on.

  6. Thoriq Firdaus Avatar

    Hi, Troy.

    Thanks for covering this. I’m really glad to see WordPress finally showing more standard PHP development practices in the examples, like using namespaces.

    Kaspars has already pointed out several valid points that I agree with, but I’d like to add a few more thoughts 😀

    1. Since the tutorial mentions PSR-4, I think it might be worth considering creating the class in PascalCase without underscores. Historically, underscores were often used as a sort of “namespace” before namespaces existed in PHP. Now that namespaces are available, I think using underscores no longer feel necessary. Using PascalCase would bring WordPress closer to the conventions used across the wider PHP ecosystem.

    2. The Plugins_Path class doesn’t seem necessary to instantiate in the plugin’s main file. I think it could be simplified by defining __FILE__ and __DIR__ as constants in the plugin main file. This could also serve as a good example of how to use namespaces with constants.

    3. Building on point 2, I think Plugins_Path could even be simplified into a function. That way, the tutorial could also demonstrate how Composer can autoload functions, not just classes.

    Altogether, this would nicely expand the examples to cover namespaces in classes, functions, and constants.

    1. Troy Chaplin Avatar

      Thanks for this great feedback Thoriq. I am working on some revisions to this article based on all the great feedback that I’ve received, and I appreciate you taking the time to not only make this comment, but to also create a PR based on the feedback.

  7. Benj Grolleau Avatar

    Thank you very much, Troy, for sharing this. It’s really nice to see autoloading and PSR-4 being discussed in the WordPress ecosystem.

    There’s one point I’d like to add, building on the previous comments: it’s generally not the constructor’s responsibility to register actions or filters. A cleaner approach is to move that into a dedicated “hooks” method. This keeps the constructor focused only on the actual construction of the object.

    Also, instead of manually instantiating every class, I’d recommend looking into autowiring and service containers. They make dependency management much easier, even if there’s a bit of a learning curve at first.

    That said, your article is an excellent (and big!) first step into namespaces and more modern PHP practices within WordPress. Thanks again!

  8. Antony Booker Avatar

    I think this might have been mentioned already regarding PSR-4 but for performance on production it would be best to use authoritative autoloading for composer. With multiple plugins/themes using PSR-4 it can cause file exist checks for non-existent files between plugins:

    “on the filesystem-based discovery (PSR-0 or PSR-4), the best practice is indeed to have a prefix as precise as possible, to avoid running filesystem checks for other classes. But note that this mechanism will always be slower than using the optimized autoloader than composer can generate.”

    https://github.com/composer/composer/issues/10205

Leave a Reply

Your email address will not be published. Required fields are marked *