| Crates.io | husk-lang |
| lib.rs | husk-lang |
| version | 0.1.1 |
| created_at | 2025-06-27 19:10:52.446303+00 |
| updated_at | 2025-06-27 19:28:17.148648+00 |
| description | Rust's syntax meets JavaScript's flexibility - Choose your own adventure: Run interpreted for rapid development or transpile to JavaScript for the entire npm ecosystem |
| homepage | https://husk-lang.org |
| repository | https://github.com/fcoury/husk |
| max_upload_size | |
| id | 1729250 |
| size | 2,166,590 |
Choose your own adventure: Run interpreted for rapid development or transpile to JavaScript for the entire npm ecosystem
Husk is a lightweight interpreted language that brings Rust's elegant syntax to the world of scripting and JavaScript development. Write type-safe, expressive code with the flexibility to run it instantly or compile it for production use with full access to npm's 1M+ packages.
Write scripts with Rust's clean, expressive syntax while leveraging JavaScript's massive ecosystem. No more choosing between elegant code and practical libraries.
Perfect for:
# Zero configuration, instant feedback
husk run script.husk
# Interactive REPL for exploration
husk repl
Perfect for:
# Build once, run anywhere JavaScript runs
husk build
# Use with your favorite npm packages
npm install express
node dist/app.js
as# Install Husk (requires Rust/Cargo)
cargo install husk-lang
// hello.husk
fn greet(name: string) -> string {
format!("Hello, {}!", name)
}
fn main() {
let message = greet("World");
println(message);
}
Run it instantly:
husk run hello.husk
Or compile to JavaScript:
husk compile hello.husk | node
To start the Husk REPL, run:
husk repl
To execute a Husk script file, use:
husk run path/to/your/script.hk
To transpile a Husk script to JavaScript, use:
husk compile path/to/your/script.hk
This will output the transpiled JavaScript code to stdout. If you have node installed you can do:
husk compile path/to/your/script.hk | node
Husk supports project-based development with husk.toml configuration files. To build an entire project:
husk build
Additional build options:
# Generate package.json from husk.toml
husk build --generate-package-json
# Specify target platform
husk build --target node-cjs
Create a husk.toml file in your project root:
[package]
name = "my-husk-app"
version = "0.1.0"
description = "My Husk application"
author = "Your Name"
[dependencies]
express = "^4.18.0"
lodash = "^4.17.21"
[build]
target = "node-esm"
src = "src"
out = "dist"
Place your Husk source files in the src directory. The build command will compile all .husk files and generate corresponding JavaScript files in the output directory.
Here's how Husk enables you to move seamlessly from rapid prototyping to production:
// calculator.husk - Quick prototype
fn calculate(operation: string, a: int, b: int) -> Result<int, string> {
match operation {
"add" => Ok(a + b),
"subtract" => Ok(a - b),
"multiply" => Ok(a * b),
"divide" => {
if b == 0 {
Err("Division by zero")
} else {
Ok(a / b)
}
},
_ => Err("Unknown operation")
}
}
fn main() {
let result = calculate("add", 10, 5);
match result {
Ok(value) => println(format!("Result: {}", value)),
Err(msg) => println(format!("Error: {}", msg))
}
}
# Test instantly during development
husk run calculator.husk
# Output: Result: 15
// web-calculator.husk - Production version with Express
use external::express;
async fn create_server() -> Result<unit, string> {
let app = express();
app.get("/calculate/:op/:a/:b", |req, res| {
let operation = req.params.op;
let a = req.params.a as int;
let b = req.params.b as int;
match calculate(operation, a, b) {
Ok(result) => res.json({"result": result}),
Err(error) => res.status(400).json({"error": error})
}
});
app.listen(3000);
println("Server running on http://localhost:3000");
Ok(())
}
async fn main() {
match create_server().await {
Ok(_) => {},
Err(e) => println(format!("Server error: {}", e))
}
}
# Build for production
husk build
npm install express
node dist/web-calculator.js
The same core logic, two different execution modes!
Here are some examples of Husk syntax:
let x = 5;
let name = "Alice";
let is_true = true;
fn add(x: int, y: int) -> int {
x + y
}
struct Person {
name: string,
age: int,
}
let p = Person {
name: "Bob",
age: 30,
};
enum Option {
Some(int),
None,
}
let opt = Option::Some(5);
match opt {
Option::Some(value) => println(value),
Option::None => println("No value"),
}
let arr = [1, 2, 3, 4, 5];
let slice = arr[1..3];
for i in 0..5 {
println(i);
}
// For loop
for x in [1, 2, 3, 4, 5] {
println(x);
}
// While loop
let i = 0;
while i < 5 {
println(i);
i = i + 1;
}
// Infinite loop with break
loop {
println("Hello");
if some_condition {
break;
}
}
Husk supports a module system for organizing code across multiple files:
// In utils.hk
pub fn log(message: string) {
println(format!("[LOG] {}", message));
}
pub fn formatDate(date: string) -> string {
format!("Date: {}", date)
}
// In main.husk
use local::utils::{log, formatDate};
fn main() {
log("Application started");
let today = formatDate("2023-12-25");
println(today);
}
Module import prefixes:
local:: - Import from project rootself:: - Import from current directorysuper:: - Import from parent directoryasync fn fetchData() -> Result<string, string> {
let response = fetch("https://api.example.com/data").await?;
Ok(response.text().await?)
}
async fn main() {
match fetchData().await {
Ok(data) => println(data),
Err(error) => println(format!("Error: {}", error)),
}
}
Husk includes Option and Result types for safe error handling:
fn divide(a: int, b: int) -> Result<int, string> {
if b == 0 {
Err("Division by zero")
} else {
Ok(a / b)
}
}
let result = divide(10, 2)?; // Error propagation operator
Husk supports explicit type conversion using the as operator:
// Numeric conversions
let i = 42;
let f = i as float; // 42.0
let f2 = 3.14;
let i2 = f2 as int; // 3 (truncates decimal)
// String parsing
let s = "123";
let num = s as int; // 123
// To string conversion
let n = 456;
let str = n as string; // "456"
// Boolean conversion
let b = true as int; // 1
let zero = 0 as bool; // false
let nonzero = 5 as bool; // true
Husk provides JavaScript-compatible methods for primitive types:
let s = " Hello World ";
println(s.len()); // 15
println(s.trim()); // "Hello World"
println(s.toLowerCase()); // " hello world "
println(s.toUpperCase()); // " HELLO WORLD "
let text = "Hello World";
println(text.substring(0, 5)); // "Hello"
println(text.substring(6, 11)); // "World"
let csv = "apple,banana,orange";
let parts = csv.split(","); // ["apple", "banana", "orange"]
let arr = [1, 2, 3, 4, 5];
println(arr.len()); // 5
To set up the development environment:
Clone the repository:
git clone https://github.com/fcoury/husk.git
cd husk
Build the project:
cargo build
Run tests:
cargo test
Husk is an open-source project that welcomes contributions from everyone! Whether you're:
We'd love your help making Husk better. Check out our Contributing Guide to get started.
To set up the development environment:
# Clone the repository
git clone https://github.com/fcoury/husk.git
cd husk
# Build the project
cargo build
# Run tests
cargo test
# Install locally for testing
cargo install --path .
This project is licensed under the MIT License - see the LICENSE file for details.
Ready to choose your own adventure?
Visit husk-lang.org to get started!