Custom variable in custom block template
After long hours of searching and trying I finally found a solution.
Not really sure why but it seems a naming convention has to be respected.

I changed the name of #theme and templates to start with module name, here the name is custom_blocks.

src/Plugin/Block/FrontAppsBlock.php

/**
 * @Block(
 *   id = "front_apps_block",
 *   admin_label = @Translation("Front Apps Block"),
 * )
 */
class FrontAppsBlock extends BlockBase implements BlockPluginInterface {

  public function build() {
    return [
      '#theme' =&gt; 'custom_blocks__front_apps',
      '#app' =&gt; 'test value',
    ];
  }

}


custom_blocks.module

function custom_blocks_theme($existing, $type, $theme, $path) {
  return [
    'custom_blocks__front_apps' =&gt; [
      'variables' =&gt; [
        'app' =&gt; null
      ],
    ]
  ];
}


templates/custom-blocks--front-apps.html.twig

&lt;p&gt;Hello: {{ app }}&lt;/p&gt;
&lt;p&gt;Base Label: {{ label }}&lt;/p&gt;