Fast to start
Run nubo file.nubo for scripts, or nubo serve . for a web app. The first useful program can be one file.
Nubo starts simple. Create a .nubo file and run it directly.
let name = "Nubo"
println("Hello, " + name)nubo hello.nuboHello, NuboNo server. No framework. No project structure required.
A .nubo file can also be an HTTP route.
import request from "@server/request"import response from "@server/response"
let name = request.query("name")
if isNil(name) { name = "World"}
response.write(<h1>Hello, { name }</h1>)nubo serve .Open:
http://localhost:3000/?name=NuboNubo gives you direct access to the request and response, so small web apps stay small.
Fast to start
Run nubo file.nubo for scripts, or nubo serve . for a web app. The first useful program can be one file.
Web features built in
Routes, request data, JSON responses, cookies, uploads, static files, and custom error pages are part of the Nubo server workflow.
Typed, but not noisy
Let Nubo infer simple values, then add types for functions, lists, dictionaries, structs, interfaces, and function values when structure matters.
HTML is part of the language
Return html values, build components, pass children, bind attributes, and compose pages without switching languages.
Serve a folder and Nubo maps files to routes.
index.nubousers/ [id].nuboerror.nuboDynamic route params are available through @server/request.
import request from "@server/request"import response from "@server/response"
let id = request.param("id")
response.json({ "id": id})GET /users/42{ "id": "42"}Read JSON from the request and return JSON from the response.
import request from "@server/request"import response from "@server/response"
if !request.is("POST") { response.status(405) response.json({ "error": "method not allowed" })
return}
let data = request.json()
response.json({ "ok": true, "received": data})That is enough for small APIs, internal tools, prototypes, dashboards, and webhooks.
Nubo can infer types:
let title = "Dashboard"let count = 5let enabled = trueAdd annotations where they help:
let names: []string = ["Nubo", "Cloud"]
let scores: dict[string, int] = { "nubo": 100}Create your own types:
struct User { name: string roles: []string}
fn hasRole(user: User, role: string) bool { return user.roles.includes(role)}Function implementations use the return type after the parameter list:
fn greet(name: string) string { return "Hello, " + name}Use -> only for function value types:
let formatter: fn(string) -> stringUse @std/component to build reusable HTML components.
import { Context } from "@std/component"
fn Button(ctx: Context) html { return <button class="btn"> { ctx.children.join(" ") } </button>}Then compose it like HTML:
let page = <main> <h1>Nubo App</h1> <Button>Save changes</Button></main>
println(page)Normal interpolation escapes content.
let name = <script>alert(1)</script>
let safe = <p>{ name }</p>Use !{ ... } only when you intentionally want raw HTML.
let html = <strong>Nubo</strong>
let raw = <p>!{ html }</p>Nubo includes standard libraries for common app work.
import http from "@std/http"import json from "@std/json"import sql from "@std/sql"import hash from "@std/hash"import io from "@std/io"import time from "@std/time"Hash a password:
import hash from "@std/hash"
let password = "secret"let hashed = hash.bcrypt(password)
if hash.bcrypt.compare(password, hashed) { println("password ok")}Make an HTTP request:
import http from "@std/http"
let res = http.base.request("GET", "https://example.com")
println(res.status)println(res.body())Run a process:
import process from "@std/process"
let result = process.run("git", ["--version"])
println(result.stdout)Nubo can use packages from GitHub.
nubo get github.com/nubolang/colorimport color from "github.com/nubolang/color"
println(color.green("success"))println(color.yellow("warning"))println(color.red("error"))Small web apps
Build pages, forms, dashboards, and APIs without pulling in a large framework.
Internal tools
Connect HTTP, SQL, JSON, IO, processes, hashing, SSH, Telnet, or serial communication in a small codebase.
Prototypes
Try ideas quickly with file-based routes, simple types, and HTML returned directly from Nubo.
Scripts that can grow
Start with nubo file.nubo, then move the same code toward a server route or package when needed.
go install github.com/nubolang/nubo/cmd/nubo@latestnubo initnubo hello.nubonubo serve .