JSFiddle - React, Tailwind, and code Playground

HTML

<div class="section">
  <h3>Convert img[src] to ICO</h3>
  <div>
    Example (PNG): <img src="https://gist.githubusercontent.com/twolfson/7656254/raw/c5d0dcedc0e212f177695f08d685af5aad9ff865/sprite1.png" id="input" />
  </div>

  <div>
    <button onclick="test()">Conver to ICO</button>
  </div>

  <div id="result1" style="display:none">
    Save ICO: <a id="a" href="#" download="example.ico">click me</a>
  </div>
</div>

<div class="section">
  <h3>Convert input[type=file] to ICO</h3>
  <input type="file" id="file" />
  <div id="result2" style="display:none">
    Save ICO: <a id="a2" href="#" download="example.ico">click me</a>
  </div>
</div>

CSS

.section {
  padding: 4px;
  border: 1px solid gray;
  margin: 4px;
}

h3 {
  margin: 0 0 4px 0;
}

JavaScript

var MyBlobBuilder = function() {
  this.parts = [];
}

MyBlobBuilder.prototype.append = function(part) {
  this.parts.push(part);
  this.blob = undefined; // Invalidate the blob
};

MyBlobBuilder.prototype.write = function(part) {
  this.append(part);
}

MyBlobBuilder.prototype.getBlob = function(atype) {
  if (!this.blob) {
    this.blob = new Blob(this.parts, {
      type: !atype ? "text/plain" : atype
    });
  }
  return this.blob;
};

const img = document.getElementById('input'),
  a = document.getElementById('a'),
  a2 = document.getElementById('a2'),
  file1 = document.getElementById('file');
let imgSize = 0,
  imgBlob;

img.onload = e => {
  fetch(img.src).then(resp => resp.blob())
    .then(blob => {
      imgBlob = blob;
      imgSize = blob.size;
    });
};

function convertToIco(imgSize, imgBlob) {
  let file = new MyBlobBuilder(),
    buff;

  // Write out the .ico header [00, 00]
  // Reserved space
  buff = new Uint8Array([0, 0]).buffer;
  file.write(buff, 'binary');

  // Indiciate ico file [01, 00]
  buff = new Uint8Array([1, 0]).buffer;
  file.write(buff, 'binary');

  // Indiciate 1 image [01, 00]
  buff = new Uint8Array([1, 0]).buffer;
  file.write(buff, 'binary');

  // Image is 50 px wide [32]
  buff = new Uint8Array([img.width < 256 ? img.width : 0]).buffer;
  file.write(buff, 'binary');

  // Image is 50 px tall [32]
  buff = new Uint8Array([img.height < 256 ? img.height : 0]).buffer;
  file.write(buff, 'binary');

  // Specify no color palette [00]
  // TODO: Not sure if this is appropriate
  buff = new Uint8Array([0]).buffer;
  file.write(buff, 'binary');

  // Reserved space [00]
  // TODO: Not sure if this is appropriate
  buff = new Uint8Array([0]).buffer;
  file.write(buff, 'binary');

  // Specify no color planes [01, 00]
  // TODO: Not sure if this is appropriate
  buff = new Uint8Array([1, 0]).buffer;
  file.write(buff, 'binary');

  // Specify unknown bits per pixel (bit depth) [20, 00]
  // TODO: Quite confident in this one
 ...