phoon

A web framework inspired by ExpressJS ๐Ÿ‡โšก

Pure Nim score 15/100 ยท tests present ยท no docs generated

Summary

Latest Version Unknown
License Public Domain
CI Status Failing
Downloads 0
Last Indexed 2026-07-21 05:24

Installation

nimble install phoon
choosenim install phoon
git clone https://github.com/ducdetronquito/phoon

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
phoon โœ“ โœ“ โœ“ - - - - - - -

Source

Repository https://github.com/ducdetronquito/phoon
Homepage https://github.com/ducdetronquito/phoon
Registry Source nimble_official

README

Phoon ๐Ÿ‡โšก

Github Actions License

A simple web framework for Nim.

Usage

Nota Bene: Phoon is in its early stage, so every of its aspects is subject to changes ๐ŸŒช๏ธ

Create an application:

import phoon

var app = new App

app.get("/",
    proc (ctx: Context) {.async.} =
        ctx.response.body("I am a boring home page")
)

app.post("/users",
    proc (ctx: Context) {.async.} =
        ctx.response.status(Http201).body("You just created a new user !")
)

app.get("/us*",
    proc (ctx: Context) {.async.} =
        ctx.response.body("Every URL starting with 'us' falls back here.")
)

app.get("/books/{title}",
    proc (ctx: Context) {.async.} =
        # You can retrieve parameters of the URL path
        var bookTitle = ctx.parameters.get("title")

        # You can also retrieve url-decoded query parameters
        let count = ctx.request.query("count")
        if count.isNone:
            ctx.response.body("Of course I read '" & bookTitle & "' !")
        else:
            ctx.response.body(
                "Of course I read '" & bookTitle & "', "
                "at least " & count & " times!"
            )
)

app.get("/cookies/",
    proc (ctx: Context) {.async.} =
        # You can send a cookie along the response
        ctx.response.cookie("size", "A big one ๐Ÿช")
)


# Chaining of callbacks for a given path
app.route("/hacks")
    .get(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle GET requests")
    )
    .patch(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle PATCH requests")
    )
    .delete(
        proc (ctx: Context) {.async.} =
            ctx.response.body("I handle DELETE requests")
    )


app.serve(port=8080)

Create a nested router

import phoon

var router = Router()

router.get("/users",
    proc (ctx: Context) {.async.} =
        ctx.response.body("Here are some nice users")
)

app.mount("/nice", router)

Register a middleware

import phoon

proc SimpleAuthMiddleware(next: Callback): Callback =
    return proc (ctx: Context) {.async.} =
        if ctx.request.headers.hasKey("simple-auth"):
            await next(ctx)
        else:
            ctx.response.status(Http401)

app.use(SimpleAuthMiddleware)

Error handling

import phoon

# Define a custom callback that is called when no registered route matched the incoming request path.
app.on404(
    proc (ctx: Context) {.async.} =
        ctx.response.status(Http404).body("Not Found ยฏ\\_(ใƒ„)_/ยฏ")
)

# Define a custom callback that is called when an unhandled exception is raised within your code.
app.onError(
    proc (ctx: Context, error: ref Exception) {.async.} =
        ctx.response.status(Http500).body("Oops ยฏ\\_(ใƒ„)_/ยฏ\r\n" & error.msg)
)

License

Phoon is released under the BSD Zero clause license. ๐ŸŽ‰๐Ÿป