Skip to content

Changelog

v1.0.0 — Initial Release

First stable release of Zen.

  • Compiler core stabilized (LLVM backend)
  • Language design finalized
  • Standard library introduced
  • Basic tooling and documentation added

Notes

This marks the first public version of Zen. Future updates will be incremental improvements and new features.

v1.0.1

  • Disabled map dynamic key access (compile-time safety)
  • Disabled loop in mutation during iteration (undefined behavior prevention)
  • Added sys.performance() to stdlib
  • Added sys.argv to stdlib
  • Various bug fixes

v1.1.1

Language

  • Added support for List<Struct>
  • Added limited struct literal support
  • Struct variables can now be initialized using literals:
    Person p = { name: "Jishith", age: 21 }
    
  • Functions can now return structs
  • Structs can now be exported and imported across modules
  • Empty initialized global struct instances can be exported and imported
  • Added byte generic support through List<byte>
  • Added limited empty List type inference when type context is available
  • Disabled automatic function type inference for structs
  • Disabled dynamic map access and dynamic map assignment
  • Disabled maps as function parameters

Standard Library

  • Added matchRegex() with POSIX ERE regex support
  • Added ffi.fn
  • Added List.join()
  • Added List.indexOf()
  • Added Map.keys() returning List<string>
  • Added fs.readFileBytes()
  • Added fs.writeFileBytes()
  • Added binary file support through List<byte>

Compiler & Runtime

  • Added function name mangling
  • Migrated compiler and runtime to LLVM opaque pointers (ptr)
  • Added 32-bit and 64-bit aware size and alignment calculations
  • Standardized internal LLVM helper functions with _-prefixed names
  • Improved global string handling after opaque pointer migration
  • Improved struct passing and struct return behavior

Tooling

  • Added zen init <project-name> for project scaffolding

Creates a new project directory containing:

<project-name>/
├── main.zen
└── zen.json

Generated zen.json:

{
  "name": "<project-name>",
  "version": "1.0.0",
  "main": "main.zen"
}
  • Added official Zen Package Registry for package management
  • Added zen signup and zen login for authentication
  • Added zen logout and zen whoami for account management
  • Added zen install <package> to install packages from registry
  • Added zen publish to publish packages to registry
  • Added zen unpublish to remove packages from registry
  • Added zen list with pagination to browse all packages (50 per page)
  • Registry supports both runnable applications (main) and library packages (bin)
  • Library packages install to ~/.zen/packages/
  • Runnable applications install to current directory
  • Secure JWT-based authentication
  • GitHub-hosted package source code

Fixes

  • contains() no longer performs struct literal comparisons
  • Various compiler, runtime, and standard library bug fixes

v1.2.1

Language

  • Introduced enum with constant integer values
  • Added support for importing and exporting within the same module
  • Added circular import detection and resolution
  • Added installed package imports (import(...) from "package")
  • Exported modules can now import other modules and packages
  • Added built-in HttpServer, HttpRequest, and HttpResponse structs

Standard Library

  • Added httpServer namespace
  • Added httpServer.create(port)
  • Added HttpServer.listen()
  • Added HttpServer.next()
  • Added HttpServer.close()
  • Added HttpRequest.method
  • Added HttpRequest.path
  • Added HttpRequest.json()
  • Added HttpRequest.html()
  • Added HttpRequest.css()
  • Added HttpRequest.send()
  • Added HttpRequest.setHeader()
  • Added HttpRequest.redirect()
  • Added HttpRequest.status()
  • Added sys.setEnv()
  • Added sys.hasEnv()
  • Added sys.timestamp()
  • Added sys.execOutput()
  • Added os.exit()
  • Added os.pid()
  • Added os.parentPid()
  • Added os.platform()
  • Added os.isWindows()
  • Added os.isLinux()
  • Added os.isMac()
  • Added os.isAndroid()
  • Added os.homeDir()

Tooling

  • Added zen recovery for account recovery
  • Added zen uninstall <package>
  • Added zen search <package>
  • Added zen kind <package>
  • Added zen mine
  • zen install now automatically detects the repository's default Git branch
  • Increased package description limit from 50 to 400 characters
  • Migrated the package registry backend from JSON storage to PostgreSQL

Compiler & Runtime

  • Improved module dependency resolution
  • Improved import/export compilation
  • Improved HTTP runtime support

Fixes

  • Various compiler, runtime, CLI, package registry, and standard library bug fixes

v1.3.0

Language

  • Added built-in Json, JsonObject, and JsonArray structs
  • Added JSON parsing and traversal API
  • Added HttpRequest.body
  • Added bitwise XOR (^) operator for integer operands
  • Added time.now()
  • Added time.format()
  • Added sys.clipboard.get()
  • Added sys.clipboard.set()
  • Added sys.clipboard.clear()
  • Added sys.clipboard.hasText()

Standard Library

  • Added Json.parse()
  • Added Json.free()
  • Added Json.getRootObject()
  • Added Json.getRootArray()
  • Added JsonObject.getString()
  • Added JsonObject.getInt()
  • Added JsonObject.getDouble()
  • Added JsonObject.getBool()
  • Added JsonObject.getObject()
  • Added JsonObject.getArray()
  • Added JsonArray.getString()
  • Added JsonArray.getInt()
  • Added JsonArray.getDouble()
  • Added JsonArray.getBool()
  • Added JsonArray.getObject()
  • Added JsonArray.getArray()
  • Added HttpRequest.sendFile(path, contentType)

Compiler & Runtime

  • Added compile-time distinction between built-in struct properties and methods
  • Added compile-time validation for built-in struct property access
  • Added runtime JsonError
  • Added use-after-free detection for JSON objects
  • Improved HTTP server runtime
  • Improved JSON runtime
  • Improved bitwise operator validation

Documentation

  • Expanded language specification
  • Added JSON API documentation
  • Added HTTP server documentation
  • Added semantics documentation
  • Added runtime error reference

Removed

sys.timestamp() has been removed.
Use time.now() instead.

Fixes

  • Various compiler, runtime, CLI, package registry, and standard library bug fixes

v2.0.0 — Major Release

⚠️ Breaking Release

ZEN v2 introduces the largest language update since the initial release. Several language constructs have been refined for improved consistency, readability, and long-term stability.

From v2 onwards, the language syntax is considered frozen for backward compatibility. Future releases will focus on new features and APIs while preserving existing syntax whenever possible.


Language

Syntax Changes

⚠️ Breaking Change

Struct field declarations now use type name order.

Old

name string
age int

New

string name
int age

⚠️ Breaking Change

const now appears before the type.

Old

int const age = 10

New

const int age = 10

  • Added .free() method for string values
  • Introduced .free() methods for heap-owned values
  • Heap-owned values in Zen now provide an explicit .free() method for manual memory management
  • Improved ownership and memory management semantics for heap-allocated values

⚠️ Breaking Change

byte has been replaced by the built-in Byte struct.

Binary APIs now use List<Byte>, and byte values are created using toByte().

  • Added callback function parameters (fn cb(...))
  • Added thread fn for lightweight concurrent execution
  • Added extern fn for foreign function declarations without name mangling
  • Added generic function call syntax (function<Type>()) for type-safe generic returns
  • Added built-in Ptr struct for native pointer manipulation
  • Added built-in Byte struct for binary data
  • Added global toByte() conversion function
  • Map is now implemented as a built-in struct instead of a language data type
  • Added struct-style Map literals
  • Introduced ownership semantics for runtime-managed objects
  • Improved compile-time type safety for generic APIs

Standard Library

HTTP

  • Added http.urlEncode()
  • Added http.urlDecode()
  • Added http.setHeader()
  • Added http.clearHeaders()
  • Added http.lastStatus()
  • Added configurable request timeout support

Threads

  • Added threads namespace
  • Added threads.waitAll()

Debug

  • Added debug namespace
  • Added debug.pretty() for formatted printing of Lists, Maps, and structs

Package Registry

  • Added package version history and version-specific publishing
  • Added support for installing specific package versions: zen install <package>@<version>
  • Added automatic dependency detection with zen deps
  • Added recursive dependency detection through imported .zen files
  • Added automatic dependency installation during package installation
  • Package dependencies are stored in zen.json
  • Added support for recursive package dependencies
  • Package versions are backed by Git tags
  • Registry now preserves previously published package versions
  • Added version-specific package metadata and repository resolution
  • Library packages are installed to ~/.zen/packages/<package>
  • Installing a package automatically installs its dependencies
  • Added Semantic Versioning validation for package versions

Compiler & Runtime

  • Added runtime support for thread execution
  • Added callback code generation support
  • Added external function declarations
  • Added native pointer runtime (Ptr)
  • Migrated Map to an opaque built-in runtime struct
  • Migrated binary APIs to List<Byte>
  • Added compile-time ownership validation where possible
  • Added runtime detection for invalid ownership operations
  • Added runtime detection for use-after-free errors
  • Improved generic type resolution for nested List types
  • Improved built-in struct handling
  • Improved Byte runtime integration
  • Improved HTTP runtime
  • Improved parser consistency
  • Improved formatter support

Tooling

  • Added official source formatter (zen fmt)
  • Added built-in linter (zen lint)
  • Added Language Server Protocol (LSP) implementation
  • Added editor auto-completion support
  • Added hover information support
  • Added signature help support
  • Improved diagnostics
  • Improved code formatting workflow
  • Improved developer tooling integration

Documentation

  • Completely rewritten language specification
  • Updated all syntax examples to v2
  • Added thread documentation
  • Added callback documentation
  • Added extern documentation
  • Added Ptr documentation
  • Added Byte documentation
  • Added toByte() documentation
  • Added ownership semantics documentation
  • Added Map runtime documentation
  • Expanded built-in struct documentation
  • Updated binary API documentation to List<Byte>
  • Improved API reference
  • Improved appendix and language reference

Fixes

  • Fixed numerous parser bugs
  • Fixed formatter inconsistencies
  • Fixed built-in struct handling
  • Fixed HTTP runtime issues
  • Fixed generic type resolution
  • Fixed module and compiler edge cases
  • Fixed known compiler, runtime, tooling, and standard library bugs

Notes

This release marks the beginning of the ZEN v2 series. The language syntax is now considered stable, with future releases focusing on new capabilities, performance improvements, tooling, and standard library expansion while maintaining backward compatibility.

v2.1.0

Language

  • Added new primitive type byte (i8)
  • Added new primitive type long (i64)
  • Added L suffix for long literals
  • Added B suffix for byte literals
  • Added hexadecimal byte literals using an explicit trailing B suffix
  • Changed toByte() to Byte()
  • Added Long() global cast
  • Added concatenation coercion support for byte
  • Added setT() / getT() support for long and byte

Standard Library

Crypto

Added the new crypto namespace:

  • crypto.sha256(data)
  • crypto.sha512(data)
  • crypto.hmacSha256(key, data)
  • crypto.hmacSha512(key, data)
  • crypto.randomBytes(length)
  • crypto.randomInt(min, max)
  • crypto.base64Encode(data)
  • crypto.base64Decode(data)
  • crypto.base64UrlEncode(data)
  • crypto.base64UrlDecode(data)

Map & JSON

  • Added Map.json()
  • Added Json.map()

Compiler & Runtime

  • Changed several built-in APIs from int to long for 64-bit values.

OS

  • os.totalMemory: int → long
  • os.freeMemory: int → long
  • os.usedMemory: int → long
  • os.processMemory: int → long
  • os.pid: int → long
  • os.parentPid: int → long

Time

  • time.millis: int → long
  • time.now: int → long
  • time.format argument: int → long
  • time.sleep argument: int → long

v2.1.1

Standard Library

HTTP

  • Added HttpRequest.getHeader() for retrieving a request header by name.

JSON & Map

⚠️ Important

  • JSON integer numbers become Long values when converted using .map().
  • After .map(), use getLong() to retrieve JSON integer values.
  • Normal Map integer/long behavior remains unchanged.

Language

Automatic List Field Initialization
  • List fields are automatically initialized when a new struct instance is declared without an initializer.
  • Struct literals only initialize or assign the fields explicitly specified in the literal.

Path

  • extName() returns the file extension without the leading ..
  • path.extname() returns the file extension with the leading ..

Fixes

  • Various compiler, runtime, standard library, and type-resolution bug fixes.

v3.0.0 — Major Release

⚠️ Breaking Release

  • toString() / toInt() renamed to intToAscii() / asciiToInt()
  • private is now a reserved keyword (functions, methods, fields)
  • Keyword in removed
  • Classic loops must always use loop (init, cond, update)
  • + with a string operand converts the other operand to a string and concatenates
  • fs.writeFileBytes() now returns int (success code) instead of void
  • sqrt() now takes and returns double
  • zen tests renamed to zen test
  • zen -v changed to zen --v
  • JSON integers after .map() are no longer always Long (see Standard Library)
  • Windows support is temporarily paused

Language

  • Formalized numeric widening: byte → int → long → double
  • bool can now be used in arithmetic (true = 1, false = 0) and bitwise operations
  • Added bitwise operators &, |, >>, <<, ~
  • Added unary +
  • auto inference now supports int, bool, double, string, long, byte
  • Added compile-time constants (int N = 10; int arr[N])
  • sizeOf() now supports bare types and expressions (bare struct names are not supported)
  • Struct fields can have default initializers
  • Uninitialized structs get zero-value fields (0, "", false, empty list)
  • Struct literals only set the fields explicitly given
  • Added anonymous inline functions as callback arguments (no closures: they cannot capture outer variables)
  • Named functions passed as callbacks can use closures
  • Thread functions now accept parameters and report capture errors at compile time
  • Thread methods in structs are supported
  • Added multiple exports and imports per file
  • Added import aliasing for functions and variables (import (worker as w)); structs cannot be aliased
  • Struct dependencies are tracked: importing a struct also registers its dependent structs as hidden (usable through the struct, not nameable)
  • Exported functions can take or return structs that are not exported
  • Chained calls on returned structs are supported (make().show())
  • Added private for fields and methods
  • Added scientific notation for double literals (1e300, 1.5e-10, 2E+5)
  • byte is signed (-128 to 127); suffixed values outside the range wrap (two's complement)
  • Hex literals without a suffix are always int (0xFB is 251)
  • Hex literals with a type suffix need an underscore: 0xFB_B is byte, 0xFF_L is long
  • Added \e and \xHH string escapes (for example "\e[31m" for ANSI colors)
  • Added constants SQRT1_2, SQRT3, LOG2E, LOG10E, BYTE_MAX, BYTE_MIN, I64_MAX, I64_MIN

Standard Library

General

  • Added lastIndexOf()
  • Added stringToBytes() and bytesToString()
  • length() now accepts a List directly, alongside list.length

List and Map

  • Added List.remove(), List.reverse(), List.sort(), List.sum(), List.avg()
  • Added List.flat() (flattens any depth to depth 1)
  • Added Map.keys() and Map.entries()

JSON

⚠️ Important

JSON numbers converted with .map() can be read with getInt(), getByte() or getLong(). Overflow is checked at runtime for the getter used. This replaces the v2.1.1 behavior where integers were always Long.

File System and System

  • Added fs.listDir(), fs.isFile(), fs.isDir()
  • Added sys.spawn(), sys.kill(), sys.isRunning(), sys.wait()
  • Added threads.count() and threads.currentId()

Networking

  • Added TCP support: Tcp and TcpServer structs
  • Added net.online(), net.connect(host, port), net.listen(port)
  • Added Tcp.send(), Tcp.receive(), Tcp.close(), Tcp.isOpen()
  • Added TcpServer.accept(), TcpServer.close(), TcpServer.isOpen()

HTTP

  • Added http.getProgress(url, callback) for downloads with progress reporting. The callback receives downloaded and total bytes (long), and the call returns the data as List<byte>
  • Connect timeout is 10 seconds for every request
  • Requests without a progress callback have a 30 second total limit
  • Requests with a progress callback have no total limit; they abort only if speed stays below 1 KB/s for 30 seconds
  • Network failures and timeouts print a NetworkError and exit

Tooling

  • zen install and zen uninstall accept multiple package names
  • renamed zen -h to zen --h
  • Added zen installed
  • Added zen upgrade <package>
  • Added zen install <package>@<semver>
  • Added zen read <package> [--raw] to render a package README in the terminal
  • Added zen update --dev to install the development version
  • Added zen test <package> to run a package's test.zen
  • Added zen --v <package>, zen --version <package> and zen version <package> for installed package versions
  • Added zen info for namespaces and globals (with --methodName)
  • zen deps now detects and records native/*.o; native objects link automatically
  • .c files are supported as native dependencies
  • zen.json supports flags: [] at module and standalone level (for example -lmariadb)
  • Added --link a.o b.o
  • Added interactive REPL (zen with no arguments); prints "Bye!" on exit()
  • Enhanced LSP server (zen lsp)
  • Enhanced formatter and fixed bugs
  • Fixed linter bugs
  • Better compile-time diagnostics with hints and source text

zen fmt

Formats .zen files. Output goes next to the source as name.formatted.zen (the original is never touched).

Usage

zen fmt <path...> [-r | --recursive] [--no-comments]
Command What it formats
zen fmt a.zen one file
zen fmt a.zen b.zen several files
zen fmt src .zen files directly inside src
zen fmt src -r everything under src, all subfolders
zen fmt . -r the whole project
zen fmt *.zen shell glob, works as normal multiple paths

Flags

  • -r, --recursive descend into subdirectories (flag position doesn't matter)
  • --no-comments drop comments from the output

Rules

  • Skipped always: *.formatted.* files (so re-running never formats its own output)
  • Skipped when recursing: node_modules, build, .git, .zen
  • Duplicate paths are formatted once
  • Errors: Path not found: <path> if an input doesn't exist, No .zen files found if nothing matched

Breaking change

The old dir/* and dir/** syntax is removed. The shell expanded them before zen saw them. Use dir and dir -r instead.


Installer

  • Added --tag and --branch install modes
  • Branch installs skip the VERSION check and version from the short commit hash
  • Verified on Termux (Android) and reviewed for apt, pacman, dnf and zypper
  • Windows is not supported for now (documented, not auto-installed)

Compiler & Runtime

  • Thread methods spawn through the same path as thread functions
  • Thread context is freed inside the thread; string arguments are duplicated and freed per thread
  • Struct dependency tracking with clear errors for naming or clashing with hidden structs
  • Redefinition errors now show line information
  • Unified unknown-struct error in member chains
  • Parser supports chained access after a statement-level call

Documentation

  • Added architecture documentation
  • Updated error reference

Known Limitations

  • Structs cannot be imported with an alias
  • debug.pretty() does not support struct fields of type List<Map>
  • HTTP timeouts are not configurable; no retry or resume
  • Windows support is paused

Fixes

  • Fixed linter, formatter and LSP bugs
  • Various compiler, runtime, CLI, and standard library bug fixes

v3.1.0 — Language and Standard Library Improvements

Language

  • Added automatic initialization of Map fields in structs when no initializer is provided
  • Added optional labeled function arguments using label: value syntax; labels are for readability and do not affect argument ordering or evaluation

Standard Library

Path

  • Updated path.join() to accept two or more path components in a single call

Output

  • Added variadic print() built-in for printing multiple values separated by a single space, followed by a newline
  • Preserved the existing screen(value, format) API for formatted output

Map

  • Added Map.type(key) to return the canonical type of a stored value as a string, including nested list types such as List<List<int>>

Compiler & Runtime

  • Restricted explicit type arguments to generic-capable calls; currently, getList() supports explicit type arguments
  • Added runtime validation of requested list depth and leaf type in Map.getList()
  • Added validation of declared list types against getList() generic arguments
  • Added validation of supported list element types in Map.setList() and Map.getList()
  • Improved nested list inference for Map values, setList() arguments, and function return values
  • Improved list depth and leaf-type validation during indexing
  • Added runtime bounds checking for string indexing
  • Fixed undefined behavior when iterating over a List of Maps

Diagnostics & Compiler Improvements

  • Improved parser diagnostics for missing closing braces at EOF
  • Improved source locations for unresolved struct field types
  • Improved type errors for void expressions used where values are expected
  • Improved built-in type handling and error messages
  • Improved return-path analysis for switch statements with a default case
  • Added typo suggestions for unknown functions, variables, and namespaces
  • Improved handling of generic type arguments in method and function calls

CLI & Runtime

  • Fixed program argument forwarding in zen run
  • Fixed propagation of nonzero exit codes from compiled programs

Fixes

  • Fixed Map initialization and pointer handling in struct fields
  • Fixed incorrect list element sizes and metadata for nested lists
  • Fixed generic handling and type validation in Map list operations
  • Fixed invalid LLVM generation when indexing beyond the declared list depth
  • Various compiler, parser, runtime, CLI, and standard library bug fixes