JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"></script>
<body class="bg-gray-200" x-data="downloads" x-init="init()">
  <div class="p-8 bg-gray-200" x-ref="details">
    <div class="bg-white rounded-lg shadow-lg">
      <div class="p-6 flex items-center gap-4">
        <svg xmlns="http://www.w3.org/2000/svg" class="w-12" viewBox="0 0 512 512" xml:space="preserve">
          <path fill="#cff09e" d="M319.666 253.182V95.093H192.334v158.089h-60.592L256 416.907l124.258-163.725z" />
          <g fill="#507c5c">
            <path d="M256 431.967a15.063 15.063 0 0 1-11.996-5.954L119.748 262.287a15.06 15.06 0 0 1 11.996-24.164h45.533V95.092c0-8.315 6.742-15.059 15.059-15.059h127.331c8.317 0 15.059 6.743 15.059 15.059v143.03h45.533a15.06 15.06 0 0 1 11.996 24.164L267.997 426.011A15.062 15.062 0 0 1 256 431.967zm-93.925-163.726L256 391.999l93.925-123.758h-30.259c-8.317 0-15.059-6.743-15.059-15.059V110.151h-97.214v143.03c0 8.315-6.742 15.059-15.059 15.059h-30.259v.001z" />
            <path d="M256 512C114.842 512 0 397.158 0 256S114.842 0 256 0c8.317 0 15.059 6.743 15.059 15.059S264.317 30.118 256 30.118C131.448 30.118 30.118 131.448 30.118 256S131.448 481.882 256 481.882 481.882 380.552 481.882 256c0-68.911-30.874-133.183-84.706-176.34-6.489-5.203-7.532-14.681-2.33-21.17 5.203-6.49 14.679-7.529 21.168-2.331C477.015 105.064 512 177.903 512 256c0 141.158-114.842 256-256 256z" />
          </g>
        </svg>
        <h2 class="text-3xl uppercase text-green-800 tracking-wide">Downloads</h2>
      </div>
      <div class="px-4 pb-6">
        <template x-for="pacakge in packages">
          <div class="flex items-center rounded-lg p-2 cursor-pointer hover:bg-gray-100">
            <div class="w-10 h-10 rounded-full bg-green-100 p-2">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.001 512.001" xml:space="preserve">
                <path d="M86.883...

JavaScript

var downloads = {
  vendor: 'tzsk',
  packages: [],
  total: 0,
  exportUrl: '',
  async init() {
    const {
      packageNames
    } = await getAllPackages(this.vendor);
    const packages = packageNames.map(name => ({
      name,
      count: 0,
      total: 0,
    }));
    this.packages = packages;

    this.fetchAll();
  },
  async fetchAll() {
    const calls = this.packages.map(async ({
      name
    }) => {
      const {
        package
      } = await getDetailByPackageName(name);
      return {
        name,
        count: this.formatNumber(package.downloads.total),
        total: package.downloads.total
      };
    });

    const results = await Promise.all(calls);

    this.packages = results;
    const total = this.packages.reduce((prev, curr) => prev + curr.total, 0);
    this.total = this.formatNumber(total);
    setTimeout(() => {
      this.readyToExport();
    }, 400);
  },
  async readyToExport() {
    const blob = await domtoimage.toBlob(this.$refs.details);

    this.exportUrl = URL.createObjectURL(blob);
  },
  formatNumber(number) {
    return new Intl.NumberFormat('en-US').format(number);
  },
  exportImage() {
    const link = document.createElement('a');
    link.href = this.exportUrl;
    link.setAttribute('download', `${this.vendor}.png`);
    link.click();
  }
};

function getAllPackages(vendor) {
  return fetch(`https://packagist.org/packages/list.json?vendor=${vendor}`)
    .then(res => res.json());
}

function getDetailByPackageName(name) {
  return fetch(`https://packagist.org/packages/${name}.json`)
    .then(res => res.json());
}