Triplit Release Notes 4/5/2024

Svelte 5 support

Triplit now has framework support for Svelte 5 and SvelteKit. You can use the TriplitClient with Svelte 5 by adding the @triplit/svelte package. Currently, the useQuery and useConnectionStatus hooks are supported. You can use them in your Svelte components like this:

<script lang="ts">
  import { useQuery, useConnectionStatus } from '@triplit/svelte'
  import { TriplitClient } from '@triplit/client'
  import { schema } from '../triplit/schema';

  const client = new TriplitClient({ schema });

  let connection = useConnectionStatus(client);
  let data = useQuery(client, client.query('todos'));
  let todosArray = $derived(data.results ? Array.from(data.results): [])
  {#if data.fetching}
  {:else if data.error}
    <p>Error: {data.error.message}</p>
      {#each todosArray as [_id, todo]}
  {#if connection.status === 'OPEN'}
    <p>The client is connected</p>
    <p>The client is not connected</p>

We've also updated the create-triplit-app CLI to support Svelte 5. You can create a new Svelte project with Triplit and Vite by running:

npm create triplit-app@latest my-svelte-app

Select the svelte option. Vite will scaffold the project but likely install an old version of Svelte. You can update Svelte to version 5 by running:

npm install svelte@next

Read the documentation on Svelte 5 and SvelteKit support for more information.

Experimental Web Worker support for the Triplit client

Triplit now supports running the client in a Web Worker. While running a Web Worker, data will sync between browser tabs without having to sync with server. This will reduce network traffic for Triplit apps running in the multiple tabs, move Triplit local database computation to a separate thread, and allow for robust multi-tab offline support. This is an experimental feature and is not yet recommended for production use.

To use the Web Worker, import WorkerClient from @triplit/client/worker-client and create a new instance of the client:

import { WorkerClient } from '@triplit/client/worker-client';
import { schema } from './schema';

const client = new WorkerClient({
  serverUrl: import.meta.env.VITE_TRIPLIT_SERVER_URL,
  token: import.meta.env.VITE_TRIPLIT_TOKEN,

And that's it! The client will now run in a Web Worker.

Relational order clauses

Queries now support relational order clauses, using a dot syntax. For a schema with a relation between users and messages:

const schema = {
  users: S.Schema({
    id: S.Id(),
    name: S.String(),
    email: S.String(),
  messages: S.Schema({
    id: S.Id(),
    text: S.String(),
    created_at: S.Date({ default: }),
    sender_id: S.String(),
    sender: S.RelationById('users', '$sender_id'),

You can now order messages by the name of the sender:

// Order messages by the name of the sender in ascending order
client.query('messages').order('', 'ASC');

// Order messages by the name of the sender and then by the created date in descending order
  ['', 'ASC'],
  ['created_at', 'DESC'],

Read more about relations here.

Relational write rules

write rules now support relational filters. For a schema with a relation between users and posts, you can now write a rule that only allows admin users to create posts:

const schema = {
  users: {
    schema: S.Schema({
      id: S.Id(),
      name: S.String(),
      admin: S.Boolean(),
  posts: {
    schema: S.Schema({
      id: S.Id(),
      text: S.String(),
      author_id: S.String(),
      author: S.RelationById('users', '$author_id'),
    rules: {
      write: {
        'admin-write': {
          description: 'Only admin users can create posts',
          filter: [
            ['author.admin', '=', true],
            ['author_id', '=', '$user_id'],

read rules support relational filters as well. Read more about rules here.

Various logging and CLI fixes

Most notably, triplit seed run is no longer constrained by message size limits, we're logging more things.