In Drupal 7, if we wanted to push code to our environments enabling modules, we would call module_enable() in hook_update_N(). We no longer have that in Drupal 8, so how do we programmatically enable modules? Do we use Drupal 8's Configuration Manager or hook_update_N()?

A diff on the exported configuration yields this:

+++ b/cim/sync/core.extension.yml
@@ -10,6 +10,9 @@ module:
   config: 0
   contact: 0
   contextual: 0
+  ctools: 0

So it seems the module is enabled via code using Configuration Manager. We're also working with the idea of this:

function mymodule_update_8003() {
  $modules = array(

What is the correct method?

3 Answers 3


For site-specific changes, I would definitely go with using configuration deployments.

They have a very interesting advantage and difference to enabling modules in update hooks/through the API yourself. Config deployments can handle changed default configuration while installing the module.

A module might provide default configuration like views, settings and so on. They might also programatically do things during hook_install() that you want to customize (like configuring default formatters/widgets for fields they add) Configuration deployment allows you install a module locally, customize it and deploy the result as an atomic operation (as much as is possible) to production.

I'd only use the API and hook_update_N() if it's a functional change in a module, e.g. when a module is split up into a new one and/or has a new dependency that is mandatory for it to work.

Also note that I would advice against doing both in the same deployment. Update hooks might run code and create config that will result in differences on every run (like creating a new configurable field). Running config deployments first isn't possible anyway and will soon be prevented explicitly in core and running after might result in the deployment removing and re-adding configuration due to different UUID's.

  • Do you have a reference for core preventing config deployments being run first in the future?
    – gapple
    Commented Feb 17, 2016 at 22:03
  • Yes: drupal.org/node/2628144
    – Berdir
    Commented Feb 17, 2016 at 22:11
  • Thanks, that's a solid reference for my recent question
    – gapple
    Commented Feb 18, 2016 at 18:11
  • I'm marking this answer with the "check" but want to say that @gapple made a comment that actually solved it in my head.
    – mikeDOTexe
    Commented Feb 19, 2016 at 18:08
  • 1
    Answering my own question: 'What does a Drupal 8 "configuration deployment" look like in terms of code, for enabling a Drupal module?' The answer is that there is a boolean flag entry in core.extension.yml for each module as to when it is installed ("enabled") or not. which is made active by drush config-import, according to: drupal.stackexchange.com/questions/214918/… In actual fact, the original poster had mentioned core.extension.yml however it wasn't initial apparent to me that this was an approach I should consider. Thanks. Commented Jul 25, 2017 at 14:44

The code:

\Drupal::service('module_installer')->install($modules, TRUE);

Should be fine to use. This is how Drush enables modules and how they are enabled through /admin/modules. This should also create the configuration you need and it is best to stick to what core does. This will prevent any issues that hard-coding the config file might cause and if the way conf files are formatted changes, this will be updated to work with those changes.

  • Core is also doing/offering the configuration deployment functionality.
    – Berdir
    Commented Feb 17, 2016 at 22:12
  • Very true, but this offers more abstraction. If the format of the config files change you will have to manually update it. If you use this core will do it for you. Commented Feb 17, 2016 at 22:28
  • 1
    The question is specifically about enabling modules during deployments. Configuration format doesn't change in that scenario (and it hardly ever does, as that would more or less be an API change). You enable new modules on your local/test environment, configure them, export the config and deploy. There is no scenario where the config structure could possibly change between those steps.
    – Berdir
    Commented Feb 17, 2016 at 22:57
  • 1
    The configuration importer makes use of the module_installer service too. Deploying configuration makes installing in hook_update unnecessary.
    – gapple
    Commented Feb 18, 2016 at 18:57
  • 1
    However; (a) config should usually only be updated via exporting the config in its entirety, during which it will ensure that all necessary dependencies are specified (b) if you're editing the exported config files by hand you should know what you're doing, and include all dependencies.
    – gapple
    Commented Feb 22, 2016 at 21:46

I've yet to run into any issues just using configuration management, so I'd just stick with that for now.

The only thing that could be considered an issue is environment specific modules (i.e. Devel) can be tricky to manage. I tend to just deploy the configuration with them enabled and then disable them as part of my deployment scripts (either Flightplan.js or Acquia Cloud Hooks depending on environment).

  • If using drush, the --skip-modules option will prevent config-export from including the module as enabled in your config files, and prevent config-import from disabling the module on your development environment.
    – gapple
    Commented Feb 17, 2016 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.