Skip to main content

Myna (myna-lang)

PyPI PyPI downloads Python versions License: MIT

Myna is an ultra-dense, symbol-based, AI-native programming language designed to cut LLM token and character usage by ~50% while transpiling 1:1 to Python 3.12+ and to a bounded JavaScript (ES2024+) target—and decompiling existing Python code back into Myna.


Why Myna?

Coding agents spend thousands of context and output tokens on repetitive syntactic boilerplate (def __init__(self, ...):, self., Optional[...], try ... except Exception as e:, quoted JSON keys, and 4-space indentation blocks).

Myna replaces verbose multi-token boilerplate with tokenizer-friendly ASCII sigils and digraphs ($$, @, ~@, =>, ??, !?, !&, $, $?) and brace-delimited blocks ({}):

  • ~46%–52% fewer LLM tokens and ~48%–58% fewer characters than equivalent Python (compact and ultra-compact modes).
  • Zero indentation fragility: Blocks use { ... } or =>, making partial diffs and single-line generation rock-solid for AI agents.
  • Bi-directional (Python <-> Myna) & Multi-Target (Myna -> Python / JS): Compress existing Python codebases into .myna to fit twice as much code into an agent's context window, or let agents write .myna and transpile to clean Python or JavaScript.
  • Agent-Ready: Ships with a compact Rosetta Stone skill (skills/myna/SKILL.md) that teaches any coding agent to read and write idiomatic Myna in one shot.

Side-by-Side Comparison

Python (21 lines, 611 chars)

from dataclasses import dataclass
import asyncio

@dataclass
class Task:
    id: int
    title: str
    priority: int = 1
    done: bool = False

    def to_dict(self) -> dict[str, object]:
        return {"id": self.id, "title": self.title, "done": self.done}

async def pending(tasks: list[Task], min_p: int = 1) -> list[dict[str, object]]:
    try:
        await asyncio.sleep(0.01)
        items = [t for t in tasks if not t.done and t.priority >= min_p]
        return [t.to_dict() for t in sorted(items, key=lambda t: -t.priority)]
    except Exception as e:
        print(f"Error: {e}")
        return []

Myna (11 lines, 299 chars — 51% smaller)

<asyncio
$$Task(id:i,title:s,priority:i=1,done:b=F){
  @to_dict->{s:A}=>{.id,.title,.done}
}
~@pending(tasks:[Task],min_p:i=1)->[{s:A}]{
  !{
    ~asyncio.sleep(0.01)
    items=[t|t<-tasks?!t.done&&t.priority>=min_p]
    ^[t.to_dict()|t<-@srt(items,key=t=>-t.priority)]
  }!!e{p(`Error: {e}`);^[]}
}

Quickstart

The CLI requires Python 3.11+ and has zero external dependencies. Generated Python targets 3.12+ when the source declares a type alias ($= emits type X = ...); other output runs on 3.11+.

# Install from PyPI
pip install myna-lang          # or: uv tool install myna-lang / pipx install myna-lang

# Install for local development (from a checkout)
pip install -e .

# Show the package and language versions
myna --version

# Create and run a script
printf 'p(`hello from {1+1}`)\n' > hello.myna
myna run hello.myna

# The remaining examples are in a checkout of the repository.
# Run a Myna script directly (via Python)
python3 -m myna run examples/demo.myna

# Run a portable Myna script via Node.js (JavaScript target)
python3 -m myna run -t js examples/cross_target.myna

# Compile Myna -> Python (.py)
python3 -m myna compile examples/rest_api.myna -o rest_api.py

# Compile Myna -> JavaScript (.js)
python3 -m myna compile -t js examples/cross_target.myna -o cross_target.js

# Bundle a multi-file program into one standalone Python file
python3 -m myna bundle src/main.myna -o app.py

# ...or into a runnable zipapp (stdlib-only, executable)
python3 -m myna bundle src/main.myna --zipapp -o app.pyz

# Compress existing Python -> Myna (.myna)
python3 -m myna decompile script.py -o script.myna

# Ultra-compact decompilation (with local variable minification)
python3 -m myna decompile -m script.py -o script.min.myna

# Compare token & character efficiency
python3 -m myna stats examples/books_api.myna

# Report declared/inferred Python & JavaScript support
python3 -m myna targets examples/demo.myna

Multi-file programs

myna run gives relative imports a package context, so a program can be split into sibling .myna files:

# main.myna
<.util:{slug}
p(slug("Hello World"))
# util.myna
@slug(text:s)->s { ^ text.lower().replace(" ", "-") }
  • <.util:{slug} → util.myna beside the importing module.

  • <.pkg.helper:{parse} → pkg/helper.myna; pkg may have an __init__.myna or be a plain directory (namespace package).

  • <.util (no {...} list) binds the imported module object.

  • Absolute imports (<json, <mypkg>alias) keep their normal Python meaning.

  • Imported files are compiled on first import and cached by Python's import system.

  • myna run --module-root DIR (or MYNA_MODULE_ROOT=DIR) resolves the entry file's relative imports from DIR instead of the entry's own directory. For the usual src/ + tests/ layout this removes the need for a symlink:

    python3 -m myna run --module-root . tests/run_tests.myna
    

    Modules imported from that root still resolve their own relative imports from their own directory. With a module root set, the entry's own directory is not searched, so a file beside the entry is imported by its path from the root (e.g. <.tests.harness).

  • myna bundle src/main.myna -o app.py embeds the whole relative-import graph in one standalone Python file. It runs with a plain python3 and does not need myna installed; absolute imports still come from the environment.

  • myna bundle src/main.myna --zipapp -o app.pyz writes a runnable, executable zipapp containing real module files (python3 app.pyz). It is reproducible: rebuilding the same sources produces identical bytes. Without -o, the archive lands next to the entry file as <name>.pyz. --module-root applies to bundling too.

  • myna compile still compiles one file at a time. If you use relative imports, the emitted .py files must be placed in a matching Python package.

  • For -t js, each relative import becomes a relative ES module specifier (./util.js, or ./util.mjs when the output ends in .mjs) and every top-level binding is exported. Compile the files into a mirrored tree, or let myna run -t js do it. Node treats a .js file containing import/export as CommonJS unless the project sets "type": "module", so prefer .mjs outputs or add that to the project's package.json. myna bundle remains Python-only.

JavaScript target

myna compile -t js and myna run -t js emit ES modules. JavaScript is a bounded target: Myna semantics are Python semantics, so the generator inlines __myna_* helpers for truthiness, equality, %, //, #, <-, indexing, slicing, and printing. The runtime floor is Node 20.11+ (import.meta.filename backs the @main guard).

Unsupported constructs fail with a compile-time TargetError instead of producing wrong output:

  • single-file bundling for JavaScript (myna bundle is Python-only; use myna compile -t js over the tree or myna run -t js);
  • star imports (<math:{*});
  • multiple inheritance, class decorators, and method decorators;
  • builtins with no faithful JavaScript equivalent (@open, @ord, @id, …);
  • Python standard-library imports (they are not rewritten for Node).

Known representation limits: JavaScript has one number type (no int/float split or arbitrary-precision integers), tuples and lists are both arrays, dictionary keys are JavaScript property names (string-coerced), with is approximated with try/finally + .close(), keyword arguments to user functions become a trailing object, f-string format specs beyond .Nf are not translated, === maps to Object.is (so primitive identity compares by value), ordered comparisons use JavaScript coercion when operand types differ, and bitwise operators use 32-bit JavaScript semantics. @main compiles to an import.meta.filename === process.argv[1] guard (Node's __main__ equivalent), so an imported module's entry block stays dormant. myna targets reports whether a file generates for a target; the test suite also executes the Node output and runs node --check on every generated file.


Token & Character Efficiency Benchmarks

Measured by compiling each example to Python and running python3 -m myna stats on the generated file (so the Myna columns reflect the decompiler's compact and -m modes). Counts use the built-in bpe-approx estimator unless tiktoken is installed:

python3 -m myna compile examples/demo.myna -o /tmp/demo.py
python3 -m myna stats /tmp/demo.py

Running stats directly on a .myna file instead compares the generated Python against that file as written, so its Myna counts will differ from the table.

Example Program Python Tokens / Chars Myna (Compact) Myna (Ultra-Compact -m)
examples/demo.myna (Async Task Pipeline) 517 toks / 953 chars 271 toks (-47.6%) / 463 chars (-51.4%) 247 toks (-52.2%) / 397 chars (-58.3%)
examples/rest_api.myna (Todo HTTP REST API) 4,105 toks / 8,011 chars 2,183 toks (-46.8%) / 3,932 chars (-50.9%) 2,045 toks (-50.2%) / 3,573 chars (-55.4%)
examples/books_api.myna (Library Catalog API) 4,402 toks / 8,515 chars 2,371 toks (-46.1%) / 4,381 chars (-48.5%) 2,289 toks (-48.0%) / 4,104 chars (-51.8%)

Language Cheat Sheet

Feature Myna Syntax Python Equivalent JavaScript Equivalent
Literals T, F, N, U, _ True, False, None, None, pass true, false, null, undefined, /*noop*/
Types i, f, s, b, B, A, T?, [T], {K:V} int, float, str, bool, bytes, Any, T | None, list[T], dict[K, V] (Type annotations stripped in JS)
Imports <os, numpy>np / <mod:{a, b>c} import os, numpy as np / from mod import a, b as c import * as ... / import { a, b as c } from ...
Targets @target(py) / @target(py) { ... } Python-only module / Python-only block JS-only module / JS-only block
Functions @f(a:i, b=1)->i { ^a+b } or @f(a)=>a+1 def f(a: int, b=1) -> int: return a + b function f(a, b = 1) { return a + b; }
Async / Gen ~@f / ~expr / *@gen / ^*val async def / await / generator / yield async function / await / function* / yield
Classes $C < Base { @init(x){ .x=x } } class C(Base): def __init__(self, x): self.x = x class C extends Base { constructor(x) { this.x = x; } }
Dataclasses $$User(id:i, name:s="anon") @dataclass class User: ... class User { constructor(id, name = "anon") ... }
Dict Shorthands {.id, .title, =name, ok: T} {"id": self.id, "title": self.title, "name": name, "ok": True} ({id: this.id, title: this.title, name, ok: true})
Key Lookup d$key / d$?key ?? "def" d["key"] / d.get("key") or "def" d["key"] / d.get("key") ?? "def"
Branching ? c1 {...} :? c2 {...} : {...} if c1: ... elif c2: ... else: ... if (c1) {...} else if (c2) {...} else {...}
Pattern Match ?? v { 0 => {...}; x ? x>0 => {...}; _ => {...} } match v: case 0: ... case x if x > 0: ... case _: ... Block-scoped pattern & guard dispatch
Loops % x <- 0..10 { ... } / %? cond { ... } for x in range(10): ... / while cond: ... for (let x = 0; x < 10; x += 1) / while (cond)
Comprehensions [x*2 | x <- items ? x > 0] [x * 2 for x in items if x > 0] items.filter(x => x > 0).map(x => x * 2)
Exceptions !{ ... } !!e:ValueError { ... } !: { ... } try: ... except ValueError as e: ... finally: ... try { ... } catch (e) { ... } finally { ... }
With / Assert !& f=open(p) { ... } / !? cond, "msg" with open(p) as f: / assert cond, "msg" Scoped try/finally .close() / if (!cond) throw ...
Built-in Aliases p, #x, @j, @J, @u8, @u8d, @srt, @sum print, len(x), json.loads, json.dumps, .encode, .decode, sorted, sum console.log, len, JSON.parse, JSON.stringify, TextEncoder, TextDecoder, .sort, .reduce

See SPEC.md for the complete language specification and skills/myna/SKILL.md for the AI agent skill file.


Running Tests

python3 -m unittest discover -s tests -v

Versioning & Design Decisions

Releases follow the policy in VERSIONING.md: during 0.x, patches are correctness fixes and release hygiene, minors carry new syntax, new capabilities, or intentional behavior changes, and 1.0 is gated on a documented, executable parity matrix. The accepted decisions behind the targets are recorded in DECISIONS.md.


License

MIT

Metadata

Release files for myna-lang 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for myna-lang 0.5.0
File Size Uploaded Provenance Actions
myna_lang-0.5.0.tar.gz 117.4 kB With provenance Details for myna_lang-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for myna-lang 0.5.0
File Interpreter ABI Platform Actions
myna_lang-0.5.0-py3-none-any.whl Python 3 none any Details for myna_lang-0.5.0-py3-none-any.whl

Total release size: 199.7 kB

Release files / myna_lang-0.5.0.tar.gz

Download URL myna_lang-0.5.0.tar.gz
Size 117.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bb81cac62bd5ac9b3663c4e2681bf72f3f64794b0fb313a0e83f77de7ba7631d
BLAKE2b-256 checksum
How to use checksums
1b648ddc24dbfcb8ec3772ed5e0a232a2134bb86004f03c051057be95bab3751
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / myna_lang-0.5.0-py3-none-any.whl

Download URL myna_lang-0.5.0-py3-none-any.whl
Size 82.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
580b5682223b4b48ec41e0541f46a5eec1cb303ec978ab7f22b385019b791f4b
BLAKE2b-256 checksum
How to use checksums
0eaeafd1ce263009a30dfeba57a4f6a2ee4d2a119325dc55b9f7e0c42dbb9e23
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for myna-lang 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for myna_lang-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page