---
title: Getting started
description: Run Sluurp, make an administrator, serve a folder.
section: Start
order: 1
---

# Getting started

<p class="lead">Sluurp is a single executable. It stores data in a folder of SQLite files and serves an API, an admin UI and your app. Nothing else to install.</p>

Sluurp is free for non-commercial use: personal projects, study, schools, clubs and charities. Using it in a business needs a [business licence](/business), one per server.

## Install

On macOS and Linux:

```sh title="Terminal"
curl -fsSL https://raw.githubusercontent.com/SluurpHQ/releases/main/install.sh | sh
```

On Windows, in PowerShell:

```sh title="PowerShell"
irm https://raw.githubusercontent.com/SluurpHQ/releases/main/install.ps1 | iex
```

Both install the `sluurp` binary to `~/.sluurp/bin`. Set `SLUURP_VERSION=v0.2.0` to pick a release, or `SLUURP_INSTALL` for another folder.

## Run it

```sh title="Terminal"
sluurp superuser you@example.com a-long-password
sluurp serve --public ./my-app
```

| Path | What |
|---|---|
| `/` | your app (the `--public` folder) |
| `/api/` | the REST, realtime and sync API |
| `/_/` | the admin UI: collections, records, rules, logs, SQL, backups, jobs |
| `/sluurp.js` | the browser client, imported as `"sluurp"` |

## From a git repository

`--public` also accepts a repository URL. It's shallow-cloned into the current folder and served from there; on the next run the clone is pulled first.

```sh title="Terminal"
sluurp serve --public https://github.com/you/your-app
```

Append a subfolder (`…/repo/reports`) or a branch or tag (`…/repo@v2`). Without a subfolder, the repository root is the app, or its `app/` folder if the root isn't one. Your own `git` does the fetching, so private repositories work wherever `git clone` does. Local changes in the clone are never overwritten.

## A first collection

Create one in the admin UI, or define it in `schema.json`:

```json title="schema.json"
{
  "collections": [{
    "name": "todos",
    "schema": [
      { "name": "title", "type": "text", "required": true },
      { "name": "done", "type": "bool" },
      { "name": "author", "type": "relation", "relation": "users" }
    ],
    "rules": {
      "list": "author = @request.auth.id",
      "create": "author = @request.auth.id",
      "update": "author = @request.auth.id"
    }
  }]
}
```

`sluurp serve --public ./my-app` applies the app's `schema.json` (inside the folder or next to it) on startup: new collections and fields are added, nothing is dropped. `sluurp schema apply schema.json` does the same manually; add `--drop` to also remove what's no longer in the file.

## A first page

No bundler, no `npm install`. The page imports `sluurp` through the import map Sluurp injects.

```html title="my-app/index.html"
<script type="module">
  import { Sluurp } from "sluurp";
  const todos = await new Sluurp().collection("todos").list({ sort: "-created" });
</script>
```

Next: a server-rendered page in [routes/](/docs/server-components), a function the browser can call with ["use server"](/docs/server-functions), or live data with [sync](/docs/sync).

## Ship it

`sluurp compile` builds a single binary containing the server and your app. `sluurp push` and `deploy` store an app as an immutable bundle and point a channel at it; `rollback` reverts a channel to the previous version.
