Getting Started
spotify-effect is an Effect-native Spotify Web API client. This guide walks you through installation, credential setup, and running your first API call.
Prerequisites
- Node.js 18+ (or Bun 1.0+)
- A Spotify Developer application with a client ID and client secret
Installation
sh bun add @spotify-effect/core effect sh npm install @spotify-effect/core effect sh pnpm add @spotify-effect/core effect Configure credentials
spotify-effect uses SpotifyConfig — an Effect service — to supply credentials. The easiest way to provide it is via makeSpotifyLayer, which accepts a SpotifyLayerOptions object.
import { makeSpotifyLayer } from "@spotify-effect/core";
const SpotifyLayer = makeSpotifyLayer({ clientId: process.env.SPOTIFY_CLIENT_ID!, clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,});The layer handles token refresh automatically. You never manage access tokens manually.
Make your first API call
-
Import the service you need
Each Spotify resource group is a separate Effect service. To search for tracks, use
Search:import { Search } from "@spotify-effect/core"; -
Build an Effect program
import { Effect } from "effect";import { Search, makeSpotifyLayer } from "@spotify-effect/core";const program = Effect.gen(function* () {const search = yield* Search;const results = yield* search.search("Tame Impala", ["track"], {limit: 5,});return results.tracks?.items ?? [];}); -
Provide the layer and run
import { NodeRuntime } from "@effect/platform-node";const SpotifyLayer = makeSpotifyLayer({clientId: process.env.SPOTIFY_CLIENT_ID!,clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,});program.pipe(Effect.provide(SpotifyLayer), NodeRuntime.runMain);
Full example
import { Effect } from "effect";import { NodeRuntime } from "@effect/platform-node";import { Search, makeSpotifyLayer } from "@spotify-effect/core";
const SpotifyLayer = makeSpotifyLayer({ clientId: process.env.SPOTIFY_CLIENT_ID!, clientSecret: process.env.SPOTIFY_CLIENT_SECRET!,});
const program = Effect.gen(function* () { const search = yield* Search; const results = yield* search.search("Tame Impala", ["track"], { limit: 5, }); const tracks = results.tracks?.items ?? []; for (const track of tracks) { console.log(`${track.name} — ${track.artists[0]?.name}`); }});
program.pipe(Effect.provide(SpotifyLayer), NodeRuntime.runMain);Configure retries
makeSpotifyLayer accepts a retry option so you can tune retry behavior per client instance.
import { makeSpotifyLayer } from "@spotify-effect/core";
const SpotifyLayer = makeSpotifyLayer({ clientId: process.env.SPOTIFY_CLIENT_ID!, clientSecret: process.env.SPOTIFY_CLIENT_SECRET!, retry: { maxRetries: 5, baseDelayMs: 250, maxDelayMs: 5_000, },});Available retry options:
| Option | Type | Description |
|---|---|---|
maxRetries | number | Maximum number of retry attempts for retryable failures |
baseDelayMs | number | Initial backoff delay before exponential growth |
maxDelayMs | number | Upper bound for the backoff delay |
To disable retries entirely, set maxRetries to 0:
const SpotifyLayer = makeSpotifyLayer({ clientId: process.env.SPOTIFY_CLIENT_ID!, clientSecret: process.env.SPOTIFY_CLIENT_SECRET!, retry: { maxRetries: 0 },});Next steps
- Authentication — understand token strategies (client credentials vs. authorization code)
- Browser (PKCE) — use
@spotify-effect/browserfor SPA OAuth flows - Error Handling — handle
SpotifyHttpError,SpotifyRateLimitError, and more - Pagination — paginate through large result sets with
paginateAlland streams