The Best Internet Radio Stations To Stream

I listen to a lot of music while coding, reading and walking my dog. Over the years I’ve built up a solid go-to list of radio stations across the world to listen to when I want to put something on and not worry about choosing a specific album or playlist. These are the best Internet ratio stations I’ve found over the years to stream that keep me going throughout the day and night. These stations are actually more than just Internet radio actually, most of them are broadcast from a city over the FM dial. But since none of them are in my area I’ve come to rely on them strictly via the web.

They’re also commercial free radio so there’s no need to worry about interruptions from local car dealerships. They all rely on people like you and me to keep the music going, so drop them a dime or two if you find one that you like.

KEXP – Seattle

Indie/Variety
Stream URL
KEXP’s curatorial staff of 45 DJs, who are widely recognized as experts in their field, present the newest emerging popular artists alongside established bands. KEXP’s programming features both variety and specialty shows that brings you the emerging sounds and long-time favorites from the Pacific Northwest, the country, and throughout the world. – kexp.org

WWOZ- New Orleans

WWOZ 90.7 FM is the New Orleans Jazz and Heritage Station, a community radio station currently operating out of the French Quarter in New Orleans. Our governance board is appointed by the New Orleans Jazz & Heritage Festival and Foundation.
WWOZ’s mission is to be the worldwide voice, archive, and flag-bearer of New Orleans culture and musical heritage. – wwoz.org

WQXR – New York

Classical
Stream URL
WQXR is New York City’s only classical music radio station, broadcasting live on 105.9 FM. We share our audience’s passion for music by playing the most outstanding pieces on air, online and through our app. – wqxr.org

KCRW Eclectic 24- California

Indie/Variety
Stream URL
KCRW’s all-music channel blending the collected talents and tastes of all KCRW’s DJs into a single voice streaming 24 hours a day. – kcrw.org

After Hours FM – Internet

Techno/Trance
Stream URL

AH.FM is a online radio that plays Trance and Progressive mixes produced exclusively for AH.FM by the hottest DJs from around the world. Afterhours’ main purpose is to provide the Electronic Dance Music community the best and richest quality music, all for FREE. We don’t believe in charging listeners money to listen to music, we believe that if a listener likes what they hear and wishes to support Afterhours, they will simply donate or purchase something in the store to help. – ah.fm

React + Mapbox GeoJSON Example

Here’s an example of how to create a Mapbox map in React using a GeoJSON data set. When I started building my first React Mapbox map I built them around some of the other pre-built components out there like ReactMapboxGL or react-map-gl. Both of these wrappers are great but eventually figured out I was better able to control all the Mapbox features on my own by targeting the Mapbox GL JS libary directly vs using a another component.

This example uses React hooks but could easily be updated for a class component if that is what you are working with. Below is one component called Districts that loads Minnesota’s eight congressional districts from a separate geojson file. After loading the districts they are given a unique fill-color and added as a layer.

You can view the entire React Mapbox GeoJSON example project in the GitHub repository or you can view a live example at clintmcmahon.github.io/react-mapbox-example

Districts.js React Component

import React, { useState, useEffect, useRef } from "react";
import mnDistricts from "./data/mn/mn-districts.geojson";
import ReactDOM from 'react-dom';
import mapboxgl from 'mapbox-gl';

function Districts(props) {
    mapboxgl.accessToken = process.env.REACT_APP_MAPBOX_KEY;
    const mapContainer = useRef(null);
    const [long, setLong] = useState(-94.503809);
    const [lat, setLat] = useState(46.443226);
    const [zoom, setZoom] = useState(4.5);
    const [hoveredDistrict, _setHoveredDistrict] = useState(null);
    const hoveredDistrictRef = useRef(hoveredDistrict);

    const setHoveredDistrict = data => {
        hoveredDistrictRef.current = data;
        _setHoveredDistrict(data);
    };

    useEffect(() => {

        let map = new mapboxgl.Map({
            container: mapContainer.current,
            style: "mapbox://styles/mapbox/light-v10",
            center: [long, lat],
            zoom: zoom
        });


            // Add zoom and rotation controls to the map.
            map.addControl(new mapboxgl.NavigationControl());
        map.once("load", function () {

            map.addSource('district-source', {
                'type': 'geojson',
                'data': mnDistricts
            });

            map.addLayer({
                'id': 'district-layer',
                'type': 'fill',
                'source': 'district-source',
                'layout': {},
                'paint': {
                    'fill-color': [
                        'match',
                        ['get', 'CD116FP'],
                        '01',
                        '#5AA5D7',
                        '02',
                        '#02735E',
                        '03',
                        '#00E0EF',
                        '04',
                        '#84D0D9',
                        '05',
                        '#202359',
                        '06',
                        '#CE7529',
                        '07',
                        '#00AE6C',
                        '08',
                        '#0056A3',
                        /* other */ '#ffffff'
                    ],
                    'fill-opacity': [
                        'case',
                        ['boolean', ['feature-state', 'hover'], false],
                        .8,
                        0.5
                    ]
                }
            });

            map.on('mousemove', 'district-layer', function (e) {
                if (e.features.length > 0) {
                    if (hoveredDistrictRef.current && hoveredDistrictRef.current > -1) {

                        map.setFeatureState(
                            { source: 'district-source', id: hoveredDistrictRef.current },
                            { hover: false }
                        );
                    }

                    let _hoveredDistrict = e.features[0].id;

                    map.setFeatureState(
                        { source: 'district-source', id: _hoveredDistrict },
                        { hover: true }
                    );

                    setHoveredDistrict(_hoveredDistrict);
                }

            });

            // When the mouse leaves the state-fill layer, update the feature state of the
            // previously hovered feature.
            map.on('mouseleave', 'district-layer', function () {
                if (hoveredDistrictRef.current) {
                    map.setFeatureState(
                        { source: 'district-source', id: hoveredDistrictRef.current },
                        { hover: false }
                    );
                }
                setHoveredDistrict(null);
            });

        });

    }, []);

    return (
        <div className="district-map-wrapper">
            <div id="districtDetailMap" className="map">
                <div style={{ height: "100%" }} ref={mapContainer}>

                </div>
            </div>
        </div>
    );
}

export default Districts;

Minnesota Congressional Districts GeoJSON

This geojson data set represents Minnesota’s eight congressional districts that I pulled from the US Census. Each feature has a property “CD116FP” that I’m using to set the fill-color of each district layer. The GeoJSON data is so big I didn’t include it in this blog post but you can download it from the Github repo.

You can view the source on Github.

That’s it. Happy coding!