Automated summary
Expert in the Navi language, a statically-typed compiled language with no NULL pointer exceptions and built-in concurrency support.
Strengths
- No NULL pointer exceptions thanks to modern optional types
- Comprehensive error handling with throws, try, try?
- Built-in concurrency with spawn and channels
- Compiled performance comparable to Go, Rust, and C
Limitations
- If and switch are statements, not expressions, limiting assignment use
- Scientific notation requires explicit sign
- Single-threaded concurrency (spawn) is limited compared to Go's goroutines
Use this skill when writing, debugging, or optimizing Navi code for high-performance applications requiring reliability with no null pointer issues.
Avoid this skill if you need expression-oriented control flow or a mature ecosystem with extensive libraries.
Security analysis
SafeThe skill is purely instructional documentation for the Navi programming language, with no executable actions, destructive commands, or data exfiltration risks.
No concerns found
How this analysis is madeExamples
Write a Navi function that reads a file and returns its contents, handling possible errors properly using throws and try.Explain how optional types work in Navi and show examples of safe unwrapping with ||, ?., and !.Why does this Navi code give a syntax error? let status = if (active) { 'on' } else { 'off' };name: navi description: Navi programming language expert. Use when writing Navi code, implementing features, handling errors, or working with Navi's type system, concurrency, and modules. Navi is a high-performance, statically-typed compiled language with modern optional types, no NULL pointer exceptions, and built-in concurrency support.
Navi Language Skill
Navi (/ˈnævi/) is a high-performance, statically-typed compiled language designed for complex computing tasks. It offers script-like execution with compiled performance comparable to Go, Rust, and C.
Core Characteristics
- Statically typed with type inference
- No NULL pointer exceptions - once compiled, code runs reliably
- Modern optional types (similar to Rust's Option)
- Comprehensive error handling with
throws,try,try?,try! - Built-in concurrency with
spawnand channels (single-threaded concurrency) - Cross-platform: Linux, Windows, macOS, WebAssembly
Quick Reference
Basic Syntax
// Entry point (main must have throws)
fn main() throws {
let name = "World";
let message = `Hello ${name}.`; // String interpolation
println(message); // Auto-imported from std.io
}
// Functions
fn add(a: int, b: int): int {
return a + b;
}
// Structs
struct User {
name: string,
email: string?, // Optional field
active: bool = true, // Default value
}
impl User {
fn new(name: string): User {
return User { name, email: nil };
}
}
Key Syntax Rules
- Statements end with
; - Use 4 spaces for indentation
//for single-line comments,///for doc comments- String interpolation uses backticks:
`value: ${x}` - File extension:
.nv
Important Syntax Limitations
If and Switch are STATEMENTS, not expressions:
// ❌ WRONG - Cannot assign if/switch directly
let status = if (active) { "on" } else { "off" };
let day = switch (n) { case 1: "Mon"; default: "Other"; };
// ✅ CORRECT - Use statements, then assign
let status = "";
if (active) {
status = "on";
} else {
status = "off";
}
Scientific notation requires explicit sign:
// ❌ WRONG
let num = 1.5e10;
// ✅ CORRECT
let num = 1.5e+10; // or 1.5e-10 for negative exponent
Map access with [] vs .get():
let scores = {"Alice": 95, "Bob": 87};
// ❌ WRONG - scores["key"] returns non-optional, can't use ||
let score = scores["Eve"] || 0;
// ✅ CORRECT - Use .get() which returns optional type
let score = scores.get("Eve") || 0;
// ✅ Also correct - Direct access (but key must exist)
let alice_score = scores["Alice"]; // OK if key exists
// ✅ Also correct - Check before access
if (scores.get("Eve") != nil) {
let score = scores["Eve"];
}
Type System Essentials
// Primitives (all 64-bit)
let n: int = 100;
let f: float = 3.14;
let b: bool = true;
let s: string = "text"; // Immutable UTF-8
let c: char = '🎉';
// Optional types (key to NULL safety)
let value: string? = nil;
let result = value || "default"; // Unwrap or default
let length = value?.len(); // Safe chaining (returns nil if value is nil)
println(value!); // Unwrap (panics if nil - use sparingly)
// Collections
let array = [1, 2, 3];
let map = {"key": "value"};
let empty: [int] = [];
Error Handling Pattern
// Declare function can throw
fn divide(a: int, b: int): int throws {
if (b == 0) {
throw "Division by zero";
}
return a / b;
}
// Handle errors
let result = try? divide(10, 0); // Returns int? (nil on error)
let result = try divide(10, 2); // Propagate error up
let result = try! divide(10, 2); // Panic on error
// Do-catch block
do {
let r = try divide(10, 0);
} catch (e) {
println(e.error());
}
Control Flow Patterns
// If-let for optionals
if (let value = optional) {
println(value); // value is unwrapped here
}
// Let-else for early returns
let value = optional else {
return;
};
// value is unwrapped here
// Switch with type matching
switch (let v = value.(type)) {
case int:
println("integer");
case string:
println("string");
default:
println("other");
}
// For loops
for (let i in 0..10) { // Range
println(`${i}`);
}
for (let item in array) { // Array
println(item);
}
for (let k, v in map) { // Map
println(`${k}: ${v}`);
}
Concurrency Basics
use std.time;
fn main() throws {
let ch = channel::<int>();
// Spawn concurrent task (not parallel - single thread)
spawn {
time.sleep(0.1.seconds());
try! ch.send(42);
}
let result = try ch.recv();
println(`${result}`);
}
Worker Pattern
use std.worker.Worker;
fn main() throws {
// Create worker with closure
let worker = try Worker.create(|worker| {
let msg = try worker.recv::<string>()!;
try worker.send(msg.to_uppercase());
});
try worker.send("hello");
let response = try worker.recv::<string>();
println(response); // "HELLO"
}
Navi Stream Integration
use nvs.macd; // Import .nvs file as module
fn main() throws {
// Create instance of NVS indicator
let indicator = macd.new();
// Execute with market data
indicator.execute(
time: 1234567890,
open: 100.0,
high: 105.0,
low: 99.0,
close: 103.0,
volume: 1000.0,
turnover: 100000.0
);
// Access exported variables
println(`hist=${indicator.hist:?}`);
println(`signal=${indicator.signal:?}`);
println(`macd=${indicator.macd:?}`);
}
Variadic Arguments
// Accept arbitrary number of arguments
fn sum(values: ..int): int {
let total = 0;
for (let n in values) {
total += n;
}
return total;
}
sum(1, 2, 3); // Call with multiple args
let nums = [2, 3, 4];
sum(..nums); // Spread array
sum(1, ..nums, 5); // Mix regular and spread
// With other parameters
fn format(prefix: string, parts: ..string): string {
return prefix + parts.join(",");
}
Common Patterns
Safe Optional Handling
// Pattern 1: Unwrap or default
let name = user?.name || "Unknown";
// Pattern 2: If-let
if (let user = optional_user) {
process(user);
}
// Pattern 3: Let-else (early return)
let user = optional_user else {
return;
};
process(user);
// Pattern 4: Method chaining
let email = user?.profile?.email || "none";
Resource Management
fn process_file(path: string) throws {
let file = try open_file(path);
defer {
file.close(); // Always runs when function exits
}
try file.read();
// defer executes here (LIFO if multiple defer blocks)
}
Builder Pattern
impl Config {
fn new(): Config {
return Config { /* defaults */ };
}
fn with_port(self, port: int): Config {
self.port = port;
return self;
}
}
let config = Config.new().with_port(8080);
CLI Commands
navi run # Run main.nv
navi run file.nv # Run specific file
navi test # Run all tests
navi test file.nv # Run tests in file
navi test --doc # Run doc tests
navi build # Build project
navi compile # Show bytecode
Testing
test "addition" {
let result = add(2, 3);
assert result == 5;
assert_eq result, 5;
assert_ne result, 0;
}
/// Doc test example
/// ```nv
/// assert_eq add(1, 2), 3;
/// ```
fn add(a: int, b: int): int {
return a + b;
}
Best Practices
Naming Conventions
snake_case: variables, functions, fields (user_name,get_user)CamelCase: types, structs, enums (User,HttpRequest)SCREAMING_SNAKE_CASE: constants (MAX_SIZE)
When to Use Each Error Handler
try- When error should propagate up (most common)try?- When failure is acceptable, convert to optionaltry!- When failure is unexpected (use sparingly)do-catch- When you need custom error handling logic
Optional Type Guidelines
- Use
||for simple defaults - Use
?.for safe chaining - Prefer
if letfor conditional logic - Use
let elsefor early returns
Concurrency Notes
spawnis concurrent, not parallel (single-threaded)- Tasks interleave but don't run simultaneously
- Use channels for communication between tasks
- Blocking operations block entire runtime
When to Load References
Load reference files when you need detailed information:
- syntax.md - Full syntax reference with all language constructs
- types.md - Complete type system including interfaces, unions, type aliases
- error-handling.md - Comprehensive error handling patterns and custom errors
- concurrency.md - Advanced concurrency patterns, channels, and spawn details
- modules.md - Module system, imports, visibility rules
- testing.md - Testing framework, annotations, doc tests
- patterns.md - Common idiomatic patterns and anti-patterns
Use Read tool to load these files from ~/.claude/skills/navi/references/ when needed.
Resources
- Official Site: https://navi-lang.org
- Standard Library: https://navi-lang.org/stdlib/
- GitHub: https://github.com/navi-language/navi
- Installation:
curl -sSL https://navi-lang.org/install | sh
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/navi-programming-language-expert-mm5t89c4' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/navi-programming-language-expert-mm5t89c4/download' --output '.skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md.part' && mv '.skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md.part' '.skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Original excerpt: Quick Reference
Basic Syntax
// Entry point (main must have throws)
fn main() throws {
let name = "World";
let message = `Hello ${name}.`; // String interpolation
println(message); // Auto-imported from std.io
}
// Functions
fn add(a: int, b: int): int {
return a + b;
}
// Structs
struct User {
name: string,
email: string?, // Optional field
active: bool = true, // Default value
}
impl User {
fn new(name: string): User {
return User { name, email: nil };
}
}
Key Syntax Rules
- Statements end with
; - Use 4 spaces for indentation
//for single-line comments,///for doc comments- String interpolation uses backticks:
`value: ${x}` - File extension:
.nv
Important Syntax Limitations
If and Switch are STATEMENTS, not expressions:
// ❌ WRONG - Cannot assign if/switch directly
let status = if (active) { "on" } else { "off" };
let day = switch (n) { case 1: "Mon"; default: "Other"; };
// ✅ CORRECT - Use statements, then assign
let status = "";
if (active) {
status = "on";
} else {
status = "off";
}
Scientific notation requires explicit sign:
// ❌ WRONG
let num = 1.5e10;
// ✅ CORRECT
let num = 1.5e+10; // or 1.5e-10 for negative exponent
Map access with [] vs .get():
let scores = {"Alice": 95, "Bob": 87};
// ❌ WRONG - scores["key"] returns non-optional, can't use ||
let score = scores["Eve"] || 0;
// ✅ CORRECT - Use .get() which returns optional type
let score = scores.get("Eve") || 0;
// ✅ Also correct - Direct access (but key must exist)
let alice_score = scores["Alice"]; // OK if key exists
// ✅ Also correct - Check before access
if (scores.get("Eve") != nil) {
let score = scores["Eve"];
}
Type System Essentials
// Primitives (all 64-bit)
let n: int = 100;
let f: float = 3.14;
let b: bool = true;
let s: string = "text"; // Immutable UTF-8
let c: char = '🎉';
// Optional types (key to NULL safety)
let value: string? = nil;
let result = value || "default"; // Unwrap or default
let length = value?.len(); // Safe chaining (returns nil if value is nil)
println(value!); // Unwrap (panics if nil - use sparingly)
// Collections
let array = [1, 2, 3];
let map = {"key": "value"};
let empty: [int] = [];
Error Handling Pattern
// Declare function can throw
fn divide(a: int, b: int): int throws {
if (b == 0) {
throw "Division by zero";
}
return a / b;
}
// Handle errors
let result = try? divide(10, 0); // Returns int? (nil on error)
let result = try divide(10, 2); // Propagate error up
let result = try! divide(10, 2); // Panic on error
// Do-catch block
do {
let r = try divide(10, 0);
} catch (e) {
println(e.error());
}
Control Flow Patterns
// If-let for optionals
if (let value = optional) {
println(value); // value is unwrapped here
}
// Let-else for early returns
let value = optional else {
return;
};
// value is unwrapped here
// Switch with type matching
switch (let v = value.(type)) {
case int:
println("integer");
case string:
println("string");
default:
println("other");
}
// For loops
for (let i in 0..10) { // Range
println(`${i}`);
}
for (let item in array) { // Array
println(item);
}
for (let k, v in map) { // Map
println(`${k}: ${v}`);
}
Concurrency Basics
use std.time;
fn main() throws {
let ch = channel::<int>();
// Spawn concurrent task (not parallel - single thread)
spawn {
time.sleep(0.1.seconds());
try! ch.send(42);
}
let result = try ch.recv();
println(`${result}`);
}
Worker Pattern
use std.worker.Worker;
fn main() throws {
// Create worker with closure
let worker = try Worker.create(|worker| {
let msg = try worker.recv::<string>()!;
try worker.send(msg.to_uppercase());
});
try worker.send("hello");
let response = try worker.recv::<string>();
println(response); // "HELLO"
}
Navi Stream Integration
use nvs.macd; // Import .nvs file as module
fn main() throws {
// Create instance of NVS indicator
let indicator = macd.new();
// Execute with market data
indicator.execute(
time: 1234567890,
open: 100.0,
high: 105.0,
low: 99.0,
close: 103.0,
volume: 1000.0,
turnover: 100000.0
);
// Access exported variables
println(`hist=${indicator.hist:?}`);
println(`signal=${indicator.signal:?}`);
println(`macd=${indicator.macd:?}`);
}
Variadic Arguments
// Accept arbitrary number of arguments
fn sum(values: ..int): int {
let total = 0;
for (let n in values) {
total += n;
}
return total;
}
sum(1, 2, 3); // Call with multiple args
let nums = [2, 3, 4];
sum(..nums); // Spread array
sum(1, ..nums, 5); // Mix regular and spread
// With other parameters
fn format(prefix: string, parts: ..string): string {
return prefix + parts.join(",");
}
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md' && test -s '.skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/navi' && cp -R '.skill-downloads/navi-programming-language-expert-mm5t89c4' '.claude/skills/navi'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/navi-programming-language-expert-mm5t89c4'openskills read 'navi-programming-language-expert-mm5t89c4'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/navi-programming-language-expert-mm5t89c4/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.