Elevate your creative intelligence

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.

It's for creative people of all stripes - you just need basic coding ability.

AI makes it easier for people to understand the world, but not necessarily their world. Coding copilots make it easier for people to build static websites, but it's still tricky for local experts to embed AI into their idiosyncratic daily lives.

In spite of that, future-facing people with basic coding ability are scraping data, organising files and running it all through LLMs to get smarter, faster and more creative.

Setting up that infrastructure is painful. What if it were simple?

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

Keepsync Library
Offline + private
functionality
Tonk
CLI
Tonk Daemon
React + Typescript + Tailwind
State
management
Distributed
auth*
Share Links
Deployment*

*under construction

Example usecases

Learning Tonk requires a mindset shift because as developers we're used to thinking in terms of singular applications that are tightly coupled to databases.

Tonk doesn't just help you build apps or store data. Tonk can be best described as helping you build your own little internet: a way to store shared highly mutable state across many apps and many users, and build ephemeral services, apps and tools on top of that shared state.

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.

Here are some examples of what Tonk can help with:

🗺️ Maps

An evolving dataset for your friends to add locations, routes, reviews, planned trips - and surface whatever you like in custom maps apps.

Hackathon idea: A social mapping app where friends can collaboratively pin spots, share routes, and plan trips—with the option to remix the shared dataset into custom experiences like foodie maps, hiking guides, or road trip planners.

🎯 Productivity

A fluctuating set of todos for your colleagues to track progress on ephemeral projects without forcing everyone to use the same productivity app.

Hackathon idea: A multiplayer to-do list for temporary teams - where shared project tasks live in a public space and AI nudges contributors to focus on what matters before the project dissolves.

💰 Banking

Aggregated financial information for your household to track your finances and make intelligent investments.

Hackathon idea: A household finance dashboard that syncs every member's bank accounts, applies AI to optimize spending, and auto-generates investment proposals based on shared goals.

❤️ Health

A dataset for your family to make health data available to bespoke meditation, exercise or sleep apps.

Hackathon idea: A health data layer for families — syncing sleep, steps, and stress scores across devices and enabling personalized wellness bots that work across meditation, exercise, and diet apps.

💬 Social

An ad-free, private chatboard for your friends, but where everyone customises their experience with pluggable components such as games, calendars and notifications.

Hackathon idea: A modular group chat app where every conversation is a programmable space - friends can add shared games, calendars, polls, or moodboards, and the feed adapts to how your group vibes, not how the algorithm dictates.

🤖 Assistants

An AI that can assist you with full context from your chat apps, calendars, todo boards and social feeds.

Hackathon idea: A privacy-first AI assistant that reads your calendar, chat threads, and todos from your shared spaces — then recommends actions, summarizes life, and shares updates with your friends.

How it works

Building with Tonk feels like magic because it's default vibecode-friendly, local-first and multiplayer.

Apps generated with the Tonk CLI come pre-bundled with React, Typescript, Tailwind and aggressively prompt your agent to ensure smooth vibe-coding.

The Tonk CLI provides a simple but powerful command-line interface for interfacing with your Tonk and scaffolding Tonk templates.

The Tonk runs in the background on your computer. It hosts your bundles and stores. It's the glue between all your applications.

The keepsync library manages state with an optimized sync engine based on Automerge CRDTs, enabling real-time collaboration without a central server.

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 applications especially collaborative and interoperable. It also means that they are private, performant, have offline support and reduce dependency on third parties. Apps on Tonk sidestep traditional database headaches such as caching, migrations and auth.

Installing Tonk

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

npm install -g @tonk/cli && tonk hello

This will install the Tonk CLI globally and run the hello command, which sets up the Tonk daemon for synchronizing your data.

Creating a new Tonk app

To create a new Tonk app, use the create command:

tonk create

The CLI will guide you through a series of prompts to configure your project:

  1. Choose a template (React or Node.js)
  2. Enter a project name (or accept the default)
  3. Provide a brief description of your project

After answering these questions, Tonk will scaffold a new project with everything you need to get started, including:

  • React, TypeScript, and Tailwind CSS
  • Keepsync for state management and synchronization
  • Development tools and configuration

Developing your app

Navigate to your project directory and start development:

cd my-app
pnpm dev

This will:

  1. Start a development server with hot reloading
  2. Set up a sync server for real-time collaboration
  3. Open your app in the browser (typically at http://localhost:3000)

Understanding Tonk Stores

Stores are what make Tonk apps special. They're containers of shareable data that easily plug into any app. Stores are synchronized using the Automerge CRDT library, which enables automatic conflict resolution when multiple users edit the same data.

Unlike traditional databases, Tonk stores:

  • Work offline first, then sync when connections are available
  • Don't require schema migrations
  • Handle synchronization automatically
  • Provide real-time updates across all connected clients

Working with stores in your app

Your Tonk app comes with the @tonk/keepsync library already integrated. Here's how to use it:

// 1. Import the sync middleware
import { create } from "zustand";
import { sync } from "@tonk/keepsync";

// 2. Create a synced store
const useTodoStore = create(
  sync(
    (set) => ({
      todos: [],
      addTodo: (text) =>
        set((state) => ({
          todos: [...state.todos, { id: Date.now(), text, completed: false }],
        })),
      toggleTodo: (id) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id ? { ...todo, completed: !todo.completed } : todo
          ),
        })),
    }),
    { docId: "todos" } // This identifies the store for synchronization
  )
);

When multiple users access your app, any changes they make to the store will automatically synchronize across all clients in real-time.

Deploying your app

Once your app is ready for deployment, you can build and serve it:

# Build the app
pnpm run build

# Push the bundle you've just built
tonk push

Start a service to host your bundle

tonk start <bundleName>

The bundleName will likely be the folder of your project. You can see available bundles by running tonk ls


Usage: tonk start [options] <bundleName>

Start a bundle server

Arguments:
bundleName Name of the bundle to start

Options:
-u, --url <url> URL of the Tonk server (default: "http://localhost:7777")
-p, --port <port> Port for the bundle server (optional)

You should see a message like:


Bundle server started successfully!
Server ID: 454f91d5-40a9-4892-aca8-f6cfaa3936a5
Running on port: 8000
Status: running
Use 'tonk ps' to see all running servers

Use a reverse-proxy to share your application to external devices

Pinggy makes this simple and free


ssh -p 443 -R0:localhost:8000 free.pinggy.io

The caveat is of course that free pinggy tunnels last only 60 minutes. If you pay for a dedicated tunnel, then you could serve the application off that.

Tonk Deploy (Coming Soon TM)

Dedicated hosting of bundles at Tonk is on the roadmap. Please let us know if you'd like to join early access.

For more advanced deployment options, see the reference section.

Tonk Stack

Keepsync Library
Offline + private
functionality
Tonk
CLI
Tonk Daemon
React + Typescript + Tailwind
State
management
Distributed
auth*
Share Links
Deployment*

*under construction

The Tonk stack consists of a few packages:


Tonk CLI

A command line utility tonk that runs the Tonk Daemon and communicates to your Tonk. This tool helps you to create Tonk template applications and manage different packaged bundles you are hosting.


Tonk Daemon

Hosts app bundles, the sync websocket and saves changes of stores to the filesystem. Changes are propagated to every client (allowing collaboration) and saved as stores on your machine when you are running your applications connected with keepsync. 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";
import { BrowserWebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
import { IndexedDBStorageAdapter } from "@automerge/automerge-repo-storage-indexeddb";

const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
const httpProtocol =
  window.location.protocol === "https:" ? "https://" : "http://";
const wsUrl = `${wsProtocol}//${window.location.host}/sync`;
const wsAdapter = new BrowserWebSocketClientAdapter(wsUrl);
const storage = new IndexedDBStorageAdapter();

configureSyncEngine({
  url: `${httpProtocol}//${window.location.host}`,
  network: [wsAdapter as any],
  storage,
});

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>
  );
}

You can also directly read and write documents and address them using paths similar to a filesystem. This is useful for when you need more fine-grained control over document access and a zustand store is too cumbersome (e.g. when you want each document to have its own space and be directly addressable);

import { readDoc, writeDoc } from "@tonk/keepsync";

 * Reads a document from keepsync
 *
 * This function retrieves a document at the specified path in your sync engine.
 * It returns the document content if found, or undefined if the document doesn't exist.
 *
 * @param path - The path identifying the document to read
 * @returns Promise resolving to the document content or undefined if not found
 * @throws Error if the SyncEngine is not properly initialized
 */
readDoc = async <T>(path: string): Promise<T | undefined>;

/**
 * Writes content to a document to keepsync
 *
 * This function creates or updates a document at the specified path.
 * If the document doesn't exist, it creates a new one.
 * If the document already exists, it updates it with the provided content.
 *
 * @param path - The path identifying the document to write
 * @param content - The content to write to the document
 * @throws Error if the SyncEngine is not properly initialized
 */
writeDoc = async <T>(path: string, content: T);

Reference

This reference guide provides detailed information about Tonk commands, features, and troubleshooting tips.

Command reference

The Tonk CLI includes the following commands:

tonk hello

Initializes the Tonk daemon, which provides synchronization services for your apps.

Usage: tonk hello [options]

Say hello to start and launch the tonk daemon

Options:
  -h, --help  display help for command

tonk create

Creates a new Tonk application with an interactive setup process.

Usage: tonk create [options]

Create a new tonk application or component

Options:
  -i, --init  initialize in the folder
  -h, --help  display help for command

tonk push

Packages and uploads your application bundle.

Usage: tonk push [options]

Package and upload a bundle to the Tonk server

Options:
  -u, --url <url>    URL of the Tonk server (default: "http://localhost:7777")
  -n, --name <name>  Name for the bundle (defaults to directory name)
  -d, --dir <dir>    Directory to bundle (defaults to ./dist)
  -s, --start        Start the bundle after upload
  -h, --help         display help for command

tonk ls

Lists available application bundles.

Usage: tonk ls [options]

List available bundles on the Tonk server

Options:
  -u, --url <url>  URL of the Tonk server (default: "http://localhost:7777")
  -h, --help       display help for command

tonk ps

Shows running bundle servers.

Usage: tonk ps [options]

List running bundle servers

Options:
  -u, --url <url>  URL of the Tonk server (default: "http://localhost:7777")
  -h, --help       display help for command

tonk start <bundle-name>

Starts a bundle server for a specific bundle.

Usage: tonk start [options] <bundleName>

Start a bundle server

Arguments:
  bundleName         Name of the bundle to start

Options:
  -u, --url <url>    URL of the Tonk server (default: "http://localhost:7777")
  -p, --port <port>  Port for the bundle server (optional)
  -h, --help         display help for command

tonk kill <server-id>

Stops a running bundle server.

Usage: tonk kill [options] <serverId>

Stop a running bundle server

Arguments:
  serverId         ID of the server to stop

Options:
  -u, --url <url>  URL of the Tonk server (default: "http://localhost:7777")
  -h, --help       display help for command

Using llms.txt files

Tonk projects include llms.txt files containing instructions for AI assistants. These files help AI models understand the project structure and conventions when helping you develop your app.

FAQ

Pre-requisites to install

  1. You'll need Node.js and npm installed to run the Tonk installation command.

How do I get it working on Windows?

Tonk should work on Windows without any extra configuration.

  1. Install Tonk via npm:
npm install -g @tonk/cli
  1. Start Tonk:
tonk hello