Who should you see at Treefort 2027?
spotifort.com · Setup Guide · Full Lineup · Why Client ID?
Spotifort helps you find your acts at Treefort Music Fest 2027 (March 31 – April 4, Boise, Idaho). Type a few artists you like, no account needed, and it lists who you already like that is playing and recommends other acts on the lineup that sound like them, with a reason for each and a link to listen on Spotify, Apple Music, Tidal or Bandcamp. If you want, connect your Spotify library to add all your artists at once.
All processing happens client-side in your browser. Spotifort has no backend, no database, no cookies, and no advertising or cross-site tracking. Anonymous, cookieless page-visit counts are collected with Cloudflare Web Analytics. Your Spotify data never leaves your device, and the Spotify access token is held in memory only.
What is remembered, on your device only (localStorage): the artists you added, which listening service you chose, and your Spotify Client ID if you leave "Remember my Client ID on this device" ticked. "Forget my data" clears all of it.
- Type an artist you like (or tap one of the examples)
- Add a few more; results update as you go
- Pick where you listen; every row has a listen link and
[+]for similar acts on the lineup - Share your picks with a link, if you like
Recommendations come from Last.fm similar-artist data collected ahead of time for every lineup artist, so the site needs no server.
- Create a free Spotify Developer app (setup guide)
- Paste your Client ID into Spotifort ("or connect your Spotify library")
- Authorize with Spotify (read-only access to your Liked Songs, top artists and followed artists)
Spotify's February 2026 API changes restrict Development Mode apps to 5 authorized users. Rather than limiting Spotifort to 5 people, each user creates their own Spotify Developer app — making you user #1 on your own app. This is the only way an independent, open-source project can work within Spotify's current restrictions.
For the full story on what changed and what Spotifort could be without these restrictions, see Why Does Spotifort Need a Client ID?
Requirements (Spotify only):
- Spotify Premium account (required by Spotify for Developer Mode)
- A desktop/laptop computer to create the Developer app (Spotify's dashboard doesn't work on mobile)
- Once set up, Spotifort works on any device
The Treefort lineup is built ahead of time into static JSON from the official Treefort website, Spotify, MusicBrainz and Last.fm (see Updating Lineup Data below). It may not reflect last-minute changes.
You can view the full lineup data, with listen links, tags and which matches are unverified, at spotifort.com/lineup.
- Vanilla JavaScript
- Vite build tool
- Spotify Web API with PKCE authentication
- Hosted on Cloudflare Pages
# Clone the repo
git clone https://github.com/commitconfirm/spotifort.git
cd spotifort
# Install dependencies
npm install
# Optional, for testing the Spotify import locally: a Client ID whose app has the
# redirect URI http://127.0.0.1:9090/callback (dev builds only; never used in production)
echo "VITE_SPOTIFY_CLIENT_ID=your_client_id_here" >> .env.local
# Start dev server (runs on port 9090)
npm run dev
# Try the recommendation engine from the command line
npm run try -- "Phoebe Bridgers" "Turnstile"
# Build for production
npm run build
# Run the tests
npm test
# After a build, check dist/ against the CSP and build rules
npm run check:distEvery change lands through a pull request. CI runs the tests, build, npm audit (high and critical fail) and check:dist on each PR; main deploys to spotifort.com.
The festival year and dates live in one place, festival.config.js. The lineup is built in stages; each is incremental and safe to rerun.
# Everything, in order: lineup source, Spotify, MusicBrainz, Last.fm, build.
# A rerun with nothing new makes four requests to the festival app vendor's API and changes no file.
npm run lineup
# Or one stage at a time
npm run lineup:source # the lineup: the vendor's documented API (festival id in festival.config.js); falls back to the Treefort page + performer feed
npm run lineup:festival # fallback only: the festival's own performer feed for links (--refresh re-fetches everyone)
npm run lineup:spotify # Spotify ids: festival link first, search as the fallback (SPOTIFY_CLIENT_ID + SPOTIFY_CLIENT_SECRET in .env.local, see .env.local.example)
npm run lineup:musicbrainz # links to other platforms (1 request per second; a first run takes about 7 minutes)
npm run lineup:lastfm # similar artists and tags (LASTFM_API_KEY in .env.local)
npm run lineup:build # outputs and the review and sanity reports; no networkWhat it writes:
| File | What | Edited by |
|---|---|---|
data/<year>/state.json |
everything resolved so far | the pipeline |
data/<year>/overrides.json |
hand corrections the pipeline always respects | you |
data/<year>/review.md |
matches to check, new and removed artists | the build |
public/data/<year>/lineup.json, similarity.json |
static data the site loads | the build |
To fix a wrong match, add the artist to overrides.json (see docs/ARCHITECTURE.md) and run npm run lineup:build. Raw API answers are cached in ~/.cache/spotifort/, outside the repository; set SPOTIFORT_CACHE_DIR to put them elsewhere.
A scheduled GitHub Actions workflow (.github/workflows/lineup.yml) reruns npm run lineup twice a day, at 14:17 and 02:43 UTC (about 7:17 am and 7:43 pm Mountain Standard Time, one hour later in daylight time). If the data changed it runs the tests and the build, pushes the branch lineup-update (rebuilt from main each run) and opens or updates one pull request whose description carries the review report. GitHub holds the checks on a pull request opened by a workflow: on the pull request click "Approve and run", then merge when check and Cloudflare Pages are green. If nothing changed, nothing is pushed.
It needs three repository secrets (Settings, Secrets and variables, Actions): SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET and LASTFM_API_KEY. While any is missing the job ends green with a notice and does nothing. To run it by hand: Actions tab, "Lineup update", "Run workflow" (on main).
To correct a match, add the artist to data/<year>/overrides.json on main and merge that; the next run applies it and the pull request updates itself. A failed stage turns the run red and the run summary names the stage and shows the end of its output.
Similar artists, tags and listener counts come from Last.fm; links to other platforms come from MusicBrainz.
This project is not affiliated with, endorsed by, or associated with Treefort Music Fest or Spotify. This is an independent, open-source community tool built by an enthusiast.
Use at your own risk. No guarantees of accuracy or availability. Lineup data may not reflect the most current information.
Contributions are welcome. If you find an artist missing from the lineup or matched incorrectly, open an issue. If you want to add a feature, check the issues or open a discussion first.
Found a security problem? Please report it privately; see SECURITY.md. Do not open a public issue for it.
This project was built with Claude Code by Anthropic.
- commitconfirm — creator and maintainer
- Claude Code — AI pair programmer
MIT — see LICENSE for details.
