Product updates

What’s new in v0.17

This new release brings better TypeScript integration, React Native support, improved LiveList conflict resolution, and new API endpoints to fetch rooms and users within rooms.

What’s new in v0.17

We’re excited to announce several new features coming to version 0.17:

Better TypeScript integration

Some of our APIs accept generic types that let you redefine your storage schema even if it has been initialized differently. This flexibility gives a false sense of confidence and can lead to confusion.

Our long-term goal is to give you the tools to define your Storage schema to safely build your app around it and make sure that you can synchronize your documents to your own database without invalid data.

A great way to start doing this is to rely on TypeScript to define the schema at the Room level. In this release, we now let you define your types once in a liveblocks.config.ts file—enabling you to have a clear and scalable data schema at the client level. Here is what it looks like for React.

import { createClient } from "@liveblocks/client";import { createRoomContext } from "@liveblocks/react";
const client = createClient({ /* client options */});
// Presence represents the properties that will exist on every User in the Room// and that will automatically be kept in sync. Accessible through the// `user.presence` property. Must be JSON-serializable.type Presence = { cursor: { x: number; y: number } | null; // ...};
// Optionally, Storage represents the shared document that persists in the// Room, even after all Users leave. Fields under Storage typically are// LiveList, LiveMap, LiveObject instances, for which updates are// automatically persisted and synced to all connected clients.type Storage = { author: LiveObject<{ firstName: string; lastName: string }>; // ...};
export const { RoomProvider, useMyPresence, useObject, /* ...all the other hooks you’re using... */} = createRoomContext<Presence, Storage>(client);

The hooks can then be imported from the config file inside your application.

import { useMyPresence, useObject, useOthers } from "./liveblocks.config";
// All the hooks are typed without additional genericsconst author = useObject("author");const [{ cursor }] = useMyPresence();const others = useOthers();

With this, you’ll have an even better code completion experience in tools like VSCode—giving you the confidence that what you’re typing maps to the schema defined in liveblocks.config.ts.

A video showing someone typing in VSCode.

Client-side typing is only the first step; this foundational work will pave the way for runtime checking and server-side validation.

As of 0.17, we’ve deprecated the use of some previously recommended APIs, to be able to offer better type inference and auto-completion going forward. We’ve kept these breaking changes as small as possible, and we’ve written a step-by-step guide to help you migrate. If you’re stuck, please reach out to us on GitHub, and we’ll lend you a hand!

React Native support

With the release of 0.17, we’re also bringing React Native support! Under the hood, Liveblocks relies on WebSocket, fetch, atob, and Promise. This makes it technically possible to use our APIs with all kinds of technologies—including React Native.

React Native To-do List

Please take a look at our API reference to learn how to use Liveblocks packages with React Native. You can also check out this open-source React Native multiplayer to-do list example if you’d prefer to learn that way.

We’re excited to see what kind of native app you’ll build with Liveblocks!

Improved LiveList conflict resolution

In previous versions, there were some issues related to the way we handled data conflicts when multiple people updated the same lists. This rarely occurred, but at Liveblocks we’re committed to building the most reliable APIs possible.

The Liveblocks server now appropriately resolves conflicts when multiple people add items to a LiveList simultaneously.

An animation showing two users adding elements to a list simultaneously.

To make sure this continues to work smoothly, we’ve improved our test coverage: in addition to our fuzz tests, we now have end-to-end tests to consistently reproduce these scenarios, including the one highlighted below. If you’re curious, feel free to check them out directly on GitHub.

test(  "remote insert conflicts with another insert",  prepareTestsConflicts(    {      list: new LiveList(),    },    async ({ root1, root2, wsUtils, assert }) => {      root1.get("list").push("A");      root2.get("list").push("B");
await wsUtils.flushSocket1Messages();
assert({ list: ["A"] }, { list: ["A", "B"] });
await wsUtils.flushSocket2Messages();
assert({ list: ["A", "B"] }); } ));

Building a stable multiplayer infrastructure implies having great test coverage—we’re excited about these improvements and will continue to invest in this area.

New API endpoints

More additions in 0.17 are the new API endpoints, unlocking all kinds of new experiences for developers. The first one allows you to get connected users in a room, and the second one allows you to get the rooms that have been created.

Lobby enabling automatic room assignment

Amongst other things, these endpoints enable developers to create what we’re calling lobby-based multiplayer experiences. In these lobbies, visitors can automatically be assigned to different rooms based on how full they are.

This is especially useful for multiplayer landing pages and websites that get a lot of visitors at once: instead of filling up one room quickly and not enabling others to participate in the interactive multiplayer experience, they now can get automatically assigned to rooms as soon as they land on the page.

This is something we’re experimenting with at the moment and is yet to be properly documented. Here is a proof-of-concept built with Next.js, Redis, and Liveblocks to show you how to set it up for your own landing page. If this is something you’d be interested in or would like to contribute to, please reach out.

Contributors

A big thank you to all our contributors! We wouldn’t have made it here without your support and feedback. This month, we want to send a special shout-out to @Vinod_Santharam for the React Native integration, and @ofoucherot for the conflict resolution stability.

And that’s all, folks! Remember to check out the changelog for the full release notes, and see you soon for 0.18!