Using Effect
Use the Effect-native service, typed error channels, streams, and dependency layers when your application already uses Effect.
The Promise client is the recommended starting point. If your application
already uses Effect, YouTubeApi exposes the same operations as typed Effects,
and layer() provides configuration, session, and transport dependencies.
Provide the service
import { Effect } from 'effect';
import { YouTubeApi, layer } from 'just-yt';
const program = Effect.gen(function* () {
const yt = yield* YouTubeApi;
return yield* yt.video('dQw4w9WgXcQ');
});
const video = await Effect.runPromise(
program.pipe(Effect.provide(layer({ location: 'US' }))),
);The layer creates one shared session for the provided program. Configuration is
the same YouTubeOptions used by the Promise constructor.
Handle a typed failure
const program = Effect.gen(function* () {
const yt = yield* YouTubeApi;
return yield* yt.video('dQw4w9WgXcQ').pipe(
Effect.catchTag('UnavailableError', (error) =>
Effect.succeed({ unavailable: error.reason ?? error.status }),
),
);
});Effect keeps expected failures in the error channel, so catchTag can target
one case without flattening every error into unknown.
Stream search results
The Effect service also offers searchStream(). It follows continuations
lazily and stops when interrupted or when YouTube runs out of results.
import { Effect, Stream } from 'effect';
import { YouTubeApi, layer } from 'just-yt';
const program = Effect.gen(function* () {
const yt = yield* YouTubeApi;
return yield* yt.searchStream('typescript', { type: 'video' }).pipe(
Stream.take(100),
Stream.runCollect,
);
});
const results = await Effect.runPromise(
program.pipe(Effect.provide(layer())),
);For advanced adapters, the layer also exposes Innertube and Session. Their
raw response shapes are undocumented and may change, so keep them behind your
own stable boundary.