Quick Start

Build a complete todo app in 5 minutes. No configuration, no dependencies, no build step.

Step 1

Install FLIN

FLIN ships as a single binary. One command installs everything you need — the language runtime, FlinDB, FlinUI, 1,675 icons, and all 420+ built-in functions.

curl -fsSL https://flin.sh | bash

Verify the installation:

flin --version

You should see v1.0.0-alpha.2. FLIN supports macOS, Linux, and Windows (WSL).

Step 2

Create a New App

Scaffold a new project with the flin new command. This creates a ready-to-run app with file-based routing.

flin new my-app && cd my-app

This creates the following structure:

Project structure
my-app/
├── app/
│   └── index.flin          // Home page → /
├── components/              // Custom components
├── layouts/
│   └── default.flin        // Default layout
├── entities/                // Data models
└── .env                     // Environment variables

Files in app/ become routes automatically. app/about.flin becomes /about. Folders create nested paths: app/blog/index.flin becomes /blog.

Step 3

Write Your First Page

Open app/index.flin and replace its contents with the code below. This single file defines a data model, functions, and a template — a complete todo app.

app/index.flin
// 1. Define your data model
entity Todo {
    title: text @required
    done: bool = false
}

// 2. State variables (reactive)
newTitle = ""

// 3. Functions
fn add() {
    if newTitle != "" {
        todo = Todo { title: newTitle }
        save todo
        newTitle = ""
    }
}

fn toggle(t: Todo) {
    t.done = !t.done
    save t
}

fn remove(t: Todo) {
    delete t
}

// 4. Template — just HTML + {curly braces}
<h1>{Icon name="check-square" size="28"} My Todos ({Todo.count})</h1>

<form submit={add()}>
    <input bind={newTitle} placeholder="What needs doing?" />
    <button type="submit">Add</button>
</form>

{if Todo.count == 0}
    <p>No todos yet. Add one above!</p>
{else}
    {for todo in Todo.all}
        <div class="todo-item">
            <input type="checkbox"
                checked={todo.done}
                change={toggle(todo)} />
            <span>{todo.title}</span>
            <button click={remove(todo)}>
                <Icon name="trash-2" size="14" />
            </button>
        </div>
    {/for}
{/if}

<p>{Todo.where(done == true).count} completed, {Todo.where(done == false).count} remaining</p>

Let's break down what's happening:

  • Lines 2-5: entity Todo defines a data model. FLIN automatically adds id, created_at, and updated_at fields. The @required validator ensures title is never empty.
  • Line 8: newTitle = "" creates a reactive variable. When it changes, the template updates automatically.
  • Lines 11-16: save todo persists the entity to FlinDB. No SQL, no ORM configuration.
  • Lines 18-21: Functions that take entities must have type annotations: t: Todo.
  • Line 27: bind={newTitle} creates two-way binding between the input and the variable.
  • Line 43: Template method chains like {Todo.where(done == true).count} work directly in the template.
Step 4

Run the Dev Server

Start the development server with hot reload. Every time you save a .flin file, the page updates automatically.

flin dev

Open http://localhost:3000 in your browser. You should see your todo app, ready to use. Try adding a few todos, checking them off, and deleting them.

Edit app/index.flin and save — your browser refreshes instantly. No build step, no waiting.

Step 5

Explore the Admin Console

Every FLIN app ships with a built-in admin console. No extra setup required — it's embedded in the binary.

Visit http://localhost:3000/_flin to access:

Entity BrowserBrowse, search, edit, and delete records for any entity. See your Todo items right away.
Query EditorExecute FLIN queries interactively. Try Todo.where(done == false) to see incomplete todos.
REST API DocsAuto-generated API documentation for every entity. FLIN creates REST endpoints automatically.
Metrics &amp; LogsReal-time request metrics, system health gauges, and request logs — all built in.