GENO

Docs/Reference

Supported Targets

Source of truth: targets.toml in the project root. This document is manually synced with that file.

Geno compiles to multiple backends. Each target defines a runtime, available capabilities, and which builtins are accessible. The typechecker uses the target profile to reject APIs that aren't supported at compile time.

Target vocabulary

Geno uses two related but distinct concepts. Target-aware checks validate both builtin availability and whether the checked AST can be lowered by the target's canonical backend. Validation happens in memory: it writes no artifact, executes no generated code, and grants no capabilities. See the target-aware check behavior contract.

The two concepts are:

  • Execution targets (geno check --target, geno test --target): python-cli, node-cli, browser, python-hosted. These describe the runtime environment and determine which builtins are available.
  • Compilation backends (geno compile --target): python, js. These select the output language.

The execution target determines builtin availability at typecheck time. The compilation backend determines the output format. For example, node-cli uses the js backend but has a different set of available builtins than browser.

For programs shared with JavaScript, portable Int values are limited to -(2^53 - 1) through 2^53 - 1. JavaScript rejects results outside that range. Python and interpreter execution support the separately configured max_integer_bits limit. See Portable Runtime Semantics.

JavaScript target checks reject integer literals and integer pattern literals outside that exact range. Target checks also reject source names, module/export names, and record fields that the selected backend cannot represent safely. Python keywords and dunder record fields are invalid for Python targets; JavaScript keywords, runtime discriminator fields, and prototype-sensitive fields are invalid for JavaScript targets.

Manifest target

Set targets in geno.toml to check every declared target profile:

entrypoint = "Main"
targets = ["python-cli", "node-cli"]

An explicit geno check --target TARGET checks one execution target, while still validating every target name in the manifest so typos fail closed. With no explicit or manifest target, geno check, geno test, and editor diagnostics validate Python lowering when the selected entrypoint defines main, matching the default geno run. Libraries without their own main remain permissive; an imported main does not make a library runnable. Targetless geno.api.check() remains an interpreter-oriented language check without a lowering guarantee.

geno compile --target python|js retains its output-backend selector. It checks the compatible execution profiles declared by the manifest, falling back to python-cli or node-cli when no compatible profile is declared. Use --profile for an explicit compatible override. Browser output always uses geno build; raw JavaScript compilation does not install the browser capability bootstrap or HTML wrapper.

For geno test, the target profile is applied before execution; examples and test blocks still run through the interpreter. Backend parity is covered by the pytest backend parity suites.

Targets

TargetRuntimeEntry CommandCompile Command
python-cliPythongeno rungeno compile -o app.py
node-cliNode.jsgeno compile --target js -o app.js && node app.jsgeno compile --target js -o app.js
browserBrowsergeno buildgeno build -o dist/
python-hostedPythongeno servegeno compile -o handler.py

python-cli

CLI and automation scripts running on the Python interpreter. Full access to filesystem, HTTP, process execution, and environment variables when capabilities are granted.

Capabilities: fs, http, process, stdin, env, clock, random, print, regex, serve

node-cli

CLI and automation scripts compiled to Node.js. Filesystem access uses Node.js fs; HTTP uses an internal synchronous CommonJS/ES-module bridge gated solely by the http capability. The bridge does not expose process execution to Geno code: request data travels over stdin, responses are streamed to the collection limit, redirects and resolved addresses are policy-checked, and cross-origin redirects discard caller headers. http_request preserves ordered duplicate header pairs and returns scheme, transport, and network-policy failures as Err. User-authored process execution is not supported on this target.

Capabilities: fs, http, env, clock, random, print, regex

browser

Browser apps compiled to static HTML/JS artifacts with a canvas. The default output is a dist/ directory; use --single-file when you need one HTML file. No filesystem or environment variable access. Graphics and input builtins are available. Generated browser artifacts grant the browser target capabilities at startup. HTTP is available through browser networking APIs and is subject to the browser's CORS policy.

Capabilities: http, clock, random, print, regex

python-hosted

Server handlers running in a hosted Python environment. Similar to python-cli but process execution is not allowed (security boundary).

Capabilities: fs, http, env, clock, random, print, regex, serve

Builtin Availability Matrix

Legend

  • Available - Always available, no capability needed
  • Cap: X - Available when --cap X is granted
  • -- - Unavailable on this target (compile-time error)

Pure Builtins (available on all targets)

The following builtins require no capabilities and work on every target:

List operations: length, head, tail, append, concat, set_at, slice, filter, map, fold, contains, take_while, all, sort, sort_by, reverse, zip, enumerate, flat_map

String operations: split, join, trim, to_lower, to_upper, replace, ends_with, split_once, starts_with, to_chars, sort_strings, contains_substring, repeat_string, substring, format, char_code, from_char_code

Math operations: add, subtract, multiply, divide, sqrt, floor, ceil, round, max, abs, square, clamp, bit_or

Type predicates: is_sorted, is_positive, is_numeric_string, is_permutation

Conversions: parse_int, parse_float, to_string, float_to_int, int_to_float

Range: range

Option operations: is_some, is_none, unwrap, unwrap_or

Map operations: map_insert, map_get

Array operations: array_new, array_from_list, array_get, array_set, array_length, array_to_list, array_fill, array_copy

Vec operations: vec_new, vec_from_list, vec_push, vec_pop, vec_get, vec_set, vec_length, vec_to_list

MutableMap operations: mutable_map_new, mutable_map_set, mutable_map_get, mutable_map_contains, mutable_map_delete, mutable_map_size, mutable_map_keys

Set operations: set_new, set_from_list, set_add, set_remove, set_contains, set_size, set_to_list, set_union, set_intersection

JSON/Data: json_parse, json_stringify, csv_parse, csv_parse_with_headers, toml_parse

Capability-Gated Builtins

BuiltinCapabilitypython-clinode-clibrowserpython-hosted
printprintCap: printCap: printCap: printCap: print
clock_nowclockCap: clockCap: clockCap: clockCap: clock
clock_formatclockCap: clockCap: clockCap: clockCap: clock
clock_parseclockCap: clockCap: clockCap: clockCap: clock
clock_elapsedclockCap: clockCap: clockCap: clockCap: clock
datetime_nowclockCap: clockCap: clockCap: clockCap: clock
datetime_formatclockCap: clockCap: clockCap: clockCap: clock
datetime_parseclockCap: clockCap: clockCap: clockCap: clock
datetime_elapsedclockCap: clockCap: clockCap: clockCap: clock
random_intrandomCap: randomCap: randomCap: randomCap: random
random_floatrandomCap: randomCap: randomCap: randomCap: random
math_random_intrandomCap: randomCap: randomCap: randomCap: random
math_random_floatrandomCap: randomCap: randomCap: randomCap: random
regex_matchregexCap: regexCap: regexCap: regexCap: regex
regex_find_allregexCap: regexCap: regexCap: regexCap: regex
regex_replaceregexCap: regexCap: regexCap: regexCap: regex

Target-Restricted Builtins

BuiltinCapabilitypython-clinode-clibrowserpython-hosted
sleep_msclockCap: clock------
fs_read_textfsCap: fsCap: fs--Cap: fs
fs_write_textfsCap: fsCap: fs--Cap: fs
fs_list_dirfsCap: fsCap: fs--Cap: fs
fs_existsfsCap: fsCap: fs--Cap: fs
fs_metadatafsCap: fsCap: fs--Cap: fs
fs_symlink_metadatafsCap: fsCap: fs--Cap: fs
fs_canonicalizefsCap: fsCap: fs--Cap: fs
http_fetchhttpCap: httpCap: httpCap: httpCap: http
http_posthttpCap: httpCap: httpCap: httpCap: http
http_requesthttpCap: httpCap: httpCap: httpCap: http
http_listenserveCap: serve----Cap: serve
http_routeserveCap: serve----Cap: serve
http_respondserveCap: serve----Cap: serve
execprocessCap: process------
exec_with_inputprocessCap: process------
spawnprocessCap: process------
spawn_with_inputprocessCap: process------
stdin_read_allstdinCap: stdin------
env_getenvCap: envCap: env--Cap: env
env_get_orenvCap: envCap: env--Cap: env
cli_argsenvCap: envCap: env--Cap: env

Browser-Only Builtins

These builtins are only available on the browser target (app mode with init/update/render):

Builtinpython-clinode-clibrowserpython-hosted
clear_screen----Available--
draw_rect----Available--
draw_rect_outline----Available--
draw_circle----Available--
draw_line----Available--
draw_text----Available--
screen_width----Available--
screen_height----Available--
is_key_down----Available--
is_key_pressed----Available--
mouse_x----Available--
mouse_y----Available--
is_mouse_down----Available--
is_mouse_clicked----Available--
get_text_input----Available--
clear_text_input----Available--

Using Targets

Checking against a target

geno check --target browser myapp.geno

If myapp.geno calls fs_read_text, the typechecker will reject it:

error: `fs_read_text` is not available on target `browser`
  --> myapp.geno:5:12
  |
5 |     let data = fs_read_text("config.txt")
  |                ^^^^^^^^^^^^
  = help: `fs_read_text` requires the `fs` capability, which is not supported
    on the `browser` target. Use `python-cli` or `node-cli` instead.

Compiling for a target

# Python CLI
geno compile -o app.py && python app.py --cap fs --cap http

# Node.js CLI
geno compile --target js -o app.js && node app.js

# Browser app
geno build -o dist/

# Hosted server
geno serve --cap fs --cap http

Rendered from docs/SUPPORTED_TARGETS.md in the Geno repository.