Getting Started with Serv

Serv is a programming language for building background services, APIs, schedulers, and event-driven applications. It compiles to native binaries via Go.

Installation

From Source (requires Go 1.22+)

git clone https://github.com/vyuvaraj/Pranor.git
cd Pranor
go build -o pranor.exe main.go

Move pranor.exe to a directory in your PATH.

Verify Installation

serv --help

Hello World

Create hello.pnr:

server "8080"

route "GET" "/hello" (req) {
    return { "message": "Hello from Serv!" }
}

Build and run:

pranor build hello.pnr -o hello.exe
./hello.exe

Visit http://localhost:8080/hello — you'll see:

{"message": "Hello from Serv!"}

Quick Run (no build step)

pranor run hello.pnr

Hot Reload (watch mode)

pranor run hello.pnr --watch

Changes to .pnr files trigger automatic rebuild and restart.

Your First Real Service

server "3000"
database "sqlite://app.db"

// Declare schema — run `serv migrate` once to create the table
table tasks {
    id    int    @primary @autoincrement
    title string @required
    done  bool   @default(0)
}

// Create a task
route "POST" "/tasks" (req) {
    let errors = validate(req.body, { "title": "required" })
    if errors != nil {
        return { "error": errors }
    }
    db.query("INSERT INTO tasks (title, done) VALUES (?, ?)", req.body, false)
    return { "status": "created" }
}

// List tasks
route "GET" "/tasks" (req) {
    let tasks = db.query("SELECT * FROM tasks")
    return { "tasks": tasks }
}

// Scheduled cleanup
every 1h {
    db.query("DELETE FROM tasks WHERE done = true")
    log.info("Cleaned up completed tasks")
}

Apply the schema before first run:

serv migrate app.pnr    # creates the tasks table
pranor run app.pnr

Next Steps