Coline Docs
Sites

Coline Sites

Put a Coline app on the web at its own address, with visitors, data rules and live updates, in one command.

A site is a Coline app with a public website. It gets its own address, name.coline.space or your own domain, and anyone can open it without an account. Its data lives in a Coline workspace: the team sees every record, gets notified about new ones, and can ask Kairo about them.

Sites are part of SDK 2.1 (@colineapp/sdk 2.1.2 and create-coline-app 2.9.1).

Quickstart

No account is needed to build or deploy a site.

npx create-coline-app my-site --template site
cd my-site && npm install
npm run dev          # http://127.0.0.1:3000, data in memory
npx coline-app deploy

deploy prints the live address and a claim link. A site deployed without an account stays up for 72 hours after its last deploy. Open the claim link, sign in, and pick a workspace to keep it. See deploy and claim.

What's in a site

The site template is a guestbook:

my-site/
  app.config.ts      the app: permissions, the site, collections and tools
  app.test.ts        the same rules Coline enforces, in memory
  site/main.tsx      the website (React)
  site/app.css       Tailwind is built in
  site/public/       files served at the site root (favicon, images)
  AGENTS.md          the contract, for coding agents

The site surface declares the page, its routes and what visitors can do:

import { z } from "zod/v4";
import { defineApp, defineTool } from "@colineapp/sdk/v2";

const entry = z.object({ name: z.string().max(60), message: z.string().max(500), signedAt: z.iso.datetime() });
type Entry = z.infer<typeof entry>;

const sign = defineTool({
  name: "guestbook.sign",
  description: "Sign the guestbook.",
  input: z.object({ name: z.string().min(1).max(60), message: z.string().min(1).max(500) }),
  effect: "write",
  execute: async (input, { coline }) => {
    const entry = await coline.storage
      .collection<Entry>("entries")
      .insert({ ...input, signedAt: new Date().toISOString() });
    return { output: { id: entry.id } };
  },
});

export default defineApp({
  key: "guestbook",
  name: "Guestbook",
  permissions: ["site.serve", "storage.app", "ai.tools"],
  hosting: { default: "coline" },
  surfaces: {
    site: {
      entry: "site/main.tsx",
      assets: "site/public",
      title: "Guestbook",
      description: "Leave a note.",
      routes: [{ path: "/" }, { path: "/entries/:id", head: { title: "An entry" } }],
      visitors: { signIn: true, providers: ["google", "coline"] },
      tools: ["guestbook.sign"],
    },
  },
  collections: {
    entries: { access: { read: "public", update: "owner", delete: "owner" }, schema: entry },
  },
  tools: [sign],
});

The page talks only to its own site. The React hooks are typed from the app itself, so collection names, record shapes and tool inputs are checked at compile time:

import { createSiteHooks, SignInButton, useSession } from "@colineapp/sdk/site/react";
import type app from "../app.config";

const { useCollection, useTool } = createSiteHooks<typeof app>();

function Guestbook() {
  const entries = useCollection("entries", { orderBy: "createdAt", order: "desc" }); // live
  const sign = useTool("guestbook.sign");
  // sign.run({ name: "Ada", message: "Hello" })
}

How it works

  • Every site is a Coline app. The same app can also have a home screen inside Coline, file types and Kairo tools. Its records are workspace records.
  • Visitors are their own kind of user. They are guests by default. A site can offer sign-in with Google or Coline, require it, or admit only visitors the team approves. Visitors never act as a workspace member or as the app.
  • Collections say who can do what. Each collection declares which visitors may read, create, update and delete, and a schema that every visitor write must match. A collection without rules is invisible to visitors. See data and rules.
  • Tools are the site's server code. Visitors can run the tools a site lists. They run on Coline as the app, with the app's permissions, and never at more than the write effect.
  • Endpoints answer HTTP on the site's own paths, for webhooks, JSON APIs and feeds. See endpoints.
  • Visitors can upload files when the site accepts them. See files.
  • Pages update live. Collections refresh when records change, for every visitor.
  • Coline serves the page. Each route gets server-rendered <title>, description and link preview tags, a sitemap and robots.txt. The page itself is client-rendered React.
  • Browser agents can use the site. With agentTools: true, the site's tools are offered to AI agents in the visitor's browser.

Next

On this page