What changed#
Using realtime-js library in Node.js < 22 will require to set transport for Realtime
What do I need to do#
For most users (Browser, Node.js 22+): No changes required For Node.js < 22 users: You’ll need to make a small change to explicitly set the WebSocket transport (see line 9 below).
_10npm i ws
_18import "dotenv/config";_18import { createClient, SupabaseClient } from "@supabase/supabase-js";_18import express, { Application } from "express";_18import ws from "ws";_18_18const supabaseUrl = process.env.SUPABASE_URL!;_18const supabaseAnonKey = process.env.SUPABASE_ANON_KEY!;_18const supabase: SupabaseClient = createClient(supabaseUrl, supabaseAnonKey, {_18 // Explicitly set the WebSocket transport here_18 realtime: { transport: ws as any },_18});_18_18const startRealtime = () =>_18 supabase.channel("realtime:server").subscribe(console.log);_18_18const app: Application = express();_18startRealtime();_18app.listen(3000);
[!WARNING]
We are working on a fix for the type definition as currently it's not being accepted as a WebSocketLike interface.
Why did we change it#
We have been facing multiple issues where the dynamic import of ws was breaking several runtimes and environments. The first environment where this become a serious issue was with Expo which required us to tackle the issue.
Previous attempts#
Multiple NPM entrypoints#
PR: https://github.com/supabase/realtime-js/pull/476
First approach chosen in conjunction with the Expo team but ended up creating several issues in other runtimes (namely Deno and Browser) so we reverted to use another method
Polymorphic client#
PR: https://github.com/supabase/realtime-js/pull/485
Second approach chosen as it's usually the "default" as we accepted the overhead of having a polymorphic WS connector but this created issues with Vercel ( https://github.com/supabase/supabase-js/issues/1437 )
Current approach#
After our several attempts in handling how Javascript runtimes handle dynamic imports we had to change the way we support Node.js < 22 as it was the original source of the issue due to the lack of native WebSocket support
The changes are implemented in realtime-js@2.15.1 with the changes from https://github.com/supabase/realtime-js/pull/514 The changes are implemented in supabase-js@2.55.0 with the changes from https://github.com/supabase/supabase-js/pull/1529
We opted to use this approach as it fully prevents the usage of dynamic imports; it avoids external library issues; has a path for upgradability and avoids multiple entrypoints which proven to be error prone.