These docs are accurate as of 10th April 2024 & the product is undergoing rapid changes. Please ask in the Tonk community chat when things don't work as expected.

Tonk is a simple toolchain for better vibe coding that helps you build and share applets that integrate with your data and embed into your daily life.

Each app can read and write to the shared state with barely any development overhead - no need to worry about migrations, caching, auth or permissions.

How it works

tonk hello sets up your local Tonk store - a super lightweight, local-first data store

tonk create app creates a new, LLM-friendly React app that gives strong guidance to Windsurf, Claude or Cursor (you pick)

Features

Because we replace a traditional server-database architecture with a local-first approach, Tonk apps are:

  • Quick to build
  • Easy and cheap to manage
  • Private by default
  • Work offline
  • Guaranteed to stay independent from platforms

Get started

The best place to get started is our quickstart guide.

Project status

The team behind Tonk is a venture-backed startup based in London.

The Tonk toolchain is in alpha. This is a brand new project built fully in the open, from scratch. Please ask questions in our community or visit our website for more information.

As an early stage project we are very open to feedback and keen to help builders - so please reach out to the team and we will endeavour to support your usecase.

Quickstart guide

If you haven't yet, start with the introduction before reading this quickstart guide.

Tonk apps plug into Tonk stores, which store data in a local-first way. This makes Tonk apps especially collaborative and interoperable. It also means that they are private, performant, have offline support and reduce dependency on third parties. Tonk apps sidestep traditional database headaches such as caching, migrations and auth.

I want to build a Tonk app

First, you'll need to install Tonk on your machine:

$ wget https://raw.githubusercontent.com/tonk-labs/tonk/refs/heads/main/scripts/install.sh && chmod +x ./install.sh && ./install.sh

If everything was successful you should see the message:

===============================
🎉 Congratulations! Tonk has been successfully installed! 🎉
You can get started by running: tonk hello
===============================

When you run tonk hello the Tonk Hub will open a welcome screen.

The Tonk Hub is an Electron app that helps you manage your Tonk apps and stores.

Choose your Tonk home

hub screenshot

Note: Choose a location where you like to store your projects. You should make sure that your preferred code editor has read/write access to this location.

Home Sidebar

hub screenshot

There are two sections in the sidebar

Apps

The apps section is where you develop and run your applications. For now, all Tonk applications are React web apps. We've placed lots of instructions around the Tonk app templates for LLMs which should make it much easier to vibe code.

Stores

Stores are what make Tonk apps special. They are containers of shareable data that easily plug into any of your apps. Stores are synchronized using the Automerge CRDT library. They are just automerge files which are read in by the Hub and served to your applications during runtime. Anyone who uses your application in the Hub will participate in "replicating" the store. It's like one big collaborative, evolving database.

Launch the hello world

Select the hello-world applications

hello world

Voila!

Just like that you are running your first app with Tonk.

To understand how apps work in Tonk and why they are special, follow the tutorial

Tonk Stack

image of tonk stock

The Tonk stack consists of several packages:


CLI

A command line utility tonk that is used to run the GUI, and to run your apps in both dev and serve (or production) mode.


Hub

The Tonk Hub, which is an Electron app used to assist in running your apps and viewing the state in your stores.


Server

Runs your apps and listens for changes to stores. Changes are propagated to every client (allowing collaboration) and saved as stores on your machine when you are running your applications with the Tonk CLI or Tonk Hub. The store format for now is simply an automerge binary format.


Keepsync docs

A Typescript library that wraps any Zustand store and allows it to sync to the server.

Keepsync

Creating a Store

Right now there's no way to create a store outside of an app. Stores are uniquely identified by a docId which is used to reconcile state between all clients connected over the server.

If you create a store in the app with a docId that does not exist, then it is created. If it already exists then it will synchronize with the other clients and the server. Simple as that!

You connect your app to the store using the sync middleware. See Create a Synced Store with the Middleware

Basic Usage

1. Set Up the Sync Provider

If you create a Tonk app through the Hub or throhugh the CLI, this should already be in the code.

Initialize the sync engine in your application entry point (or before using any synced stores):

// index.tsx
import { configureSyncEngine } from "@tonk/keepsync";

// Initialize the sync engine
configureSyncEngine({
  url: "ws://localhost:8080",
  name: "MySyncEngine",
  onSync: (docId) => console.log(`Document ${docId} synced`),
  onError: (error) => console.error("Sync error:", error),
});

2. Create a Synced Store with the Middleware

Use the sync middleware to create stores that automatically synchronize with other clients:

// stores/counterStore.ts
import { create } from "zustand";
import { sync } from "@tonk/keepsync";

interface CounterState {
  count: number;
  increment: () => void;
  decrement: () => void;
  reset: () => void;
}

export const useCounterStore = create<CounterState>(
  sync(
    // The store implementation
    (set) => ({
      count: 0,

      // Increment the counter
      increment: () => {
        set((state) => ({ count: state.count + 1 }));
      },

      // Decrement the counter
      decrement: () => {
        set((state) => ({ count: Math.max(0, state.count - 1) }));
      },

      // Reset the counter
      reset: () => {
        set({ count: 0 });
      },
    }),
    // Sync configuration
    {
      docId: "counter",
      // Optional: configure initialization timeout
      initTimeout: 30000,
      // Optional: handle initialization errors
      onInitError: (error) =>
        console.error("Sync initialization error:", error),
    }
  )
);

3. Use the Store in React Components

// components/Counter.tsx
import React from "react";
import { useCounterStore } from "../stores/counterStore";

export function Counter() {
  // Use the store hook directly - sync is handled by the middleware
  const { count, increment, decrement, reset } = useCounterStore();

  return (
    <div>
      <h2>Collaborative Counter: {count}</h2>
      <div>
        <button onClick={decrement}>-</button>
        <button onClick={increment}>+</button>
        <button onClick={reset}>Reset</button>
      </div>
      <p>
        <small>
          Open this app in multiple windows to see real-time collaboration in
          action.
        </small>
      </p>
    </div>
  );
}

Tutorials

My World Tutorial

Welcome to the My World tutorial! My world is a collaborative map application where you can save and share locations with friends.

Launch my-world in Dev Mode

Select the my-world application, you should see the terminal and readme.

my-world

Run the command:

tonk dev

This will launch the app in dev mode.

My World Introduction

Follow the pop-ups to learn about the features. You can refer back to this document for extra tips as you follow along.

my-world

More about Stores

A Store is like a JSON file that magically knows how to merge into other JSON files like it. Under the hood, it represents an Automerge document, which is a special file used by sync engines to store CRDT objects in a local-first way. Local-first just means it's always available locally first.

Currently, you cannot directly modify a Store from the Hub. Instead you can only modify the data via the app.

⚠️ Warning: there is a known issue where sync states get stuck whe the application loads. If you notice something isn't syncing, try again by refreshing the page.

Modify the app

You can modify the app by editing the files in the app directory. A simple way to edit the application is to launch your editor from the Tonk terminal for that application.

If you are using Cursor or Vscode, just click on the app and run the command in the terminal

code .

If you are using Claude Code, then run command

claude

if you are using Windsurf on Mac, then run the command

/Applications/Windsurf.app/Contents/MacOS/Electron .

and so on.

Vibe Coding

You can simply ask your co-pilot to make the necessary changes you'd like to see.

❗ pro-tip: Vibe Coding is best done in small incremental steps. Tell the LLM the simplest, most concise possible feature you'd like to add and work with it until you think everything is functional. Once it's working, make a commit into git. Then keep going on to the next feature.

As you make changes to the app's code - you should see the changes reflected in the app UI.

The Tonk toolchain is designed for people incorporating AI heavily into their workflow. As such, Tonk apps have prompts throughout the project structure as (llms.txt, CLAUDE.md, .cursorrules, .windsurfrules). These are files which provide context to copilots such as Claude, Cursor or Windsurf.

Try launching the app in a copilot and making changes to the interface or application logic - you should see the changes reflected in the app UI.

Note on copilots: We find Tonk works best with Claude Code as it's more aggressive when pulling in context. You may install and setup Claude Code here.

We've found that Cursor & Windsurf require more human intervention than Claude Code. Take special care to ensure the editor is correctly pulling in the corresponding llms.txt files when using these tools.

Magic Words

I want the data to synchronize with keepsync — tell the LLM to add a store that will synchronize

I don't want X data to synchronize, don't use keepsync — the LLM will just store data local to the device

Add a keepsync store that will use data with id "my-document-id" — this will help your app connect to an existing store. You should paste in some example data of what's already inside the store so the LLM knows the structure.

Create your own app

Once you're familiar with the flow of a Tonk app, you should create your own. Run the following in the Tonk Hub or your own terminal:

This will start a simple CLI flow where you'll be asked a few basic questions about your app. Your answers are used to give your copilot context for streamlined development.

Alternatively, use the "create" button in the Tonk Hub.

create-app

⚠️ Just because your copilot has context on llms.txt doesn't mean it will always use the context - it may need some guidance.

Publish your app

Coming soon

Share your app

Coming soon

Next steps

Try building your own application and share it in the Tonk community chat. If it's promising we'd love to support your project any way we can.

Reference

We encourage you to look into the llms.txt files in any of your app project files to get more context on how a Tonk app is laid out and how to properly use and configure keepsync.

FAQ

Pre-requisites to install

  1. You'll need to have wget and the right build tools (from VSCode or from Xcode) available to build the Tonk installation

How do I get it working on Windows?

  1. Do a wsl install (https://learn.microsoft.com/en-us/windows/wsl/install)

  2. Install node and npm

   curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
  1. Install necessary shared libraries
   sudo apt install libnss3
   sudo apt install libasound2t64

then copy and paste the install command listed on the tonk.xyz website.

How do I make changes to my application?

If you are using Cursor or Vscode, just click on the app and run the command in the terminal (you will need to make sure VSCode has installed the command line tool into your path).

code .

If you are using Claude Code, then run command

claude

if you are using Windsurf on Mac, then run the command

/Applications/Windsurf.app/Contents/MacOS/Electron .

When you click on an application, you can run the command inside the terminal tonk dev. Then you can open a browser at "localhost:3000".

As you make changes in the editor, you should see changes live in the browser. Tonk apps when running 'tonk dev' use hot reloading.

How do I run code that is private or that can hit external APIs outside the browser?

When you create a new Tonk app, you should see a server/ folder in the app. There are instructions in the llms.txt in that directory on how to use it. The server/ directory is an express app that runs on your local machine and all Tonk apps can hit on the /api endpoint. This allows Tonk apps to more easily hit external services, use private API_KEYs, or fetch data off your local machine.

This is a new feature, so if it doesn't exist, chat with us and we'll help you to get it setup.