Starlight Programming Language
Official documentation for the Starlight programming language.

Starlight is a lightweight, modern scripting language designed for server-side scripting, CLI tools, and automation.
It focuses on simplicity, readable syntax, and practical features for everyday programming. starlight-cli was officially released on December 14 2025.
Install the Starlight CLI via npm:
npm install -g starlight-cli
Verify installation:
starlight --version
Create a file:
program.sl
Run it:
starlight program.sl
let nums = range(0, 12, 2);
sldeploy nums;
if (len(nums) > 5) {
sldeploy "Array has more than 5 elements";
}
Output:
[ 2, 4, 6, 8, 10 ]
Array has more than 5 elements
Full documentation is organized in the docs/ folder:
docs/getting-started.mddocs/syntax.mddocs/control-flow.mddocs/functions.mddocs/modules.mddocs/built-in-functions.mddocs/error-handling.mddocs/cli.mdStarlight is built to be:
MIT License © Dominex Macedon
Name: Dominex Macedon
Date of Birth: March 21, 2006 (the same day as the first tweet)
Mother: Daw Thet Thet Maw
Father: U Kyaw Moe
From an early age, I was fascinated by technology and problem-solving. My journey started with a simple goal: to make my father's job easier. Observing his work, I realized that customers often had to meet him in person to submit items, which was time-consuming. I wanted to create a solution that would allow customers to communicate and submit requests without physically visiting him.
This led me to develop a local chat system using MySQL, PHP, HTML, and CSS. The project was small but significant. I immediately understood that if a group of people could contact a single person, I could build a one-to-one chat interface. I implemented it, and it worked, marking my first success in building functional communication systems.
After creating the local chat system, I expanded my skills into web development. Using GitHub, I hosted projects and began experimenting with website creation and deployment. These early experiences helped me understand version control, collaboration, and project management in real-world software development.
Later, I ventured into Android development and built a messaging app called Falcon S. This project used Android Studio, Firebase Auth, Realtime DB, Firestore, and Storage. The journey was challenging:
Through persistence, I successfully built the app, gaining deep experience in mobile application architecture, authentication, and real-time data management.
To expand communication tools, I developed a video call room similar to Zoom:
This project tested my ability to integrate cross-platform systems and manage real-time communication at scale.
Next, I attempted to create a rendering engine to render views directly from JSON. Though this project ultimately failed, it taught me valuable lessons about design systems, parsing, and dynamic UI rendering.
Afterwards, I moved to React Native and Expo, successfully rebuilding a messaging app with a CSS-like stylesheet design. This solidified my understanding of cross-platform mobile development and modern UI frameworks.
Finally, my experiences led me to develop the Starlight Programming Language. Starlight is based on the rendering engine concept I had explored earlier, combining ideas from my web, mobile, and desktop projects to create a language that is flexible, interactive, and user-friendly.
My work with Starlight continues to evolve, reflecting my passion for communication systems, rendering engines, and innovative programming tools.
Throughout my journey:
I am Dominex Macedon, a developer, innovator, and creator, dedicated to building tools that make communication seamless and intuitive.
Starlight is a high-level scripting language designed to be simple, expressive, and versatile. It combines the flexibility of dynamic typing with familiar programming structures.
let.fetch and sleep.Use let to declare a variable:
let name = "Alice"
let age = 25
let isStudent = true
Variables can hold any type of value, and the type can change dynamically:
let data = 10
data = "Now I'm a string"
Starlight has several core types:
42, 3.14, -7"Hello, world!"true, false[1, 2, 3], [ "a", "b" ]{ "key": "value", "num": 10 }(x) => x * 2 or named function declarationsnull (no value)+, -, *, /, %==, !=, <, <=, >, >=and, or, not, ?? (nullish coalescing)=, +=, -=, *=, /=, %=if age >= 18 {
let status = "Adult"
} else {
let status = "Minor"
}
for let i = 0; i < 5; i++ {
# do something
}
let numbers = [1, 2, 3]
for num in numbers {
# iterate over array
}
while loops:let count = 0
while count < 5 {
count += 1
}
Functions can be declared or assigned to variables:
let greet = (name) => "Hello " + name
let result = greet("Alice") # "Hello Alice"
Named function declaration:
define sayHi(name) {
"Hi " + name
}
print(value) — output to consolelen(value) — get length of array, string, or objectkeys(obj) — get object keysvalues(obj) — get object valuesmap(array, fn) — transform arrayfilter(array, fn) — filter arrayreduce(array, fn, initial) — reduce array to a single valueask(prompt) — get user inputsleep(ms) — pause executionStarlight is designed to be readable, flexible, and powerful, while keeping syntax simple and natural.
starlight is a simple programming language designed to be easy to learn and fun to use.
to run a file, use:
starlight filename.sl
to view a markdown file:
starlight filename.md
let name = "alice"
let age = 16
let is_student = true
sldeploy name
sldeploy age
sldeploy is_student
starlight supports:
"hello"123, 3.14true, false[1, 2, 3]{ key: "value" }func hello() { ... }let a = 10
let b = 5
sldeploy a + b
sldeploy a - b
sldeploy a * b
sldeploy a / b
sldeploy a % b
let t = true
let f = false
# if statement
if a > b {
sldeploy "a is greater"
} else {
sldeploy "b is greater or equal"
}
# while loop
let i = 0
while i < 3 {
sldeploy i
i += 1
}
# for loop
for let j = 0; j < 3; j += 1 {
sldeploy j
}
func greet(name) {
sldeploy "hello " + name
}
greet("bob")
# arrow functions
let square = (x) => x * x
sldeploy square(5)
func getData(url) async {
let res = await fetch(url)
let data = await res.json()
return data
}
let info = await getData("https://jsonplaceholder.typicode.com/todos/1")
sldeploy info
use sldeploy to output values:
let message = "hello world"
sldeploy message
it can display numbers, strings, booleans, arrays, objects, and functions.
this guide will help you get starlight up and running on your system.
to install starlight globally so you can run it from anywhere:
npm install -g starlight-cli@latest
after installation, check the version:
starlight --version
you should see something like:
starlight cli v1.1.7
developed by macedon
once installed, you can run a starlight file like this:
starlight myprogram.sl
or view a markdown file directly:
starlight guide.md
if you ever need to remove starlight:
npm uninstall -g starlight-cli
This is a quick reference for the core syntax and constructs of your language.
let x = 10;
let name = "Alice";
let declares a new variable.define PI = 3.14159;
define greeting = "Hello!";
define creates a variable that persists globally.123, 3.14"Hello", 'World'true, falsenull[1, 2, 3]{ key: "value", num: 42 }a + b
a - b
a * b
a / b
a % b
x = 5;
x += 3; // x = x + 3
x -= 2;
x *= 2;
x /= 4;
x %= 2;
a == b
a != b
a < b
a <= b
a > b
a >= b
a && b // AND
a || b // OR
a ?? b // Nullish coalescing
!a // NOT
if (x > 0) {
sldeploy("Positive");
} else if (x < 0) {
sldeploy("Negative");
} else {
sldeploy("Zero");
}
while (x < 5) {
sldeploy(x);
x += 1;
}
for (let i = 0; i < 5; i += 1) {
sldeploy(i);
}
for (let key in obj) {
sldeploy(key);
}
do {
sldeploy(10 / 0);
} track {
sldeploy(error); // error contains the exception
}
func add(a, b) {
return a + b;
}
sldeploy(add(2, 3)); // 5
async func fetchData(url) {
let response = await get(url);
return response;
}
let square = x => x * x;
sldeploy(square(5)); // 25
start score {
race 100 {
sldeploy("Perfect!");
}
race 50 {
sldeploy("Halfway there!");
}
race 0 {
sldeploy("Try again!");
}
}
start evaluates a value.race defines possible matches.let nums = [1, 2, 3];
sldeploy(nums[0]); // 1
let person = { name: "Alice", age: 20 };
sldeploy(person.name); // Alice
import { func1, func2 } from "utils.sl";
import * as utils from "utils.sl";
import defaultFunc from "utils.sl";
sldeploy(value) → prints a value to the consolelen(array|string|object) → returns the lengthtype(value) → returns the typemap(array, fn), filter(array, fn), reduce(array, fn, initial)keys(obj), values(obj)range(start, end, step) → generates an array of numbersask(prompt) → gets user inputnum(value) → converts to numberstr(value) → converts to stringsleep(ms) → delays executionfetch(url) / get(url) / post(url, data) → HTTP requestsobj.key
obj["key"]
myFunc(1, 2);
let obj = new MyClass(arg1, arg2);
x++;
--y;
obj.value++;
arr[0]--;
This document covers all major syntax elements in your language, with sldeploy as the primary output mechanism.
Variables are containers for storing data. They can hold numbers, strings, arrays, objects, or functions.
let – block-scoped variablelet x = 10;
let name = "Alice";
x = 20;
name = "Bob";
define – global or constant-like variabledefine PI = 3.14159;
define greeting = "Hello!";
define in the same scope, it updates the value.Variables can hold different types of values:
| Type | Example |
|---|---|
| Number | let age = 25; |
| String | let name = "Alice"; |
| Boolean | let isActive = true; |
| Null | let empty = null; |
| Array | let arr = [1, 2, 3]; |
| Object | let obj = { key: "value" }; |
let): Visible only inside the block it was defined.if (true) {
let x = 5;
}
sldeploy(x); // Error: undefined variable
define): Accessible from anywhere.define y = 10;
if (true) {
sldeploy(y); // 10
}
func test() {
let localVar = 42;
sldeploy(localVar); // 42
}
sldeploy(localVar); // Error: undefined variable
Variables can change types after assignment:
let x = 10;
sldeploy(x); // 10
x = "hello";
sldeploy(x); // "hello"
let a = 5;
sldeploy(a); // 5
let person = { "name": "Alice", "age": 20 };
sldeploy(person.name); // "Alice"
let nums = [1, 2, 3];
sldeploy(nums[0]); // 1
let for most variables.define for global or constant values.This covers everything about variables: declaration, types, scope, and access.
starlight supports standard data types including numbers, strings, booleans, arrays, objects, functions, and null (none).
let a = 10
let b = 3.14
let c = -5
sldeploy a
sldeploy b
sldeploy c
+, -, *, /, %.let str1 = "hello"
let str2 = 'world'
let str3 = str1 + " " + str2
sldeploy str1
sldeploy str3
".+.let t = true
let f = false
sldeploy t
sldeploy f
let n = null
let u = undefined
sldeploy n
sldeploy u
null is none.undefined appears when variables are declared but not assigned.let arr = [1, 2, 3]
let empty = []
sldeploy arr
sldeploy arr[0]
sldeploy len(arr)
let obj = {name: "alice", age: 20}
sldeploy obj.name
sldeploy obj["age"]
sldeploy keys(obj)
sldeploy values(obj)
obj.key or index obj["key"].func add(a, b) {
return a + b
}
let result = add(5, 7)
sldeploy result
let arrow = (x, y) => x * y
sldeploy arrow(3, 4)
func name(params) {}.(params) => expr return the expression value.sldeploy type(10)
sldeploy type("hello")
sldeploy type([1,2,3])
sldeploy type({"a":1})
sldeploy type(add)
sldeploy type(null)
number, string, array, object, function, or boolean.sldeploy for output, len() for array or string length.starlight provides standard control flow statements like if, else, while, for, for-in, break, continue, and custom start/race/do and track for advanced flow control.
let x = 10
if x > 5 {
sldeploy "x is greater than 5"
} else {
sldeploy "x is 5 or less"
}
if requires a boolean condition.else is optional.let count = 0
while count < 3 {
sldeploy count
count += 1
}
break to exit early, continue to skip to next iteration.for let i = 0; i < 3; i += 1 {
sldeploy i
}
for loop with initializer, test, and update.break and continue.let arr = [10, 20, 30]
for val in arr {
sldeploy val
}
let obj = {a: 1, b: 2}
for key in obj {
sldeploy key
}
val or key is dynamically assigned each iteration.let i = 0
while true {
i += 1
if i == 3 {
break
}
if i == 1 {
continue
}
sldeploy i
}
break exits the nearest loop.continue skips the rest of the current iteration.let choice = "b"
start choice {
race "a" {
sldeploy "you chose a"
}
race "b" {
sldeploy "you chose b"
}
race "c" {
sldeploy "you chose c"
}
}
start evaluates a discriminant.race clause.break inside a race stops executing further races.do {
let x = 10 / 0
} track {
sldeploy "error caught"
}
sldeploy is used for output instead of print.start / race / do and track are unique to starlight for choice and error handling.# functions in starlight
# defining a function
func greet(name) {
sldeploy "hello " + name
}
# calling a function
greet("alice")
# function returning a value
func add(a, b) {
return a + b
}
let sum = add(5, 7)
sldeploy sum
# arrow functions (inline)
let multiply = (x, y) => x * y
sldeploy multiply(3, 4)
# arrow function with block
let divide = (a, b) => {
if b == 0 {
return "cannot divide by zero"
}
return a / b
}
sldeploy divide(10, 2)
sldeploy divide(10, 0)
# functions can be assigned to variables
let fn = greet
fn("bob")
# functions can be passed as arguments
func applyFn(fn, value) {
return fn(value)
}
let result = applyFn((x) => x * 2, 8)
sldeploy result
# async functions
func asyncFetch(url) async {
let response = await fetch(url)
let data = await response.json()
return data
}
# calling async function
let data = await asyncFetch("https://jsonplaceholder.typicode.com/todos/1")
sldeploy data
✅ key points:
func name(params) { ... } defines a functionreturn sends a value back(params) => expr or (params) => { ... } are supportedasync functions support await for promises or async taskssldeploy is used for output instead of printArrays in SL are ordered collections of values. They can contain any type, including numbers, strings, booleans, objects, other arrays, and even functions.
let nums = [1, 2, 3, 4, 5];
let names = ["Alice", "Bob", "Charlie"];
let mixed = [1, "two", true, null];
let nested = [[1, 2], [3, 4]];
Array elements are accessed using zero-based indices:
sldeploy nums[0]; # 1
sldeploy names[1]; # "Bob"
sldeploy nested[1][0]; # 3
If the index is out of bounds, SL returns undefined:
sldeploy nums[10]; # undefined
You can assign new values to existing indices:
nums[0] = 42;
names[2] = "Charlie Brown";
sldeploy nums; # [42, 2, 3, 4, 5]
sldeploy names; # ["Alice", "Bob", "Charlie Brown"]
Arrays can grow dynamically by assigning to new indices:
nums[5] = 6;
sldeploy nums; # [42, 2, 3, 4, 5, 6]
SL supports iteration and higher-order functions:
let nums = [1, 2, 3, 4];
# Map: apply a function to each element
let squared = await map(nums, (x) => x * x);
sldeploy squared; # [1, 4, 9, 16]
# Filter: select elements
let evens = await filter(nums, (x) => x % 2 == 0);
sldeploy evens; # [2, 4]
# Reduce: accumulate values
let sum = await reduce(nums, (a, b) => a + b, 0);
sldeploy sum; # 10
for loopsfor (let i = 0; i < nums.length; i++) {
sldeploy nums[i];
}
for-in loopsfor n in nums {
sldeploy n;
}
len(array) — returns the length of the array:sldeploy len(nums); # 4
map(array, fn) — returns a new array with each element transformed by fn.filter(array, fn) — returns a new array containing elements where fn returns true.reduce(array, fn, initial) — reduces the array to a single value using fn.Arrays can be nested or concatenated manually:
let a = [1, 2];
let b = [3, 4];
let c = [a[0], a[1], b[0], b[1]];
sldeploy c; # [1, 2, 3, 4]
map, filter, reduce.len() to get the number of elements.undefined.Objects are collections of key-value pairs. They are similar to dictionaries or maps in other languages. Keys can be strings, numbers, or expressions, and values can be any type, including other objects or functions.
Objects are created using let with curly braces {}:
let myObj = {
"name": "Alice",
"age": 25,
"isStudent": true
}
Keys must be unique within an object. Values can be literals, arrays, functions, or even other objects.
Properties of an object can be accessed using dot notation or bracket notation:
let name = myObj.name
let age = myObj["age"]
You can also assign new values to existing properties:
myObj.age = 26
myObj["isStudent"] = false
New properties can be added dynamically:
myObj.grade = "A"
Objects can contain other objects:
let person = {
"name": "Bob",
"address": {
"city": "New York",
"zip": "10001"
}
}
let city = person.address.city
You can iterate over objects using a for-in loop. This iterates over the keys:
for key in person {
let value = person[key]
}
You can also use built-in functions:
let keysList = keys(person) # ["name", "address"]
let valuesList = values(person) # ["Bob", { "city": "New York", "zip": "10001" }]
Objects can hold functions as values:
let calculator = {
"add": (a, b) => a + b,
"subtract": (a, b) => a - b
}
let sum = calculator.add(5, 3) # 8
let difference = calculator["subtract"](10, 4) # 6
Functions inside objects behave like normal functions but can also access the object if this is used.
. or bracket [].for-in or use keys and values.Modules in Starlight allow you to organize code into separate files and reuse functionality across programs. They help keep your code clean, maintainable, and modular.
Use the import statement to include another module in your program. You can import specific exports, the default export, or the entire module as a namespace.
import fs from "./fileUtils.sl"
let content = fs.readFile("data.txt")
import { readFile, writeFile } from "./fileUtils.sl"
let content = readFile("data.txt")
writeFile("output.txt", content)
import * as fs from "./fileUtils.sl"
let content = fs.readFile("data.txt")
In Starlight, everything defined in a file can be exported and used in other modules.
define greet(name) {
"Hello " + name
}
define farewell(name) {
"Goodbye " + name
}
You can then import these functions using a named import:
import { greet, farewell } from "./messages.sl"
let msg = greet("Alice") # "Hello Alice"
let bye = farewell("Bob") # "Goodbye Bob"
To export the entire module as a default:
let defaultExport = {
greet: greet,
farewell: farewell
}
And import it like this:
import messages from "./messages.sl"
let msg = messages.greet("Alice")
Starlight can import Node.js modules or packages installed via npm:
import fs from "fs"
let data = fs.readFileSync("data.txt", "utf-8")
If a module cannot be found, Starlight will throw a RuntimeError with a suggestion if a similar name exists.
Modules in Starlight make it easy to split large programs into manageable pieces while maintaining clean and reusable code.
your language supports asynchronous programming using async functions and the await keyword. this allows you to write non-blocking code that reads like normal synchronous code.
use the async func syntax to define an asynchronous function:
async func fetchdata(url) {
let response = await fetch(url);
let data = await response.json();
return data;
}
async func marks the function as asynchronous.async function, you can use await to pause execution until a promise-like operation completes.awaitawait can be used with any async operation:
async func main() {
let user = await get('https://api.example.com/user/1');
sldeploy user;
}
main(); // calling an async function
await can only be used inside async functions.await until the operation resolves.do…trackuse do…track to catch errors from async operations:
async func loaddata() {
do {
let data = await fetch('https://api.example.com/data');
sldeploy await data.json();
} track {
sldeploy 'an error occurred:', error;
}
}
do contains the code that might fail.track handles errors; the error variable holds the exception.you can run multiple async calls sequentially:
async func process() {
let a = await fetch('https://api.example.com/a');
let b = await fetch('https://api.example.com/b');
sldeploy [await a.json(), await b.json()];
}
or process arrays asynchronously:
async func processusers(users) {
let results = await map(users, async (u) => {
let res = await fetch(`https://api.example.com/user/${u.id}`);
return await res.json();
});
sldeploy results;
}
map, filter, and reduce are fully async-aware.await async callbacks to maintain proper sequence.async arrow functions work with await:
let fetchuser = async (id) => {
let response = await fetch(`https://api.example.com/user/${id}`);
return await response.json();
};
async func run() {
let user = await fetchuser(1);
sldeploy user;
}
run();
you can use async functions inside loops:
async func loopfetch(users) {
for let u in users {
let data = await fetch(`https://api.example.com/user/${u}`);
sldeploy await data.json();
}
}
or using for…in over objects:
async func objloop(obj) {
for let key in obj {
let val = await obj[key];
sldeploy key, val;
}
}
you can pause execution asynchronously:
async func countdown(n) {
for let i = n; i > 0; i-- {
sldeploy i;
await sleep(1000); // pause 1 second
}
sldeploy 'done!';
}
await.await gives a "function object" (like a promise).async func main() {
let data = await fetchdata('https://api.example.com');
sldeploy data;
}
main();
you can combine loops, async, and do…track:
async func safefetch(users) {
for let u in users {
do {
let res = await fetch(`https://api.example.com/user/${u}`);
sldeploy await res.json();
} track {
sldeploy 'failed to fetch user', u, ':', error;
}
}
}
| feature | syntax example | notes |
|---|---|---|
| async function | async func name(params) { … } |
use await inside |
| await expression | let x = await asynccall() |
only inside async |
| async arrow function | let fn = async (params) => … |
can be single-expression or block |
| error handling | do { … } track { … } |
error variable holds exception |
| async loops | for let x in array { await … } |
handles async correctly |
| async utilities | map, filter, reduce |
fully async-aware |
| sleep / delay | await sleep(ms) |
pauses execution asynchronously |
starlight comes with a command line interface (cli) to run code, open learning guides, and work interactively.
starlight <file.sl> # run a starlight source file
starlight <file.md> # view a markdown file directly in browser
starlight --version # show cli version
starlight --help # show help
starlight --learn # open learning guide
starlight --writedirectly # interactive editor mode
-v or --version
show starlight cli version.
--help
display all available commands and usage.
--learn
opens the official starlight learning guide in your browser.
--writedirectly
opens an interactive editor for writing starlight code directly in the terminal.
to run a .sl file:
starlight myscript.sl
to view a markdown file directly:
starlight guide.md
--writedirectly):run to execute the code.let x = 5
let y = 10
sldeploy x + y # outputs 15
:run, your code is evaluated immediately..sl extension is added automatically if missing.starlight <file.sl>.| command | action |
|---|---|
starlight <file.sl> |
run a starlight source file |
starlight <file.md> |
view a markdown file directly in browser |
starlight --version |
show cli version |
starlight --help |
show this help guide |
starlight --learn |
open learning guide in browser |
starlight --writedirectly |
interactive editor with immediate evaluation and optional save |
A lightweight math utility library for JavaScript and Starlight, providing constants, functions, and basic vector/matrix operations.
Install via npm:
npm install starlight-math@latest
For both JavaScript and Starlight:
import math from "starlight-math";
console.log(math.pi); // 3.141592653589793
console.log(math.e); // 2.718281828459045
console.log(math.phi); // 1.61803398875
Starlight:
sldeploy(math.pi);
sldeploy(math.e);
sldeploy(math.phi);
console.log(math.abs(-5)); // 5
console.log(math.sqrt(16)); // 4
console.log(math.pow(2, 3)); // 8
console.log(math.round(4.6)); // 5
console.log(math.floor(4.9)); // 4
console.log(math.ceil(4.1)); // 5
console.log(math.max(1,2,3)); // 3
console.log(math.min(1,2,3)); // 1
Starlight:
sldeploy(math.abs(-5));
sldeploy(math.sqrt(16));
sldeploy(math.pow(2, 3));
sldeploy(math.round(4.6));
sldeploy(math.floor(4.9));
sldeploy(math.ceil(4.1));
sldeploy(math.max([1,2,3])); // pass array instead of arguments if needed
sldeploy(math.min([1,2,3]));
console.log(math.sin(Math.PI/2)); // 1
console.log(math.cos(0)); // 1
console.log(math.tan(Math.PI/4)); // 1
console.log(math.asin(1)); // 1.5707963267948966
console.log(math.acos(0)); // 1.5707963267948966
console.log(math.atan(1)); // 0.7853981633974483
console.log(math.atan2(1, 1)); // 0.7853981633974483
Starlight:
sldeploy(math.sin(math.pi / 2));
sldeploy(math.cos(0));
sldeploy(math.tan(math.pi / 4));
sldeploy(math.asin(1));
sldeploy(math.acos(0));
sldeploy(math.atan(1));
sldeploy(math.atan2(1,1));
console.log(math.log(10)); // natural log
console.log(math.log10(100));// base 10
console.log(math.log2(8)); // base 2
Starlight:
sldeploy(math.log(10));
sldeploy(math.log10(100));
sldeploy(math.log2(8));
console.log(math.random()); // random between 0 and 1
console.log(math.random(5, 10)); // random between 5 and 10
Starlight:
sldeploy(math.random());
sldeploy(math.random(5, 10));
console.log(math.factorial(5)); // 120
console.log(math.nCr(5, 2)); // 10
console.log(math.nPr(5, 2)); // 20
Starlight:
sldeploy(math.factorial(5));
sldeploy(math.nCr(5, 2));
sldeploy(math.nPr(5, 2));
const v1 = [1,2,3];
const v2 = [4,5,6];
console.log(math.vectorAdd(v1, v2)); // [5,7,9]
console.log(math.vectorSub(v1, v2)); // [-3,-3,-3]
console.log(math.vectorDot(v1, v2)); // 32
console.log(math.vectorCross(v1, v2)); // [-3,6,-3]
Starlight:
sldeploy(math.vectorAdd([1,2,3], [4,5,6]));
sldeploy(math.vectorSub([1,2,3], [4,5,6]));
sldeploy(math.vectorDot([1,2,3], [4,5,6]));
sldeploy(math.vectorCross([1,2,3], [4,5,6]));
const A = [[1,2],[3,4]];
const B = [[5,6],[7,8]];
console.log(math.matrixAdd(A, B)); // [[6,8],[10,12]]
console.log(math.matrixSub(A, B)); // [[-4,-4],[-4,-4]]
console.log(math.matrixTranspose(A)); // [[1,3],[2,4]]
Starlight:
sldeploy(math.matrixAdd([[1,2],[3,4]], [[5,6],[7,8]]));
sldeploy(math.matrixSub([[1,2],[3,4]], [[5,6],[7,8]]));
sldeploy(math.matrixTranspose([[1,2],[3,4]]));
✅ Notes:
sldeploy() instead of print() for output.A simple file system utility for JavaScript and Starlight, providing convenient methods for reading, writing, copying, deleting files and directories, as well as path utilities.
Install via npm:
npm install starlight-fs@latest
For both JavaScript and Starlight:
import fs from "starlight-fs";
const content = fs.readFile("example.txt");
console.log(content);
Starlight:
sldeploy(fs.readFile("example.txt"));
fs.writeFile("example.txt", "Hello Starlight!");
Starlight:
fs.writeFile("example.txt", "Hello Starlight!");
fs.appendFile("example.txt", "\nAppended line");
Starlight:
fs.appendFile("example.txt", "\nAppended line");
const data = fs.readJSON("data.json");
fs.writeJSON("data.json", { name: "Starlight", version: 1 });
Starlight:
sldeploy(fs.readJSON("data.json"));
fs.writeJSON("data.json", { name: "Starlight", version: 1 });
fs.deleteFile("example.txt");
Starlight:
fs.deleteFile("example.txt");
console.log(fs.exists("example.txt")); // true or false
Starlight:
sldeploy(fs.exists("example.txt"));
fs.makeDir("myFolder");
Starlight:
fs.makeDir("myFolder");
console.log(fs.listDir("myFolder"));
Starlight:
sldeploy(fs.listDir("myFolder"));
fs.deleteDir("myFolder");
Starlight:
fs.deleteDir("myFolder");
fs.copyFile("source.txt", "dest.txt");
fs.copyDir("srcFolder", "destFolder");
Starlight:
fs.copyFile("source.txt", "dest.txt");
fs.copyDir("srcFolder", "destFolder");
console.log(fs.join("folder", "file.txt")); // "folder/file.txt"
console.log(fs.basename("/path/to/file.txt")); // "file.txt"
console.log(fs.dirname("/path/to/file.txt")); // "/path/to"
console.log(fs.extname("file.txt")); // ".txt"
console.log(fs.resolve("folder", "file.txt"));
console.log(fs.relative("/a/b", "/a/b/c/d")); // "c/d"
Starlight:
sldeploy(fs.join("folder", "file.txt"));
sldeploy(fs.basename("/path/to/file.txt"));
sldeploy(fs.dirname("/path/to/file.txt"));
sldeploy(fs.extname("file.txt"));
sldeploy(fs.resolve("folder", "file.txt"));
sldeploy(fs.relative("/a/b", "/a/b/c/d"));
sldeploy() in Starlight for printing outputs instead of console.log().copyDir and deleteDir handle nested directories automatically.A simple time and date utility library for JavaScript and Starlight, providing current time, formatting, timers, and sleep functionality.
Install via npm:
npm install starlight-time@latest
For both JavaScript and Starlight:
import time from "starlight-time";
console.log(time.now()); // Current date object
console.log(time.formatDate()); // e.g., "2026-01-12"
console.log(time.formatTime()); // e.g., "14:35:42"
Starlight:
sldeploy(time.now());
sldeploy(time.formatDate());
sldeploy(time.formatTime());
console.log("Start");
time.sleep(1000); // Sleep for 1 second
console.log("End");
Starlight:
sldeploy("Start");
time.sleep(1000);
sldeploy("End");
⚠ Note:
sleepin this version is blocking. Use carefully in loops.
const stop = time.setTimer(() => console.log("Tick"), 1000); // every 1 second
setTimeout(() => {
stop(); // stop after 5 seconds
console.log("Timer stopped");
}, 5000);
Starlight:
const stop = time.setTimer(() => sldeploy("Tick"), 1000);
setTimeout(() => {
stop();
sldeploy("Timer stopped");
}, 5000);
In Starlight,
sldeploy()is used instead ofprint().
console.log(time.secondsToHMS(3661)); // "01:01:01"
console.log(time.secondsToHMS(59)); // "00:00:59"
Starlight:
sldeploy(time.secondsToHMS(3661));
sldeploy(time.secondsToHMS(59));
setInterval.sldeploy() in Starlight for output instead of console.log().sleep blocks the main thread. For async/non-blocking delays, consider using await sleepAsync(ms) (you could add a Promise-based sleep).starlight-color is a simple library for styling console text using ANSI escape codes. You can apply colors, background colors, and text styles like bold, underline, italic, and more.
npm install starlight-color@latest
import { colors, bgColors, styles, style } from 'starlight-color';
The import line is the same in both JavaScript and Starlight.
import { colors, bgColors, styles, style } from 'starlight-color';
// Basic colors
console.log(colors.red("This is red text"));
console.log(colors.cyan("This is cyan text"));
// Background colors
console.log(bgColors.yellow("Yellow background"));
console.log(bgColors.brightBlue("Bright blue background"));
// Styles
console.log(styles.bold("Bold text"));
console.log(styles.underline("Underlined text"));
// Combined styling
console.log(style("Green bold underlined text", { color: "green", bold: true, underline: true }));
// 256-color support
console.log(style("Custom foreground 202", { fg256: 202 }));
console.log(style("Custom background 120", { bg256: 120 }));
In Starlight, use
sldeploy()instead ofconsole.log()to output styled text.
import { colors, bgColors, styles, style } from 'starlight-color';
sldeploy(colors.red("This is red text"));
sldeploy(bgColors.yellow("Yellow background"));
sldeploy(styles.bold("Bold text"));
sldeploy(style("Green bold underlined text", { "color": "green", "bold": true, "underline": true }));
sldeploy(style("Custom foreground 202", { "fg256": 202 }));
sldeploy(style("Custom background 120", { "bg256": 120 }));
colors.black(text)
colors.red(text)
colors.green(text)
colors.yellow(text)
colors.blue(text)
colors.magenta(text)
colors.cyan(text)
colors.white(text)
colors.gray(text)
colors.brightRed(text)
colors.brightGreen(text)
colors.brightYellow(text)
colors.brightBlue(text)
colors.brightMagenta(text)
colors.brightCyan(text)
colors.brightWhite(text)
colors.fg256(n, text) // 256-color foreground
bgColors.black(text)
bgColors.red(text)
bgColors.green(text)
bgColors.yellow(text)
bgColors.blue(text)
bgColors.magenta(text)
bgColors.cyan(text)
bgColors.white(text)
bgColors.brightBlack(text)
bgColors.brightRed(text)
bgColors.brightGreen(text)
bgColors.brightYellow(text)
bgColors.brightBlue(text)
bgColors.brightMagenta(text)
bgColors.brightCyan(text)
bgColors.brightWhite(text)
bgColors.bg256(n, text) // 256-color background
styles.bold(text)
styles.dim(text)
styles.italic(text)
styles.underline(text)
styles.inverse(text)
styles.hidden(text)
styles.strikethrough(text)
style(text, {
color, // text color
bg, // background color
bold, dim, italic, underline, inverse, hidden, strike,
fg256, bg256 // 256-color support
})
console.log() to print styled text.sldeploy() for output.style().A utility to convert TXT files to PDF with text formatting, headers, footers, colors, bold/italic styles, and image embedding. Works in both JavaScript and Starlight.
Install via npm:
npm install starlight-txt-to-pdf@latest
For both JavaScript and Starlight:
import { txtToPdf } from "starlight-txt-to-pdf";
import { txtToPdf } from "starlight-txt-to-pdf";
(async () => {
try {
const output = await txtToPdf("letter.txt", "letter.pdf", {
header: "My PDF Document 💌"
});
console.log("PDF saved to:", output);
} catch (err) {
console.error("Error generating PDF:", err.message);
}
})();
[color:red]Hello[/color].[b]Bold[/b], [i]Italic[/i].[pos:x,y]Text[/pos].[img:path/to/image.png,x=100,y=200,w=150,h=150].import { txtToPdf } from "starlight-txt-to-pdf";
await txtToPdf("letter.txt", "letter.pdf", { header: "My PDF Document 💌" });
sldeploy("PDF generated: letter.pdf");
# My Love Letter 💖
[color:red][b]Dear Alice,[/b][/color]
I hope this letter finds you well.
## Memories
[i]Remember the day we first met?[/i]
[img:heart.png,x=200,y=500,w=100,h=100]
[img:...] tag.[pos:x,y]Text[/pos] for custom coordinates.await in Starlight or JS."Love Letter 💖" if none is provided.red, green, blue, yellow, cyan, magenta, gray, white, black.A simple Wikipedia API wrapper for fetching search results, summaries, full content, images, categories, and languages. Works in JavaScript and Starlight.
Install via npm:
npm install wiki-starlight-api@latest
For both JavaScript and Starlight:
import * as wiki from "wiki-starlight-api";
import * as wiki from "wiki-starlight-api";
(async () => {
// Search articles
const results = await wiki.search("JavaScript", 5);
console.log("Search results:", results);
// Get summary of an article
const jsSummary = await wiki.summary("JavaScript");
console.log(jsSummary);
// Get full page content
const jsPage = await wiki.page("JavaScript");
console.log(jsPage.content);
// Get a random article
const randomArticle = await wiki.random();
console.log(randomArticle);
// Get article languages
const langs = await wiki.languages("JavaScript");
console.log("Available languages:", langs);
// Get article images
const imgs = await wiki.images("JavaScript");
console.log("Images:", imgs);
// Get article categories
const cats = await wiki.categories("JavaScript");
console.log("Categories:", cats);
// Search and get summaries
const summaries = await wiki.searchAndSummary("Python", 3);
console.log(summaries);
})();
import * as wiki from "wiki-starlight-api";
// Search articles
const results = await wiki.search("JavaScript", 5);
sldeploy("Search results:\n" + results);
// Get summary
const jsSummary = await wiki.summary("JavaScript");
sldeploy("JavaScript summary:\n" + jsSummary.extract);
// Get full page content
const jsPage = await wiki.page("JavaScript");
sldeploy(jsPage.content);
// Get random article
const randomArticle = await wiki.random();
sldeploy("Random article:\n" + randomArticle.title + "\n" + randomArticle.extract);
// Get article languages
const langs = await wiki.languages("JavaScript");
sldeploy("Languages: " + langs.map(l => l.lang + " → " + l.title).join(", "));
// Get images
const imgs = await wiki.images("JavaScript");
sldeploy("Images: " + imgs.join(", "));
// Get categories
const cats = await wiki.categories("JavaScript");
sldeploy("Categories: " + cats.join(", "));
// Search and get summaries
const summaries = await wiki.searchAndSummary("Python", 3);
summaries.forEach(s => sldeploy(s.title + ": " + s.extract));
search(query, limit): Search Wikipedia articles.summary(title): Get article summary (intro).page(title): Get full article content as plain text.random(): Get a random article.languages(title): Get available translations for an article.images(title): Get images used in an article (PNG, JPG, JPEG, SVG, GIF).categories(title): Get categories of an article.searchAndSummary(query, limit): Search and return summaries for results.await in Starlight or JavaScript.This language is a JavaScript-inspired scripting language with custom keywords and syntax for tasks like asynchronous functions, tracking, deployments (sldeploy), and race conditions (start ... race).
It supports:
if, while, for, do...track, start...race)| Type | Syntax |
|---|---|
| Single-line | # comment |
| Multi-line | #* comment *# |
_)myVar, _temp1Reserved words cannot be used as identifiers.
let, sldeploy, if, else, while, for, break, continue,
func, return, true, false, null,
ask, define, import, from, as,
async, await, new, in, do, track, start, race
| Type | Example |
|---|---|
| Number | 42, 3.14 |
| String | "hello", 'hi' |
| Boolean | true, false |
| Null | null |
=, +=, -=, *=, /=, %=
+, -, *, /, %
==, !=, <, <=, >, >=
&&, ||, !, ??
++, --
=>, ->
( ) { } [ ] ; , : .
(expr)[expr1, expr2, ...]{ key: value, ... }await exprnew Constructor(args...)ask(expr...)+, -, !, ++, --
+ - * / %< <= > >= == !=&& || ??condition ? exprIfTrue : exprIfFalse
variable = expr
variable += expr
...
func(arg1, arg2)
obj.property
array[index]
(params) => expr or (params) -> expr(params) => { statements }let x = 5;
func foo(a, b) { ... }
async func bar() { ... }
if (condition) { ... } else { ... }
while (condition) { ... }
for (init; test; update) { ... }
for (let item in iterable) { ... }
do { ... } track { ... }
start expr {
race condition1 { ... }
race condition2 { ... }
}
return expr;
break;
continue;
Any expression can be a statement:
x + y;
ask("name");
Supports default, named, and namespace imports:
import foo from "module";
import { a, b as c } from "module";
import * as ns from "module";
{ ... }LexerError for invalid characters or unterminated strings/comments.ParseError for unexpected tokens or syntax errors.async func greet(name) {
let greeting = ask("Enter greeting:");
return greeting + ", " + name;
}
start event {
race ready { sldeploy greet("Alice"); }
race timeout { sldeploy "Timeout!"; }
}
These are recognized as special tokens and cannot be used as identifiers:
| Keyword | Token Type |
|---|---|
let |
LET |
sldeploy |
SLDEPLOY |
if |
IF |
else |
ELSE |
while |
WHILE |
for |
FOR |
break |
BREAK |
continue |
CONTINUE |
func |
FUNC |
return |
RETURN |
true |
TRUE |
false |
FALSE |
null |
NULL |
ask |
ASK |
define |
DEFINE |
import |
IMPORT |
from |
FROM |
as |
AS |
async |
ASYNC |
await |
AWAIT |
new |
NEW |
in |
IN |
do |
DO |
track |
TRACK |
start |
START |
race |
RACE |
| Literal Type | Token Type | Example |
|---|---|---|
| Number | NUMBER | 42, 3.14 |
| String | STRING | "hello", 'hi' |
| Boolean | TRUE/FALSE | true, false |
| Null | NULL | null |
| Symbol | Token Type |
|---|---|
= |
EQUAL |
+= |
PLUSEQ |
-= |
MINUSEQ |
*= |
STAREQ |
/= |
SLASHEQ |
%= |
MODEQ |
| Symbol | Token Type |
|---|---|
+ |
PLUS |
- |
MINUS |
* |
STAR |
/ |
SLASH |
% |
MOD |
| Symbol | Token Type |
|---|---|
== |
EQEQ |
!= |
NOTEQ |
< |
LT |
<= |
LTE |
> |
GT |
>= |
GTE |
| Symbol | Token Type | ||
|---|---|---|---|
&& |
AND | ||
! |
NOT | ||
?? |
NULLISH_COALESCING |
| Symbol | Token Type |
|---|---|
++ |
PLUSPLUS |
-- |
MINUSMINUS |
| Symbol | Token Type |
|---|---|
=> |
ARROW |
-> |
ARROW |
| Symbol | Token Type |
|---|---|
( |
LPAREN |
) |
RPAREN |
{ |
LBRACE |
} |
RBRACE |
[ |
LBRACKET |
] |
RBRACKET |
; |
SEMICOLON |
, |
COMMA |
: |
COLON |
. |
DOT |
| Type | Syntax |
|---|---|
| Single-line | # comment |
| Multi-line | #* comment *# |
\n, \t, \", \', \\.==, !=, <=, >=, &&, ||, ??, +=, etc.) are checked before single-character tokens.=> and ->.| Operator | Type | Notes |
|---|---|---|
+ |
Binary | Addition |
- |
Binary | Subtraction |
* |
Binary | Multiplication |
/ |
Binary | Division |
% |
Binary | Modulo |
+ |
Unary | Unary plus |
- |
Unary | Unary minus |
++ |
Unary | Increment (prefix/postfix) |
-- |
Unary | Decrement (prefix/postfix) |
| Operator | Type | Notes |
|---|---|---|
= |
Assignment | Assign value |
+= |
Compound Assignment | Add and assign |
-= |
Compound Assignment | Subtract and assign |
*= |
Compound Assignment | Multiply and assign |
/= |
Compound Assignment | Divide and assign |
%= |
Compound Assignment | Modulo and assign |
| Operator | Type | Notes |
|---|---|---|
== |
Binary | Equals |
!= |
Binary | Not equal |
< |
Binary | Less than |
<= |
Binary | Less than or equal |
> |
Binary | Greater than |
>= |
Binary | Greater than or equal |
| Operator | Type | Notes | ||
|---|---|---|---|---|
&& |
Binary | Logical AND | ||
| ` | ` | Binary | Logical OR | |
! |
Unary | Logical NOT | ||
?? |
Binary | Nullish coalescing |
| Operator | Type | Notes |
|---|---|---|
? : |
Ternary | Conditional expression |
| Operator | Type | Notes |
|---|---|---|
=> |
Arrow | Arrow function |
-> |
Arrow | Arrow function alternative |
| Operator | Type | Notes |
|---|---|---|
. |
Member | Object property access |
[] |
Index | Array or object indexing |
| Operator | Type | Notes |
|---|---|---|
new |
Unary | Instantiate object/class |
await |
Unary | Await asynchronous expression |
ask() |
Call | Prompt for user input |
++ --+ - ! await new* / %+ -< <= > >=== !=&&||??? := += -= *= /= %==> ->A program is represented as a Program node in the AST:
{ type: 'Program', body: [ ...statements ] }
Execution starts from the top and proceeds statement by statement.
Statements can produce values, alter state, or control flow.
Your language has the following primitive types:
| Type | Description | Example |
|---|---|---|
number |
Integer or floating-point | 42, 3.14 |
string |
Text literal | "hello", 'world' |
boolean |
true or false |
true, false |
null |
Null value | null |
array |
Ordered collection of values | [1, 2, 3] |
object |
Key-value mapping | { x: 10, y: 20 } |
function |
Callable code block | func(x) { return x+1 } |
async function |
Asynchronous function | async func() { ... } |
awaitable |
Result of async operations | await fetchData() |
Declaration: let creates a block-scoped variable.
let x = 5;
Define: define creates a global or persistent binding.
Shadowing: Inner scopes can shadow variables from outer scopes.
Scope types:
{ ... }.Expressions are evaluated according to operator precedence:
++ --+ - ! await new* / %+ -< <= > >=== !=&&||??? := += -= *= /= %==> ->Declaration:
func add(a, b) { return a + b; }
Arrow functions:
(x) => x + 1
Async functions: return awaitable promises.
Calling functions evaluates arguments and creates a new local scope.
Conditional statements:
if (condition) { ... } else { ... }
Loops:
while, for, do ... track, start ... raceBreak / Continue control loop execution.
Return exits a function with a value.
| Statement | Runtime Behavior |
|---|---|
sldeploy |
Executes a special deploy action with evaluated expression. |
ask() |
Prompts for user input and returns value. |
start { race } |
Executes multiple concurrent blocks, chooses winner. |
do ... track |
Executes a block with an optional error handling block. |
Array:
[1, 2, 3]
0.Object:
{ key: value }
obj.key) or index (obj['key']).+= -= *= /= %=).import supports:
Imports are evaluated at runtime to bring values into scope.
async func returns a promise.await pauses execution until the promise resolves.start { race } for concurrency.sldeploy(value)Outputs a formatted value to standard output.
sldeploy "Hello"
sldeploy [1, 2, 3]
sldeploy { a: 1, b: 2 }
ask(prompt)Reads user input from the terminal.
let name = ask("Enter your name:")
type(value)Returns the runtime type of a value.
type(10) // "number"
type("hi") // "string"
type([1,2]) // "array"
type({}) // "object"
num(value)Converts a value to a number.
num("42") // 42
num("abc") // RuntimeError
str(value)Converts a value to a string.
str(100) // "100"
len(value)Returns length of:
len([1,2,3]) // 3
len("abc") // 3
len({a:1}) // 1
keys(object)Returns an array of object keys.
keys({a:1, b:2}) // ["a", "b"]
values(object)Returns an array of object values.
values({a:1, b:2}) // [1, 2]
map(array, fn)Applies a function to each element.
map([1,2,3], x => x * 2)
filter(array, fn)Filters array elements.
filter([1,2,3,4], x => x > 2)
reduce(array, fn, initial?)Reduces array to a single value.
reduce([1,2,3], (a,b) => a + b)
range(...)Generates numeric ranges.
range(5) // [0,1,2,3,4]
range(1,5) // [1,2,3,4]
range(10,0,-2) // [10,8,6,4,2]
0sleep(ms)Pauses execution asynchronously.
await sleep(1000)
fetch(url, options?)Performs an HTTP request.
Returns an object with:
statusoktext()json()res = await fetch("https://example.com")
data = await res.json()
get(url)HTTP GET request returning parsed JSON.
data = await get("https://api.example.com")
post(url, data)HTTP POST request with JSON body.
post("https://api.example.com", { a: 1 })
letDeclares a variable with initializer required.
let x = 10
defineDefines a variable or constant.
define PI = 3.14
if / elseConditional execution.
if x > 5 {
sldeploy "big"
} else {
sldeploy "small"
}
whileLoop while condition is true.
while x < 5 {
x++
}
forClassic loop:
for let i = 0; i < 5; i++ {
sldeploy i
}
for ... inIterates over arrays or objects.
for x in [1,2,3] {
sldeploy x
}
for k in {a:1, b:2} {
sldeploy k
}
breakExits a loop.
continueSkips current iteration.
funcDefines a function.
func add(a, b) {
return a + b
}
async funcDefines an async function.
async func load() {
await sleep(1000)
}
x => x * 2
(a, b) => a + b
returnReturns a value from a function.
do / trackError-handling construct.
do {
risky()
} track {
sldeploy error
}
error is automatically available in trackstart / raceValue-based branching.
start x {
race 1 {
sldeploy "one"
}
race 2 {
sldeploy "two"
}
}
importSupports both Starlight files and Node.js modules.
.sl)import x from "math.sl"
import { add } from "math.sl"
import * as math from "math.sl"
.sl files are executeddefault export maps to the module objectimport fs from "fs"
import path from "path"
require+ - * / %
== != < <= > >=
&& || ??
?? is nullish coalescing! + -
x++
--y
x > 5 ? "yes" : "no"
{ a: 1, b: 2 }
[1, 2, 3]
arr[0]
obj["key"]
obj.key
newCreates an object from a function.
new MyClass(1, 2)
awaitWaits for async values.
await fetch(url)