How can I alter node markup from a custom module (not theme)?
This did the trick:
custom.module:
&lt;?php

/**
 * @file
 * Custom module hook implementations.
 */

/**
 * Implements hook_theme().
 */
function custom_theme() {
  return [
    'node__custom_article' =&gt; [
      'template' =&gt; 'node--custom-article',
      'base hook' =&gt; 'node',
    ],
  ];
}

Credit where it's due:
https://www.drupal.org/forum/support/module-development-and-code-questions/2015-06-03/drupal-8-override-template-with#comment-12461953