GitHub - nynrathod/doolang: Type-safe language for building APIs fast. Auth, CRUD, and deployment built-in, written in rust & llvm

4 min read Original article ↗

Doo - Ship Production APIs in Minutes, Not Days

Rust LLVM Native

⚠️ Alpha Software: Doo is in active development. Expect bugs and breaking changes. Not recommended for critical production use yet.

Doo is a statically-typed, compiled programming language built in Rust + LLVM, designed for building production APIs quickly and safely. Doolang eliminates manual memory management with an auto ownership model — the compiler infers whether to move, copy, or clone values based on usage context. No lifetime annotations. No borrow checker fights.

Stop wrestling with boilerplate. Write type-safe APIs and deploy with one command.

// main.doo - Your entire API
import std::Http::Server;
import std::Database;

struct User {
    id: Int @primary @auto,
    email: Str @email @unique,
    password: Str @hash,
}

struct Todo {
    id: Int @primary @auto,
    title: Str @min(3),
    done: Bool @default(false),
}

fn main() {
    let db = Database::Postgres()?;
    let app = Server::new(":3000");

    // Authentication via JWT
    app.auth("/signup", "/login", User, db);

    // Full CRUD
    // GET, POST, GET/:id, PUT/:id, DELETE/:id
    app.crud("/todos", Todo, db);

    app.start();
}

Run it:

doo run  # Compiles to native + starts server

Why Doo?

Traditional Stack Doo
500+ lines of boilerplate 20 lines of code
3 config files Zero config
Manual validation Auto-validated decorators
Separate deployment setup One command deploy
Type mismatches at runtime Compile-time safety

🔧 Installation

Windows (PowerShell)

irm https://raw.githubusercontent.com/nynrathod/doolang/main/install.ps1 | iex

Linux / macOS

curl -fsSL https://raw.githubusercontent.com/nynrathod/doolang/main/install.sh | bash

Verify Installation


🎯 Quick Start

Starter Template

doo init --template starter starter-api
cd starter-api
doo run

Blog Template

doo init --template blog blog-api  # Blog posts + comments API
cd blog-api
doo run

Visit http://localhost:3000 - your API is live.


📖 Real-World Example

Complete task management API with auth, CRUD, and custom queries:

import std::Http::Server;
import std::Database;

enum Status { Todo, InProgress, Done }
enum Priority { Low, Medium, High }

struct User {
    id: Int @primary @auto,
    email: Str @email @unique,
    password: Str @hash @min(8),
}

struct Task {
    id: Int @primary @auto,
    title: Str @min(1) @max(200),
    status: Status @default(Status::Todo),
    priority: Priority @default(Priority::Medium),
    userId: Int @foreign(User),
}

fn GetUrgent() -> [Task] ! DatabaseError {
    let db = Database::get()?;
    let result: [Task] = db.rawWithParams(
        "SELECT * FROM tasks WHERE priority = $1 AND status != $2",
        [Priority::High, Status::Done]
    )?;
    Ok result;
}

fn main() {
    let db = Database::Postgres()?;
    let app = Server::new(":3000");

    app.auth("/signup", "/login", User, db);
    app.crud("/tasks", Task, db);
    app.get("/tasks/urgent", GetUrgent);

    app.start();
}

That's it. 30 lines for a production-ready API with:

  • ✓ User authentication with JWT
  • ✓ Password hashing
  • ✓ Struct validation
  • ✓ Full CRUD operations
  • ✓ Custom business logic
  • ✓ Auto error propagation
  • ✓ Auto migrate table on startup

🌐 Language Essentials

Variables & Types

let name = "Alice";         // Type inferred
let age: Int = 25;          // Explicit
let mut count = 0;          // Mutable
Type Example
Int 42
Float 3.14
Str "hello"
Bool true
[T] [1, 2, 3]
{K: V} {"a": 1}

Structs & Validation

struct User {
    id: Int @primary @auto,
    email: Str @email @unique,
    password: Str @hash @min(8) @max(20),
    age: Int @min(18),
}

// Automatically create table on startup
@table
struct AuditLog {
    id: Int @primary @auto,
    action: Str
}

Error Handling

fn divide(a: Int, b: Int) -> Int ! Str {
    if b == 0 { Err "division by zero"; }
    Ok a / b;
}

let result = divide(10, 2)?;  // Auto-propagate errors

HTTP Routes

fn GetUser(id: Int) -> User ! DatabaseError {
    let db = Database::get()?;
    Ok db.query("SELECT * FROM users WHERE id = $1", id)?;
}

app.get("/users/:id", GetUser);

Full language guide: See examples/ folder for complete tutorials


📦 Examples

Browse comprehensive examples: See tests/dev_test/ folder for real-world patterns including:

  • HTTP routing and middleware
  • Database operations (PostgreSQL)
  • Authentication and JWT
  • Error handling
  • Custom queries and CRUD
  • WebSocket connections
  • File operations
  • And much more!

Quick references:


💬 Community & Support

  • GitHub Discussions: Ask questions, share projects
  • Issues: Bug reports and feature requests
  • Contributing: We welcome PRs! See CONTRIBUTING.md

📊 Performance Benchmarks

See doo-benchmark repository for detailed performance comparisons with other languages.

📜 License

Dual-licensed: MIT or Apache-2.0.


🙏 Acknowledgments

  • Rust + LLVM: Zero compromises on speed/safety.

Ready to ship faster? doo init starter ← Start here

Want to contribute? See CONTRIBUTING.md