🐕Dogfooding: This site is 100% built with FLIN v1.0.0-alpha.2
v1.0 Launch in -Join Discord
THE SECRET

FLIN = HTML + CSS

That's it. No new paradigms. No complex concepts.
If you know HTML and CSS, you already know 90% of FLIN.

HTML<button>Click</button>
+
CSS.btn { color: blue }
+
FLIN Magicclick={count++}
=
Enterprise AppR
471

Technologies Replaced by FLIN

Everything you used to install separately is now built-in.

Frontend

  • React/Vue/Svelte .flin files
  • Material UI/Chakra FlinUI (180 components)
  • useState/Zustand variables
  • React Router app/ folder
  • Tailwind/CSS-in-JS plain CSS

Backend

  • Express/Fastify route GET/POST
  • Passport.js guards { auth }
  • express-rate-limit rate_limit()
  • multer file @image

Database

  • PostgreSQL/MySQL .flindb/ (WAL, CRC, locking)
  • Prisma/Drizzle entity + 49 validators
  • Redis built-in cache
  • S3/Cloudinary save_file()

Auth & Security

  • NextAuth/Auth.js auth_google_login()
  • speakeasy/otplib totp_verify()
  • bcrypt/argon2 bcrypt_hash()
  • jsonwebtoken jwt_create()

DevOps

  • dotenv env("KEY")
  • PM2 systemd (3 lines)
  • webpack/vite not needed
  • Docker Compose 1 Dockerfile

AI & Search

  • OpenAI SDK ask_ai()
  • Pinecone/Weaviate semantic search
  • LangChain ask ... about
  • Elasticsearch BM25 built-in

No package.json. No node_modules. No dependency hell. Just one binary that does everything.

JS/TS Developers: You Already Know 80%

FLIN accepts TypeScript type names, the function keyword, null, console.log, and .length. Use what you know on day one.

Y

Works unchanged from JS/TS

// Type aliases
entity User {
    name: string       // = text
    age: number        // = float
    active: boolean    // = bool
}

// function keyword
function greet(name: string) {
    return "Hello, " + name
}

// null works everywhere
if user == null { return null }

// console.log works
console.log("debug info")

// .length works on strings + lists
name.length     // 5
items.length    // 3

// Also: let, const, ??, ++, +=,
// try/catch, async/await
3

Only 3 things are different

// 1. Maps use ["key": val] not {}
data = ["name": "Alice", "age": 30]
// { name: "Alice" } gives helpful error

// 2. Functions over methods
push(items, x)       // not items.push(x)
map(arr, fn)         // not arr.map(fn)
json_decode(str)     // not JSON.parse(str)

// 3. No imports needed
// Just use <Button> and User.all
// Components + entities auto-discovered

If you write maps with curly braces, FLIN tells you to use bracket syntax instead. Helpful errors, not cryptic ones.

The Only 6 Things to Learn

Everything else is just HTML and CSS you already know.

1

Variables are Reactive

// Declare a variable
count = 0

// It updates the UI automatically
<span>{count}</span>

No useState, no signals, no stores. Just variables.

2

Events are Simple

// click, submit, change, input...
<button click={count++}>
    Add
</button>

<form submit={save()}>
    ...
</form>

Same events as HTML. Just add the action.

3

Two-Way Binding

name = ""

// bind connects input to variable
<input bind={name} />

// Shows what you type
<p>Hello, {name}!</p>

No onChange handlers. Just bind.

4

Show/Hide with if

logged_in = false

{if logged_in}
    <Dashboard />
{else}
    <Login />
{/if}

Just like every template language.

5

Loop with for

todos = ["Buy milk", "Code", "Sleep"]

{for todo in todos}
    <li>{todo}</li>
{/for}

Standard for loop. Nothing new.

6

Entities = Your Database

// Enums — type-safe, auto-validated
enum Priority { Low, Medium, High }

entity Todo {
    title: text @required @minLength(2)
    done: bool = false
    priority: Priority = "Low"

    @index(done, priority)
}

// Create, save, query
todo = Todo { title: "Learn FLIN" }
save todo
Todo.where(done == false).count

Built-in database. No SQL. No setup. Just save.

Y

That's it. Variables, events, bind, if, for, entities. The rest is HTML and CSS.

What You Already Know vs FLIN

HTML Structure

HTML<div class="card">
FLIN<div class="card">

Exactly the same!

CSS Styling

CSS.card { padding: 1rem }
FLIN.card { padding: 1rem }

Exactly the same!

Inline Styles

HTMLstyle="color: red"
FLINstyle="color: red"

Exactly the same!

Dynamic Class

ReactclassName={`btn ${active}`}
FLINclass="btn {active}"

Just use interpolation in class

Form Input

Reactvalue={x} onChange={...}
FLINbind={x}

One word instead of two

Click Handler

ReactonClick={() => setX(x+1)}
FLINclick={x++}

Direct action, no wrapper

Build a Real App: Step by Step

A complete task manager in one file. This is real, working FLIN codefrom the official todo-embedded example.

1

Define Your Data

// entities/Todo.flin
enum Priority { Low, Medium, High, Critical }
enum Category { General, Work, Personal }

entity Todo {
    title: text @required @minLength(2)
    done: bool = false
    priority: Priority = "Low"
    category: Category = "General"
    due: time

    @index(done, priority)
    @unique(title)
}

// 10 types, 49 validators, enums, constraints
// Auto-adds: id, created_at, updated_at, version

No SQL. No migrations. No Prisma. Just declare your fields.

2

Write Your Functions

// Always type entity parameters!
fn toggleTask(task: Todo) {
    task.done = !task.done
    save task
}

fn deleteTask(task: Todo) {
    delete task
}

fn getGrade(score: int) {
    result = match score {
        n if n >= 90 -> "A"
        n if n >= 80 -> "B"
        _ -> "C"
    }
    return result
}

Functions with type annotations. Match expressions with guards. Simple.

3

Query Your Data

// Filter with match
filter = "all"

todos = match filter {
    "pending" -> Todo.where(done == false)
    "done" -> Todo.where(done == true)
    _ -> Todo.all
}

// Chain queries
Todo.where(priority > 2)
    .order_by("created_at", "desc")
    .limit(10)

// Aggregations
Todo.count
Todo.where(done == true).count

Readable queries. Chainable. Works in templates too.

4

Build Your UI

// Standard HTML with {curly braces}
<h1>Tasks ({Todo.count})</h1>

<form submit={add()}>
    <input bind={newTitle} />
    <button type="submit">Add</button>
</form>

{for task in todos}
    <div class={task.done ? "done" : ""}>
        <span>{task.title}</span>
        <button click={toggleTask(task)}>
            Toggle
        </button>
    </div>
{/for}

HTML you know + FLIN curly braces. That's the whole UI layer.

5

Add Dark Mode & i18n

// Session persists to cookie
theme = session.theme || "light"

<div data-theme={theme}>
    <button click={
        session.theme = theme == "light"
            ? "dark" : "light";
        location.reload()
    }>Toggle Theme</button>
</div>

// i18n (translations auto-loaded)
fn t(key) {
    dict = translations[session.lang || "en"]
    result = dict[key]
    return result ?? key
}

Session variables survive page reloads. Built-in i18n.

6

Add an API Route

// app/api/todos.flin
route GET /api/todos {
    todos = Todo.all
    response.ok({ todos: todos })
}

route POST /api/todos {
    guards { auth: required }
    validate {
        title: text @required @minLength(2)
        priority: text @one_of("Low", "Medium", "High")
        email: text @email
    }
    todo = Todo { title: body.title }
    save todo
    response.created(todo)
}

REST API with guards and validation. Auto-generates OpenAPI docs.

T

Try it yourself: Run flin dev embedded/todo-app to see this exact pattern running live.Then check flin dev embedded/fullstack for the advanced version with auth, OAuth, and WebSocket.

380+ Built-in Functions

No npm install. No importing. Every function is global and ready to use.

Strings (35)

len("hello")uppercase("hi")split("a,b", ",")join(list, ", ")replace(s, "a", "b")trim(" hi ")starts_with(s, "http")slugify("Hello World")

Math (35)

abs(-5)floor(3.7)ceil(3.2)round(3.14, 1)sqrt(16)pow(2, 10)random(1, 100)sum([1,2,3])

Lists (34)

push(list, item)pop(list)sort(list)unique(list)filter(list, fn)map(list, fn)contains(list, x)flatten(nested)

Date/Time (35)

now()today()time_format(t, "%Y-%m-%d")time_add(t, 7, "days")time_diff(a, b, "hours")time_is_weekend(t)parse_date("2026-01-15")time_to_iso(t)

Crypto & Auth (30)

uuid()bcrypt_hash(pwd)bcrypt_verify(pwd, h)jwt_create(payload)sha256("data")aes_encrypt(data, key)totp_secret()totp_verify(s, code)

Validation (20)

is_email("[email protected]")is_url("https://...")is_uuid(str)is_strong_password(p)matches_pattern(s, r)is_json(str)is_number("42")is_empty(val)

Plus: HTTP client (http_get, http_post), file I/O (read_file, write_file), email (send_email), PDF (pdf_from_html), OAuth (Google, GitHub, Discord), jobs (job_queue, job_schedule), AI (ask_ai, semantic search), and more.

Explore all 380+ functions live: flin dev embedded/playground

The Real Secret: CSS is Your Superpower

Enterprise UIs aren't about fancy JavaScript frameworks.
They're about well-organized CSS.

1

Use CSS Variables

:root {
    --primary: #d4a853;
    --radius: 8px;
    --shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.card {
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

Change one variable, update entire app.

2

Use Flexbox & Grid

/* Flexbox for alignment */
.header { display: flex; gap: 1rem; }

/* Grid for layouts */
.cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.5rem;
}

Master these two and you can build anything.

3

Use Semantic Classes

/* Bad */
.red-text { color: red; }
.big-margin { margin: 20px; }

/* Good */
.error-message { color: var(--error); }
.card-spacing { margin: var(--space-4); }

Name what it IS, not what it looks like.

4

Dark Mode in 5 Lines

[data-theme="dark"] {
    --bg: #1a1a1a;
    --text: #ffffff;
    --border: #333;
}

/* FLIN: Toggle with one click */
<button click={theme = "dark"}>

CSS does the work. FLIN just switches the variable.

507+ Ready-to-Copy Patterns

Every UI pattern you need is already documented with working code.Copy, don't reinvent.

Core (10 guides)

  • Components
  • Routing
  • Layouts
  • Styling
  • State
  • Deployment

UI & Forms (25 guides)

  • FlinUI (180 components)
  • Forms & Validation
  • Modals & Dialogs
  • Dropdowns & Tabs
  • Toasts & Alerts
  • Date/Color Pickers

Components (15 guides)

  • Data Tables
  • Card Grids
  • Pagination
  • Infinite Scroll
  • Carousel
  • Timeline

Auth & Security (10 guides)

  • Login/Register
  • OAuth (Google/GitHub)
  • Two-Factor Auth
  • WhatsApp OTP
  • Guards & Roles
  • Password Reset

Data & API (15 guides)

  • CRUD Operations
  • Queries & Filters
  • REST API
  • File Upload
  • Search
  • Time Travel

Special Features (30+ guides)

  • i18n (Multi-language)
  • Theme Toggle
  • WebSockets
  • AI Chat
  • Shopping Cart
  • PDF Generation
12

The 12-Year-Old Test

Every piece of FLIN code must be understandable by a 12-year-old who knows basic HTML.

If it's confusing, it's wrong. If it needs explanation, it needs simplification.

If you can't explain it simply, you don't understand it well enough.— Albert Einstein

A Real Example: Login Page

See how HTML knowledge directly translates to FLIN.

app/login.flin
// Variables (reactive)
email = ""
password = ""
error = ""

// HTML you already know
<div class="login-card">
    <h1>Welcome Back</h1>

    {if error}
        <p class="error">{error}</p>
    {/if}

    <form submit={login()}>
        <input
            type="email"
            bind={email}
            placeholder="Email"
        />

        <input
            type="password"
            bind={password}
            placeholder="Password"
        />

        <button type="submit">
            Sign In
        </button>
    </form>

    <p>
        Don't have an account?
        <a href="/register">Sign up</a>
    </p>
</div>

What's Happening

email = ""Declare a variable. It's reactive automatically.
bind={email}Connect input to variable. Two-way sync.
{if error}Show error message only when error exists.
submit={login()}Call login function when form submits.
&lt;a href="/register"&gt;Standard HTML link. Nothing special.
90% is HTML you already know.
The FLIN parts are just: variables, bind, if, submit.

Ready to Build?

Start with the embedded examples. See real code. Copy what works.

Beginner
flin dev embedded/starter
Intermediate
flin dev embedded/todo-app
180 Components
flin dev embedded/flinui

The fullstack app includes: Auth, OAuth, 2FA, API routes, uploads, WebSocket, i18n, themes.FlinUI includes 180 components, 1,667 icons, charts, templates, and more.
Copy the code. Make it yours. No attribution needed.

Continue Learning

Master FLIN with our complete documentation atdocs.flin.dev

Go to Full Documentation