Provides coding and architectural support for Mach language projects.
Install
mkdir -p .claude/skills/mach && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17824" && unzip -o skill.zip -d .claude/skills/mach && rm skill.zipInstalls to .claude/skills/mach
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when writing, editing, or reviewing Mach (.mach) source files. Covers the full language: project/module structure, use/fwd imports and re-exports, the shadow-module pattern, all declaration forms (def, rec, uni, fun, ext fun, val/var, test), the type grammar with the ^ secret qualifier, literals, operators and casts, statements, docstring conventions, stdlib idioms (Result/Option, std.print), the comptime channel ($mach.*/$project.*/$bin.* reads, $if/$or, $each, intrinsics, comptime parameters, variadic packs), #[...] decorators, and inline assembly (asm x86_64/aarch64/riscv64).Key capabilities
- →Write Mach (.mach) source files.
- →Edit Mach source files according to language rules.
- →Review Mach source files for correctness and style.
- →Understand Mach project and module structure.
- →Implement comptime features and inline assembly.
How it works
This skill provides guidance on Mach language rules, covering syntax, module structure, declarations, and advanced features like comptime and inline assembly. It emphasizes explicit typing and adherence to specific idioms.
Inputs & outputs
When to use mach
- →Writing Mach code
- →Reviewing Mach language syntax
- →Structuring Mach modules
About this skill
Mach
Mach is a low-level, explicitly-typed language: no type inference, no garbage
collection, no hidden control flow. Files use .mach. This skill is the fast
path for authoring correct Mach; doc/language/ in the Mach repository is the
authoritative reference and wins on any disagreement.
Hard rules - get these right
- No type inference. Every binding declares its type.
val x = 42;is an error; writeval x: i64 = 42;. - No compiler-known type aliases.
bool,usize,str,charare stdlibdefs, not built-ins. Import them before use (use std.types.bool.bool;).true/falseare stdlibvals (1/0); comparisons and logical operators produceu8. - Decorators are
#[...]attributes on the line(s) above a declaration:#[symbol("main")],#[inline],#[align(64)]. The backtick form was removed in v2.4.0 and is a migration error - never emit backticks. - File embeds are typed byte arrays.
#[embed("asset.bin")]applies only to an uninitializedvaldeclared as[_]u8(length from the file) or[N]u8(length checked). The path is relative to the declaring source file; bytes become read-only data at compile time, with no runtime I/O. - Variadics are comptime packs. A trailing
va: ...parameter, consumed by$each a in va. There is nova_list/va_start/va_arg. A bare...is a different thing entirely: the C-variadic marker, legal only on anext fun(ext fun open(path: *u8, flags: i32, ...) i32), and a removed-syntax error anywhere else. - Strings are
*u8, single-line."hello"is a pointer to null-terminated bytes. No fat-pointer string type (strisdef str: *char;); no multi-line string literal - use\nescapes. - No tagged unions, no
match. A discriminated value is areccarrying a discriminator plus a payloaduni; consumers branch withif/or. This is exactly how stdlibResult[T, E]is built. - No compound assignment.
+=etc. do not exist; writex = x + 1;. fwdis bare and always public (nopub fwd).ext funis the only body-less function form.
Project and module structure
A project has a mach.toml at its root; [project] id roots every module
path. A file at src/foo/bar.mach in project id = "myproj" is the module
myproj.foo.bar. There is no this. self-prefix - always use the full
project-rooted path, including for sibling modules. A one-segment use <id>;
resolves only when that project declares a [project] module surface file
(e.g. a library glfw imported as use glfw;); std does not - always
import full std.* paths.
An artifact build roots its module graph at [artifact.*].entry and compiles only
that module plus its active transitive use/fwd dependencies. A sibling source
file is not part of the build cell merely because it is under [project].src, so
one project may hold artifacts for disjoint targets. mach test deliberately roots
at every own-source module so it can collect otherwise-unreferenced tests.
A file reads top-down: module docstring, use/fwd lines, declarations.
use - private import
use std.types.size; # binds module `size`; use as size.usize
use sz: std.types.size; # module under alias; use as sz.usize
use std.types.size.usize; # binds the symbol; use bare as usize
The resolver binds whatever the path ends at: a module (members reached
qualified) or a symbol (used bare). Importing a module does not pull its
members in unqualified. No splat, no use foo.{a,b} - one name per line. A
module uses every dependency it directly names, even ones reachable through
a re-export: the dependency graph is visible at the top of every file.
fwd - public re-export
fwd impl.Point; # re-export as Point
fwd Pt: impl.Point; # re-export as Pt
fwd impl.helpers; # a module path re-exports the whole module
Mirrors use grammar; always publishes.
Shadow-module pattern
A surface file foo.mach co-exists with directory foo/ holding split
implementations. The surface uses each split and fwds its public symbols;
consumers use myproj.foo; and never name the splits. Topical splits forward
everything unconditionally; multiplatform splits pick one impl per target:
$if ($mach.build.os == $mach.os.linux) {
use impl: myproj.os.linux;
}
$or ($mach.build.os == $mach.os.windows) {
use impl: myproj.os.windows;
}
$or {
$error("myproj.os: unsupported target");
}
fwd impl.page_size;
Entrypoint and output
An artifact's out is literal across every target it names. A cross-platform
executable therefore uses disjoint artifacts for extension conventions:
out = "bin/app" for non-Windows targets and out = "bin/app.exe" for Windows.
mach init emits that split for binary projects. Do not use one targets = ["*"]
artifact when its output must be directly executable on Windows and elsewhere.
The stdlib provides the platform _start, which calls whatever function
exports the linker symbol main. use std.runtime; is required to link it in
even though nothing references it by name:
use std.runtime;
use std.print;
#[symbol("main")]
fun main(argc: i64, argv: **u8) i64 {
print.println("hello, mach");
ret 0;
}
use std.print; binds the leaf module print (std itself is not in scope).
It exposes print/println (stdout), eprint/eprintln (stderr), and the
format family printf/printlnf/eprintf/eprintlnf - pack-variadic, with
{} holes filled in argument order plus {:x}-style specs ({:X}, {:c},
{:5}, {:<5}, {:08x}; {{/}} for literal braces). All return
Result[usize, str].
Windows executable resources
An executable artifact may declare project-root-relative PE assets:
[artifact.game]
kind = "bin"
entry = "main.mach"
out = "bin/game.exe"
targets = ["*"]
link = []
need = []
icon = "assets/game.ico"
manifest = "assets/game.manifest"
icon is a valid ICO container; manifest is embedded byte-for-byte. Either
adds PE icon/manifest resources plus version information. Version strings come
from [project].version, InternalName/ProductName from the artifact table
key, and OriginalFilename from the resolved output basename. These keys are
accepted but not read on non-Windows targets, and are rejected on static or
shared artifacts. If a build step generates an asset, name that step in
need and make its output exactly match the resource path.
print.printlnf("built {} in {}ms", name, elapsed);
Declarations
Modifiers: pub (public surface; without it a declaration is file-private)
applies to fun, rec, uni, def, val, var; ext (C-ABI external)
applies to functions only.
def - type alias
pub def Age: i64;
pub def BinOp: fun(i64, i64) i64;
Aliases name any type; alias and underlying type are interchangeable.
rec / uni
pub rec Point { x: i64; y: i64; }
pub rec Pair[T, U] { left: T; right: U; } # generic
pub uni Number { i: i64; f: f64; } # fields overlap; size of largest
The compiler does not track which uni field is live. The sum-type idiom
(stdlib Result[T, E] verbatim):
pub rec Result[T, E] {
tag: bool;
value: uni { ok: T; err: E; };
}
Packed layout is not available; #[align(N)] raises a type's or global's
alignment.
fun
pub fun add(a: i64, b: i64) i64 { ret a + b; }
pub fun identity[T](value: T) T { ret value; } # generic; call: identity[i64](42)
pub fun load($order: u8, p: *i64) i64 { ... } # comptime value param (see Comptime)
pub fun sum(va: ...) i64 { # variadic pack (see Comptime)
var t: i64 = 0;
$each a in va { t = t + a; }
ret t;
}
Generic params [T] take types only, no constraints; monomorphized per
instantiation; call sites always supply the types explicitly.
ext fun
#[symbol("write")]
pub ext fun libc_write(fd: i64, buf: *u8, n: i64) i64;
Body-less, ends in ;, C ABI is the contract.
A C-variadic callee ends its parameter list in a bare ..., after at least one
fixed parameter — ext only, call side only (mach defines no va_arg callee):
ext fun open(path: *u8, flags: i32, ...) i32;
Tail arguments get no implicit conversion, so write C's default argument
promotions yourself: an integer narrower than 32 bits and an f32 are rejected
with the cast to apply (x::i32, x::f64), and a secret may not enter a tail.
Declaring a variadic callee at fixed arity instead is silently wrong on Apple
arm64, which passes the whole tail on the stack. See doc/language/ext-fun.md.
Provide the definition at link
time (mach build . -l c, a [link.X] manifest requirement, or an explicit
.o/.obj/.a/.lib/.so/.dylib/.dll). On PE and Mach-O targets, pin each dynamic
import with #[library("name")]. The value is the requirement's stable
library identity (defaulting to the [link.X] table name); exact loader names
remain accepted. A discovered Darwin @rpath/ install name retains its selected
library directory as an LC_RPATH command.
For a bare -l name, every target probes .o/.a; only PE/COFF also probes
the .obj/.lib spellings. Explicit paths retain their spelling so a format
mismatch produces a direct diagnostic.
Windows COFF inputs compiled with C/C++ dllimport may leave __imp_X
undefined. Attribute the real export X normally; the linker strips the object
prefix for loader lookup and points the foreign reference at X's IAT cell. A
direct X reference and __imp_X share one import entry — never map __imp_X as
a separate loader export. If the same link graph instead supplies a strong X,
__imp_X is a local pointer cell initialized to X: it creates no loader import
and needs no #[library] attribution, while direct references still target X.
An import-libra
Content truncated.
When not to use it
- →When working with languages other than Mach.
- →When type inference or garbage collection is expected.
Limitations
- →No type inference is supported.
- →No compiler-known type aliases like `bool` or `usize`.
- →No tagged unions or `match` statements.
How it compares
This skill provides authoritative guidance on Mach's strict, low-level language features, including its explicit typing and lack of type inference, which differs from more permissive languages.
Compared to similar skills
mach side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| mach (this skill) | 0 | 2mo | Review | Advanced |
| software-architecture | 333 | 7mo | No flags | Intermediate |
| codex | 32 | 3mo | Review | Advanced |
| game-development | 70 | 7mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
software-architecture
davila7
Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code, in any case that relates to software development.
codex
Lucklyric
Invoke Codex CLI for complex coding tasks requiring high reasoning capabilities. This skill should be invoked when users explicitly mention "Codex", request complex implementation challenges, advanced reasoning, or need high-reasoning model assistance. Automatically triggers on codex-related requests and supports session continuation for iterative development.
game-development
davila7
Game development orchestrator. Routes to platform-specific skills based on project needs.
senior-fullstack
davila7
Comprehensive fullstack development skill for building complete web applications with React, Next.js, Node.js, GraphQL, and PostgreSQL. Includes project scaffolding, code quality analysis, architecture patterns, and complete tech stack guidance. Use when building new projects, analyzing code quality, implementing design patterns, or setting up development workflows.
command-name
anthropics
This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.
python-project-structure
wshobson
Python project organization, module architecture, and public API design. Use when setting up new projects, organizing modules, defining public interfaces with __all__, or planning directory layouts.