How to render HTML page with attachments only from the render array?
So this is a working solution. The response has getContent() method so it can be used in code and not only as route response.

function renderHtml($some_content) {
    $html = [
      '#type' =&gt; 'html',
      'page' =&gt; [
        '#type' =&gt; 'page',
        '#title' =&gt; 'Some page',
        'content' =&gt; $some_content,
        '#attached' =&gt; [
          // At least one of these have to have value,
          // otherwise the head placeholder won't get replaced.
          'html_head_link' =&gt; [],
          'html_head' =&gt; []
        ]
      ]
    ];

    $html['page']['#attached']['html_head'][] = [[
      '#type' =&gt; 'html_tag',
      '#tag' =&gt; 'meta',
      '#attributes' =&gt; array(
        'name' =&gt; 'Sometag',
        'content' =&gt; 'somevalue',
      ),
    ], 'someid'];

    $active_theme = \Drupal::theme()-&gt;getActiveTheme();
    $render_theme_extension = \Drupal::service('theme_handler')-&gt;getTheme('rendering_theme');
    $new_active_theme = \Drupal::service('theme.initialization')-&gt;getActiveTheme($render_theme_extension);
    \Drupal::theme()-&gt;setActiveTheme($new_active_theme);

    \Drupal::service('renderer')-&gt;renderRoot($html);
    $response = new HtmlResponse();
    $response-&gt;setContent($html);
    $response-&gt;setMaxAge(0);
    $response = \Drupal::service('html_response.attachments_processor')-&gt;processAttachments($response);

    \Drupal::theme()-&gt;setActiveTheme($active_theme);

    return $response;
}


Note: when you are using this via ajax callback, you have to unset the ajax_page_state from the post request, otherwise you'll be most likely be missing some libraries.