Here’s a song I wrote in Javascript using Tone.js. This was a weekend project for getting to know Tone. Because all sounds are generated using the Web Audio API, it’s best to listen on a modern and zippy browser.
Chromium browsers, such as Brave or Google Chrome, are a good choice.

// Songs.js 
// https://github.com/ckmahoney/music-theory/blob/master/src/Songs.js
function play8BitMusic(freq) {
  Tone.Transport.bpm.value = 132;
  Tone.Transport.start();
  let phrase = 0;
  const events = [];
  for (let i = 0; i < 64 * 4; i++) 
    events.push(i);

  const play = (synth, note, dur, t, vel) => 
    synth.triggerAttackRelease(note, dur, t, vel);

  const kickCompressor = new Tone.Compressor({threshold: -36, ratio: 15});
  const kick = new Tone.MetalSynth({
    frequency : 1,
    envelope : {
      attack : 0.001,
      decay : 0.2,
      release : 0.2
    },
    harmonicity : 1.04 ,
    modulationIndex : 3,
    resonance : 80,
    octaves : 4
  }).chain(kickCompressor, Tone.Master);

  const hh = new Tone.MetalSynth({
    frequency : 600 ,
    envelope : {
      attack : 0.005 ,
      decay : 0.02,
      sustain : 0
    },
    harmonicity : 5.1 ,
    modulationIndex : 32 ,
    resonance : 4000 ,
    octaves : 1.5
  });

  const snare = new Tone.NoiseSynth({
    noise : {
      type : 'white'
    },
    envelope : {
      attack : 0.005 ,
      decay : 0.2,
      sustain : 0
    }
  }).toMaster();

  const tomCompressor = new Tone.Compressor({threshold: -24, ratio: 2.4});
  const tom = new Tone.MembraneSynth({
    pitchDecay : 0.1,
    octaves : 10 ,
    oscillator : {
      type : 'sine'
    },
    envelope : {
      attack : 0.001 ,
      decay : 0.4 ,
      sustain : 0.01 ,
      release : 1.4 ,
      attackCurve : 'exponential'
    }
  }).chain(tomCompressor, Tone.Master);

  const padFilter = new Tone.AutoFilter({
    frequency : 0.06 ,
    type : 'sine' ,
    depth : 1,
    baseFrequency : 1200 ,
    octaves : 3.6 ,
    filter : {
      type : 'highpass' ,
      rolloff : -24 ,
      Q : 4
    }
  });

  const clapDist = new Tone.Chebyshev({order: 3, oversample: '4x'});
  clapDist.wet.value = .1;
  clapDist.wet.rampTo(.4, 80);
  const clap = new Tone.NoiseSynth({
    frequency : 200,
    envelope: {
      attack: 0,
      decay: 0.09,
      sustain: 0.9,
      release: 0.001
    },
    harmonicity : 2 ,
    modulationIndex : 32 ,
    resonance : 600 ,
    octaves : 2.5
  }).chain(clapDist, Tone.Master);
  clap.volume.value = -18;

  const padVerb = new Tone.Freeverb({roomSize: 0.95, dampening: 12000});

  padFilter.start();
  padFilter.wet.value = 0.3;
  padFilter.wet.rampTo(1, 13);

  pad = new Tone.PolySynth(6, Tone.Synth, {
    envelope: {
      attack: 5
    },
    oscillator : {
      type : "square"
    }
  }).chain(padFilter, padVerb, Tone.Master);

  pad.volume.value = -12;
  pad.set("detune", -1200);
  pad.triggerAttack(["F6", "A6", "D6"], '1m', .1);

  const leadDelay = new Tone.FeedbackDelay({delayTime: "4n", feedback: 0.65}); 
  const lead = new Tone.FMSynth({
    harmonicity : 5,
    modulationIndex : 1/8,
    detune : 30,
    oscillator : {
      type : 'sine'
    },
    envelope : {
      attack : 0,
      decay : '16n',
      sustain : 0.2,
      release : 0.5
    },
    modulation : {
      type : 'square'
    },
    modulationEnvelope : {
      attack : 0.1 ,
      decay : 0 ,
      sustain : 1 ,
      release : 0.5
    }
  }).chain(leadDelay, Tone.Master);

  const leadDegrees = [
    [0, 3, 2, null],
    [5, 3, -5],
    [0, 5, 2],
    [2, 3, 7]
  ];

  const leadNotes = leadDegrees.map((phrase) => 
    Notes.degreeToPitches(phrase, ['d', 'minor'], 5));

  const bar = (tick) => tick % 16;
  const beat = (tick) => tick % 4;

  new Tone.Sequence(function(time, tick) {
    if (phrase == 1) {
      hh.toMaster();
    }

    if (tick === 0) {
      console.log("Phrase: ", phrase)
      let seq = new Tone.Sequence(function (t, note) {
        console.log("playing note ", note);
        play(lead, note, '8n.', '+6n');
      }, leadNotes[phrase], '4m');

      seq.loop = false;
      seq.start();

      // make the lead sound cooler as the song progresses.
      lead.detune.value = phrase * 15;
    }

    if ((tick + 4) % 8 === 0) {
      play(clap, '8n');
    }

    if (tick === 64 * 4 - 1) {
      phrase++;
    }

    if (tick % 4 === 2) {
      play(hh, '16n');
    }

    if (beat(tick) === 0) {
      play(kick, '8n');
      phrase > 0 && play(tom, 'A1', '8n.');
    }

    if ([10, 14, 30, 31].includes(tick)) {
      let velMod = tick / 100;
      play(snare, '8n', time, .5 + velMod);
    }
  }, events, '16n').start('+0.2');
}

Have fun.