Documentation
Getting to know NEXORA
A short, honest overview of the project: what it is, what exists today and where it is going.
NEXORA is in early development. A first interpreter runs a small subset of the language; the rest of this page describes a design in progress, and the syntax may change as the language evolves.
What is NEXORA
NEXORA is a new programming language, designed from scratch as an independent project. It explores a clearer, more expressive way to write software: a syntax of its own, rules that live inside the code, and results that both people and automated tools can read.
The question it starts from
Most languages were designed around one person giving instructions to a computer. Today the same code is also written, read and reviewed by AI systems. NEXORA starts from a different question: what would a language look like if that shared work were part of its design instead of an accident?
The answer it explores is not a new assistant, but the language itself: making the intent of a program explicit enough to be checked by a machine, without making it harder to read for a person. Whether that actually helps an AI system is still an open question, and this project does not claim to have answered it.
NEXORA in short
- What it is
- A general-purpose programming language with its own syntax, semantics and specification.
- Who builds it
- An independent project. It is not a fork, a library, or a layer on top of another language.
- What defines it
- The requirements of a program are written in the program itself, and checked in a deterministic way.
- Version
- 0.10, an experimental release before 1.0. The language can still change in incompatible ways.
- Implementation
- A reference interpreter written in Python 3.11 or later that uses only the standard library, with the
nexcommand on top of it. - Code files
- Plain UTF-8 text files with the
.nexextension. - Tools
- The
nexcommand line, a playground that runs in the browser, and JSON output for external tools. - License
- MIT.
What writing NEXORA is like
-
Static types, with no implicit conversions.
Int,Float,Bool,TextandVoid, with inference and annotations. Every change of type is written down. -
One name, one meaning. Inside a function a name is neither redefined nor
hidden, and
letbinds values that do not change unlessvarsays so. - Requirements in the code. Contracts, refined types and loop conditions are part of the program, not a separate document describing it.
- Problems found before running. Names, types and return paths are checked without executing anything, and every diagnostic says what failed, where and why.
- Data for tools, not only text for people. The same analysis can be read as JSON, with versioned schemas, by any tool that needs to understand a program instead of guessing what it means.
- Web first, in the long term. The design draft aims at compiling to JavaScript, and WebAssembly later. Neither exists yet.
What NEXORA is, and what it is not
It is not
- A framework, a library or a wrapper around another language.
- An AI assistant, a code generator or a chat. It calls no model and needs no service: its rules are deterministic code that works offline.
- Proven faster, safer or more productive than other languages. No comparison has been made.
- Ready for production, or a replacement for Python, JavaScript or any other language.
It is
- A language project with its own specification, interpreter, documentation and tests.
- A toolchain that grows around that language: the
nexcommand, the playground and structured JSON output. - An open experiment: whether these decisions really do make a program easier for an automated tool to analyse.
The idea that distinguishes it: the rules live in the code
A function declares what it expects from its caller and what it promises in return. A type declares which values it accepts. A loop declares why it ends. Each rule can carry its own explanation, and when one is broken the diagnostic says which rule failed, where, with which values, and why that rule exists.
type Percent = Int where value >= 0 and value <= 100, "A percentage goes from 0 to 100"
fn percentage(part: Int, whole: Int) -> Percent {
requires part >= 0 and part <= whole, "The part has to be inside the whole"
ensures result >= 0 and result <= 100
return Percent(part * 100 / whole)
}
fn main() -> Void {
print(to_text(percentage(3, 12)))
}
Four kinds of rule exist today:
-
requiresandensures— what a function expects from its caller, and what it promises to return, withresultas the returned value. -
type Percent = Int where ...— a refined type: a built-in type plus a rule all its values satisfy. Constants are checked bynex checkwithout running anything; computed values are checked at the moment they are converted. -
while ... decreases ... invariant ...— why a loop ends, and what it keeps true on every iteration. -
example— examples attached to a function, evaluated withnex test.
Run as it is, the program above prints 25. Change the call to
percentage(30, 12) and it stops before printing anything:
contract error[E4001]: Precondition violated
--> percentage.nex:10:19
|
10 | print(to_text(percentage(30, 12)))
| ^^^^^^^^^^^^^^^^^^ This call breaks a 'requires' condition of 'percentage'
= note: The condition at line 4 is false: requires part >= 0 and part <= whole
= note: Reason: The part has to be inside the whole
= note: It was called with: part = 30, whole = 12
What happens when you run a NEXORA program
The same analysis produces two readings: one written for a person, and one made of data for any program that needs to read the code. These are the steps both come from.
-
Read the file
The source is turned into tokens and then into a syntax tree. Nothing is executed.
-
Check names, types and return paths
Every name is resolved, every expression is given a type, and every path that reaches the end of a function is verified.
-
Report what is wrong, before anything runs
A program with errors is never executed. Each diagnostic carries a stable code, a category and an exact position.
-
Run only what is valid
The interpreter evaluates the program and checks the runtime rules: contracts, refined types, loop measures and invariants.
-
Deliver the same result as data
With
--format json, diagnostics, the syntax tree, the symbols and a summary of the program are returned as documents with versioned schemas, so a tool can read them without parsing prose.
Who it is for
- Developers who want the rules of their code written down. Requirements, limits and expected results live next to the code they describe.
- Anyone learning how a language is designed and built. The specification, the decisions behind it and the interpreter are all part of the project.
- Authors of tools that have to read programs. The structured output is available from the command line, from Python, and through an optional MCP server.
- Researchers of the human and AI collaboration. The hypothesis behind the project is written down, and so is the fact that it has not been evaluated yet.
With the current version, NEXORA suits small programs and the study of the language itself. It does not yet suit writing applications.
Where to go from here
- Language guide — a walkthrough of the syntax that already works, with every example executed and checked.
- Playground — write and run NEXORA in the browser, without installing anything.
- Current status — exactly what exists today, what is experimental and what does not exist yet.
- Design philosophy — the goals behind the decisions.
- Conceptual example — a first look at the syntax.
- Roadmap — the phases the project moves through.
- FAQ — the questions that come up most often.
- Language design draft v0.1 — the full working document, written in Spanish.
Current status
The project is at an early stage. This is what exists today and what does not:
- Available
-
- A reference interpreter, version 0.11, that runs a subset of the language from the command line.
- Rules written in the code and checked by the interpreter: contracts (
requires,ensures) and refined types (type Percent = Int where ...), loops that declare why they end (decreases) and what they keep (invariant), each with an optional explanation, and examples in functions (example) checked withnex test. - Operations on text (
Text.length,Text.slice, ordering) and reading numbers withInt.parseandFloat.parse, each function stating the requirements it checks. - Immutable lists (
List[Int],[1, 2, 3]) withList.length,List.get,List.append,List.concatandList.contains, andforloops over them. - Records: types the program declares, with immutable fields (
type Point = { x: Int, y: Int }), built by name and compared by value. Their identity is the identity of their declaration, so two records with the same fields are still different types. - Optional values (
Option[T]) and results (Result[T, E]), to say that there is no value or that something failed, without exceptions. - A language specification for that subset, and a broader design draft.
- A playground that runs code in the browser with that interpreter. It is off unless the server enables it explicitly, and it must stay off on a public site until the isolation of its containers has been checked.
- A short language guide.
- This website and this first documentation page.
- Experimental
-
- The syntax itself. It is still being defined and can change.
- Most code examples on this site. Unless stated otherwise they are illustrations, not runnable programs.
- Planned
-
- The rest of the language: modules and imports.
- More developer tools.
- Optional AI integrations, currently at the research stage.
The full design draft is available as a working document: Language design draft v0.1 (written in Spanish). It is more detailed than this page and some of its notation differs from the examples shown here.
How it is tested
Each figure is a snapshot of the day it was measured, not a guarantee about the current code.
- Passed
-
- Interpreter, version 0.9: 2,278 tests passed, 7 skipped and 0 failed, with 94.59% coverage, on Windows 11 with Python 3.12 (22 October 2026). Version 0.8: 2,190 tests passed, 4 skipped and 0 failed, with 94.34% coverage, on the same system (21 October 2026). Version 0.7: 2,074 passed, 4 skipped and 0 failed, with 94.63% coverage, on the same system (21 October 2026). Version 0.6: 1,600 passed, 4 skipped and 0 failed, on the same system (15 October 2026).
- Interpreter in the continuous integration, on Linux, Windows and macOS with Python 3.11, 3.12 and 3.13: 2,282 tests passed and 3 skipped on Linux, 2,281 passed and 4 skipped on macOS and 2,278 passed and 7 skipped on Windows, with 0 failed and 94.54% coverage on the first two platforms and 94.59% on the third (22 October 2026). On macOS the test of the limit of memory is skipped, because macOS accepts that limit and does not enforce it.
- Interpreter on Linux (Ubuntu 24.04 under WSL 2): 1,604 tests passed, none skipped and 0 failed with Python 3.12.3, and the same with 3.11.17 and 3.13.16 (17 October 2026). That includes the 4 POSIX tests that Windows skips: a file without read permission, and the memory, CPU and time limits of the playground process.
- Web server: 826 automated tests passed, none skipped and 0 failed in the continuous integration, on Linux, Windows and macOS with Node 22, 22.23.2, 24 and 24.18.1, and with Node 26 in Linux without blocking the flow (22 October 2026). The package for npm passes 12 tests on the same platforms, with Node 18, 22 and 24.
- Web server, in the development version: 821 automated tests passed, none skipped and 0 failed in one run on Windows 11 with Node 24.21.0 (21 October 2026), after the site and the playground were brought up to language 0.8. Before that, 818 passed, none skipped and 0 failed in one run with the same system and Node (21 October 2026), after the site and the playground were brought up to language 0.7. Before that, 811 passed, none skipped and 0 failed in one run with the same system and Node (18 October 2026), and before the change that preceded it, 810 passed, none skipped and 0 failed in each of three runs on Windows 11 with Node 24.21.0, and in one run each with Node 24.14.0, 22.23.3 and 22.22.3; with Node 20.6.1 and 22.15.0, 796 passed, 14 were skipped (they need Node 22.22.3 or later in the 22 line, or 24.14.0 or later in the 24 line, the versions accepted by the guards of the integration tests) and 0 failed in one run each (18 October 2026). The server itself requires Node 22.23.2 or later in the 22 line, or 24.18.1 or later in the 24 line: those exact versions are the ones the continuous integration tests. None of those manual runs was on Linux. An earlier state of that version, with 567 tests, passed in each of three runs on Windows 11 and on Linux (Ubuntu 24.04 under WSL 2) with Node 24.11.1, the same day. The tests of the container command only analyse its arguments, and the container lifecycle tests use a fake Docker: no real container was run. The database, Google reCAPTCHA and the browser are simulated too.
- Pending
-
- Checking the isolation of the playground containers with real Docker. It has not been done yet.
- Checking the website visually in a browser: the cookie banner, the account forms and the pages of this documentation. The automated tests only read the pages; they do not display them.
- Not tested
-
- Linux outside WSL or on other distributions, and a real Mac rather than the macOS runner of the continuous integration. The workflow for Linux, Windows and macOS with Python 3.11, 3.12 and 3.13 runs on every change to
main: it passed all its jobs on 22 October 2026. - The web server against a real MySQL database, real Google reCAPTCHA keys and the headers of the production server.
- Speed and memory use. There are no tests for them.
- Linux outside WSL or on other distributions, and a real Mac rather than the macOS runner of the continuous integration. The workflow for Linux, Windows and macOS with Python 3.11, 3.12 and 3.13 runs on every change to
Recent changes
- 0.10.0
-
Option[T]:Some(value)andNone, to say that there is no value without exceptions.Result[T, E]:Ok(value)andErr(error), to say that something failed, keeping the error as it was.- The variants are told apart with functions:
Option.is_some,Option.is_none,Result.is_okandResult.is_err. The value is read withOption.unwrap_orandResult.unwrap_or, or without a fallback withOption.unwrap,Result.unwrapandResult.error, which stop the program with a diagnostic. - Every program that was valid in 0.9.0 is still valid and gives the same result. Tagged as
v0.10.0and published for npm and for Python.
- 0.9.0
-
- Arguments and standard input:
args()returns the arguments the program was run with, andinput()reads one line. Both are allowed by default. - Files, with explicit permissions: a program declares what it needs with
uses read "datos/entradas.txt", and whoever runs it has to allow it with--allow-read=datos. The paths are checked where they really are, so a..or a symbolic link cannot leave the folder that was allowed. - The playground and the MCP server never allow files: a program that uses one stops with an error.
- Every program that was valid in 0.8.0 is still valid and gives the same result. Tagged as
v0.9.0and published for npm.
- Arguments and standard input:
- 0.8.0
-
- Records: types the program declares, with immutable fields (
type Point = { x: Int, y: Int }). They are built by name (Point(x: 1, y: 2)), their fields are read with a dot (p.x), and two values of the same record are compared by value. - A record is nominal: its identity is the identity of its declaration, not its name nor its fields. Two records with the same fields are still different types.
- A record never changes: there is no way to assign to one of its fields.
- Every program that was valid in 0.7.0 is still valid and gives the same result. It was never tagged or published.
- Records: types the program declares, with immutable fields (
- 0.7.0
-
- Immutable lists
List[T]: literals such as[1, 2, 3], nested lists and structural equality. Every element has the same type. - Functions on lists:
List.length,List.get,List.append,List.concatandList.contains.List.getdeclares the indexes it accepts, and an index out of range stops the program. for x in xswalks a list. It can declare invariants, and it needs no measure: it ends with the list.- Every program that was valid in 0.6.0 is still valid and gives the same result. It was never tagged or published.
- Immutable lists
- 0.6.0
-
- Operations on text that declare their requirements:
Text.length,Text.slice,Text.contains,Text.starts_withandText.ends_with, and reading numbers withInt.parseandFloat.parse, checked first withInt.can_parseandFloat.can_parse. - Ordering between texts with
<,<=,>and>=. - Every program that was valid in 0.5.1 is still valid and gives the same result.
- Operations on text that declare their requirements:
- Not released
-
- Changes to the web server and the website only; the language and the interpreter do not change. None of the playground changes has been checked with real Docker yet.
- The playground is off unless the server sets
PLAYGROUND_ENABLED=true. - The server only accepts the documented container command, and it only runs the local
nexora-workerimage, which Docker never downloads. - A container that runs out of time is removed by the name the server gave it, and its slot is only freed once the removal is confirmed.
- Sign-up and log-in are protected against spam: Google reCAPTCHA v3, loaded only if you accept it in the cookie settings, and stricter attempt limits without it. Repeated failed log-ins on one account have to wait.
- Every response carries security headers, and the fonts are served by this site instead of Google Fonts.
- Server settings that used to be read loosely now stop it at start-up when they are wrong:
NODE_ENV,TRUST_PROXY, the newLISTEN_HOSTand the reCAPTCHA settings. In production without a reCAPTCHA key, every sign-up and log-in gets the stricter limits.
Design philosophy
Three goals guide the decisions made so far. They are intentions, not finished features.
Clarity first
Code is read far more often than it is written. NEXORA aims for a syntax that is readable, consistent and easy to understand, with few special cases to remember.
Built to evolve
The language is designed so that tools, documentation and an ecosystem can grow around it without having to rethink its foundations.
AI, thoughtfully integrated
The project is exploring how AI tools could fit into the language. The intent is for them to stay optional: writing NEXORA should never require an AI service, and nothing is promised before it exists.
Ideas the current draft is exploring:
- Values that are immutable unless declared otherwise.
- Errors handled as ordinary values rather than exceptions.
- Function signatures that state their types explicitly.
Conceptual example
This is how a minimal program is currently imagined:
fn main() -> Void {
let message = "Hello, future."
print(message)
}
fn declares a function and -> Void states that it returns nothing.
let binds a name to a value, and print would write it out.
Run with the reference interpreter, this program prints Hello, future.
Roadmap
The project moves through four phases, in order. There are no dates attached to them.
Following the project
The source repository is public, but the links to it stay hidden in this site.
Follow the development on GitHub
This page and the roadmap are updated as the project advances.
Frequently asked questions
Short answers to the questions that come up most often about the project and how to take part in it.
About the project
Is NEXORA ready for production?
Not yet. Version 0.10 is an experimental development release. It can be explored and tested, but production suitability has not been established.
Is NEXORA a replacement for Python?
No such claim is made. The current implementation uses Python, and the project explores its own language design goals.
It should be evaluated on its actual capabilities rather than as a general replacement for Python or another established language.
Can I use NEXORA to learn about programming languages?
Yes. Exploring the available syntax, examples, interpreter behavior, diagnostics and design records can be useful for learning and experimentation. The playground and the language guide are good places to start.
Getting involved
Can I contribute?
You can provide feedback and explore potential contributions. The project's public repository and its contribution instructions describe the current process.
Where should I report a bug?
Use the project's issue tracker: github.com/xGlizyy/nexoralang/issues. Include:
- The NEXORA version (
nex --version); - The operating system;
- The smallest program that reproduces the issue;
- The command you ran;
- The actual output.
What should I do if a feature is missing?
Check the language documentation and limitations first. If the feature is not supported, treat it as a possible future proposal rather than assuming the language is behaving incorrectly.