Tooling And Examples
Command-Line Tools
Use args or cli for command-line interfaces:
import cli;
let parsed = cli.parseArgs(sys.args(), {
"name": {"type": "string", "required": true},
"verbose": {"type": "bool", "short": "v"}
});
let password = cli.password("Password: ");
cli.command provides source classes for command/option structure.
Source API Documentation
Use geblang doc to generate API reference material from Geblang source
without executing the program:
geblang doc examples/api_docs.gb
geblang doc --format json examples/api_docs.gb
geblang doc --out build/api.md src
The command parses .gb files, reads docblocks, and emits declarations for
functions, classes, interfaces, type aliases, and enums. It also includes
decorator metadata, generic parameters, inheritance, class fields, class
methods, static methods, and interface method signatures.
When a file contains export, only exported declarations are included. This
matches package documentation expectations: private helpers can keep docblocks
for maintainers without appearing in public API output. In scripts or examples
with no export statements, all top-level documentable declarations are
included.
Doc comments immediately before export are attached to the exported symbol,
so this is valid API documentation syntax:
## Lists users for an API endpoint.
export @route("GET", "/users")
func listUsers(): list<string> {
return ["Ada"];
}
Use JSON output for editor integrations, framework discovery tools, or custom documentation pipelines. Use Markdown output when you want a quick reference file that can be checked into project docs or converted by another site generator.
Static Checks
Use geblang check in editors and CI to validate code without executing it:
geblang check src/
geblang check --json src/
geblang check --no-lint src/
geblang check --strict src/
The checker parses files, runs semantic analysis, validates imports through the normal module resolver, verifies declared module names resolve back to their files, reports duplicate module declarations across a checked directory, and reports lint warnings such as unused imports and unreachable statements.
It also performs cross-module symbol resolution: a module.member access or
from module import name is an error when the module does not export that
name. This works for both built-in modules and your own modules across a
multi-file project, so a typo like io.foobar() or an outdated API call is
caught before you run anything:
$ geblang check app.gb
app.gb:2:4: error[import]: io has no exported member foobar
Member checks resolve relative to each file and follow local scope, so a local
variable that shadows a module name (for example a list called errors) is not
mistaken for the module.
The same resolution covers methods on your own classes: calling a method that does not exist on a typed instance's class - across its parent chain and implemented interfaces, including classes imported from other modules - is an error:
$ geblang check app.gb
app.gb:6:3: error[semantic]: Circle has no method bogus
The method check is conservative to avoid false positives: it stays silent when
the receiver's type is not a statically known class, when the class (or any
ancestor) defines __call, when the class carries decorators that may inject
members, or when any part of the hierarchy cannot be resolved.
These checks also run inside class method and constructor bodies, not just
top-level and free-function code. Inside a method, this is typed as the
enclosing class, so member access and argument types on this.field and on
typed locals are validated, and a return expression is checked against the
method's declared return type. Calls on this stay conservative: a missing
method on this is not flagged (a subclass may provide it), while the
arguments of a method that does exist are still validated.
A typo on a built-in type's method - for example "x".fooBar() or
(42).nope() - is also an error, checked against the authoritative
built-in method set for each type:
$ geblang check app.gb
app.gb:1:5: error[semantic]: string has no method fooBar
Calling a function that is not defined - not a top-level function, imported name, class constructor, in-scope variable, or built-in - is an error as well:
$ geblang check app.gb
app.gb:1:1: error[type]: unknown bytecode function notAThing
A bare type name in an annotation - parameter, return, field, variable, generic
argument, nullable, union, catch clause, or as cast - that resolves to no
known type (primitive, declared class, interface, enum, type alias, in-scope
generic type param, or built-in error class) is an error, at both check and
compile time, so a typo in a type hint is caught before you run:
$ geblang check app.gb
app.gb:1:8: error[semantic]: unknown type "Reqeust" in parameter req of function handle
A module-qualified type name (mod.TypeName) whose module is a resolved import
but does not export that name is also flagged, by geblang check:
$ geblang check app.gb
app.gb:8:13: error[type]: image has no exported type NopeType
--no-lint disables warning rules while keeping parse, semantic, import, and
module-layout validation. JSON output includes severity, rule, file,
line, column, and message fields so tools can route errors and warnings
separately.
What an error means versus a warning
geblang check follows one contract so its result lines up with the rest of
the toolchain:
- An error is code both execution backends reject. Anything
geblang checkreports as an error also failsgeblang test,geblang run, andgeblang build. Fix errors before running anything. - A warning is advisory and never changes whether code runs. By default a
warning does not affect the exit code; pass
--strictto make warnings exit non-zero in CI.
One warning rule bridges the two execution backends. Geblang runs on a tree-
walking evaluator (geblang test) and a bytecode VM (geblang run, geblang build). When a construct runs on the evaluator but the bytecode VM cannot
build it yet, geblang check reports a vm-unsupported warning instead of an
error:
$ geblang check app.gb
app.gb: warning[vm-unsupported]: bytecode compiler does not support <construct> yet
The code is valid and runs under the evaluator, so this is not an error; the
warning tells you geblang run / geblang build need --disable-vm for that
file until the VM gains support. This keeps geblang check in agreement with
geblang test while still surfacing what would block a release build.
A match over an enum that omits a variant and has no default is reported as
match-nonexhaustive, naming the missing variants:
$ geblang check app.gb
app.gb:5:12: warning[match-nonexhaustive]: match on enum 'Color' is not exhaustive: missing Blue (add the missing case(s) or a 'default:' case)
It is a warning, not an error: the code still runs and throws MatchError only
if an unhandled value reaches the match. See chapter 4 for the exhaustiveness
rules (guards do not count as covering a variant).
Introspection Builtins
Two builtins help inspect values at runtime, on both execution backends:
dir(value)returns the sorted list of method names callable on a value.dump(value)returns a type-annotated debug string for a value.
import io;
io.println(dir([1, 2, 3])); # ["all", "any", "append", ...]
io.println(dump({"a": 1})); # dict{string("a"): int(1)}
io.println(dump([1, "x"])); # list[int(1), string("x")]
dir() with no argument lists the names in the current scope and is available
only in the REPL/evaluator.
Module Invocation
Executable modules expose main(args) and can be launched with -m:
geblang -m app.cli --name Ada
geblang -m http.server 8080
This is useful for source-stdlib utilities and package-local tools because it uses normal module resolution instead of requiring a wrapper file.
Documentation Website
The reference manual website is generated from docs/user/*.md, configured
source API documentation roots, and curated runnable examples from
docs/examples/:
make docs
Static HTML is written to docs/site/. Open docs/site/index.html in a
browser or serve the directory with any static file server. By default,
make docs also parses stdlib/ and adds generated API pages under
docs/site/api/. It also parses structured file docblocks from
docs/examples/**/*.gb and adds example source pages under
docs/site/examples/.
Override the generated API inputs when building project-local docs:
make docs DOCS_API_SRC="src examples/api_docs.gb"
Override the examples tree when building docs for another project:
make docs DOCS_EXAMPLES_SRC="docs/examples"
Command Help
Use top-level help to list commands:
geblang --help
geblang help
Every command also supports local help with usage examples:
geblang test --help
geblang check --help
geblang build --help
Shell Completion
Enable bash tab-completion for subcommands:
source <(geblang completion bash)
Add that line to ~/.bashrc to make it permanent. With completion
enabled, geblang li<tab> completes to geblang licenses; the first
argument completes against the subcommand list and later arguments
complete filenames. Regenerate after upgrading so the command list
stays current.
Third-Party Notices
geblang licenses prints the assembled third-party attribution text.
On an interactive terminal it pages the output through $PAGER (falling
back to less -R, then more); when piped or redirected it writes
plain text, so geblang licenses > NOTICES.txt works unchanged. Use
--no-pager to force plain output on a terminal.
Standalone Executables
Use geblang build to package a Geblang application as a self-contained
binary that needs no Geblang installation on the target machine:
geblang build --entry myapp.main --out ./dist/myapp [<package-dir>]
The output binary embeds all source modules and precompiled bytecode. See the Bundling chapter for the full package layout, how bundling works, and complete examples.
Docker Binary Build
Build a distributable binary and bundled stdlib through Docker:
make docker-build
The target writes:
build/geblang
build/stdlib/
This build path only requires Docker and make on the host. It is intended for
reproducible binary builds and release packaging. Local development can use
make build instead.
To build both the binary and the VS Code extension together:
make compose-build
To build only the VS Code extension:
make vscode-build
See VS Code Extension for full installation and usage details.
Example Scripts
Useful examples:
geblang examples/core.gb
geblang examples/functions.gb
geblang examples/classes.gb
geblang examples/generics.gb
geblang examples/generators.gb
geblang examples/collections_module.gb
geblang examples/api_docs.gb
geblang examples/markdown.gb
geblang examples/async/file.gb
geblang examples/async/io.gb
geblang examples/async/http.gb
geblang examples/async/sockets.gb
geblang examples/async/streams.gb
geblang examples/async/network_engine.gb
geblang examples/source_web_router.gb
geblang examples/web_decorators.gb
geblang examples/expense_tracker/src/main.gb
examples/http_server.gb starts a blocking HTTP server on
127.0.0.1:8080.
Project Commands
make build
make test
make docs
make docker-build
make clean
Use geblang init --name package.name to create a package manifest.
Claude Code Skill
The toolchain ships a Claude Code skill that equips Claude to author and operate
Geblang: the language idioms and gotchas, the standard-library surface, and the
geblang CLI (run, test, check, fmt, build, doc). It is bundled at
.claude/skills/geblang/ as a top-level SKILL.md plus reference files for the
language, the stdlib, and the toolchain.
Claude Code discovers it automatically as a project skill when you open a checkout of the toolchain repository. To make it available in any project, copy it into your user skills directory:
cp -r .claude/skills/geblang ~/.claude/skills/geblang
The skill directs Claude to confirm exact signatures with geblang doc and
geblang help rather than guessing, so it stays accurate against your installed
version.