Skip to content

ason

GitHub →

ason is a fast, lightweight project scaffolding tool that transforms templates into fully-formed projects. Built in Go with minimal dependencies, it offers a Jinja2-like templating syntax (powered by Pongo2), a local template registry, interactive terminal prompts, and shell autocompletion.

ason works in two modalities:

  • As a CLI — register templates and scaffold projects from the terminal.
  • As a Go library — embed template generation directly in your own Go programs via a public API.
This documentation describes ason v0.3.0 (the “Library Export” release). The binary command is ason. v0.3.0 is backward compatible with v0.2.x — existing templates and CLI usage are unchanged.

Features

  • Jinja2-like templating — familiar {{ variable }} syntax via Pongo2 (filters, loops, conditionals, inheritance, includes).
  • Template registry — register, list, and reuse templates locally (XDG Base Directory compliant).
  • Interactive prompts — terminal UI built with Bubble Tea.
  • Library API — generator and registry types with context.Context support and pluggable engines.
  • Shell autocompletion — tab completion for bash, zsh, and fish.

Install

macOS (Homebrew, recommended)

brew tap madstone-tech/tap
brew install ason
ason --version

Shell completions are installed automatically with Homebrew.

Linux (prebuilt binary)

# AMD64
curl -sL https://github.com/madstone-tech/ason/releases/latest/download/ason_Linux_x86_64.tar.gz | tar xz
sudo mv ason /usr/local/bin/

# ARM64
curl -sL https://github.com/madstone-tech/ason/releases/latest/download/ason_Linux_arm64.tar.gz | tar xz
sudo mv ason /usr/local/bin/

From Go

go install github.com/madstone-tech/ason@latest

On Windows, download the latest .zip from GitHub Releases, extract it, and add it to your PATH.

Use as a CLI

# View available commands
ason --help

# Register a template under a name
ason register golang-service ~/templates/golang-service --description "Go service template"

# List registered templates (add --format json for machine-readable output)
ason list
ason list --format json

# Generate a project from a registered template
ason new golang-service my-service

# Pass variables on the command line
ason new golang-service my-service --var name=MyService --var author=Alice

# Preview without writing any files
ason new golang-service my-service --dry-run

# Generate straight from a local template directory (no registration needed)
ason new ./my-template ./output

# Validate a template before using it
ason validate ~/templates/golang-service

# Remove a template from the registry
ason remove golang-service

Command reference

CommandDescription
ason new <template> <output>Generate a project from a registered name or a local path. Flags: --var name=value (repeatable), --dry-run
ason register <name> <path>Register a template directory. Flag: --description "..."
ason listList registered templates. Flag: --format json
ason validate <path>Validate a template’s syntax and structure
ason remove <name>Remove a template from the registry (idempotent)
ason completion <bash|zsh|fish>Generate a shell completion script (written to stdout)
ason --versionShow version

Template syntax (Pongo2)

Templates use Pongo2, a Jinja2-like engine. Variables are substituted in file contents and paths at generation time:

Hello {{ name }}                 {# variable #}
{{ name|upper }}                 {# filter #}
{% for item in items %}- {{ item }}{% endfor %}   {# loop #}
{% if user.is_admin %}admin{% else %}user{% endif %}   {# conditional #}
{% extends "base.tmpl" %}        {# inheritance #}
{% include "header.tmpl" %}      {# includes #}

Shell autocompletion

Completion covers template names, file/directory paths, command flags, and variable names.

ason completion bash > ~/.local/share/bash-completion/completions/ason
ason completion zsh  > ~/.zfunc/_ason          # ensure fpath includes ~/.zfunc
ason completion fish > ~/.config/fish/completions/ason.fish

For Oh My Zsh, install the script as a custom plugin (~/.oh-my-zsh/custom/plugins/ason/_ason) and add ason to your plugins=(...) list.

Registry & template naming

The registry is stored at ~/.local/share/ason/registry.toml by default. Template names must be valid Go identifiers — letters, digits, and underscores, not starting with a digit:

  • Valid: my_template, golang_service, asonApp
  • Invalid: my-template (hyphen), 123app (leading digit)

Use as a Go library

go get github.com/madstone-tech/ason
import "github.com/madstone-tech/ason/pkg"

Generator

Render templates programmatically, with context.Context support for cancellation and timeouts.

package main

import (
	"context"
	"log"
	"time"

	"github.com/madstone-tech/ason/pkg"
)

func main() {
	engine := pkg.NewDefaultEngine()
	gen, err := pkg.NewGenerator(engine)
	if err != nil {
		log.Fatal(err)
	}

	variables := map[string]interface{}{
		"project_name": "my-app",
		"author":       "Alice",
		"version":      "1.0.0",
	}

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := gen.Generate(ctx, "./template", variables, "./output"); err != nil {
		log.Fatal(err)
	}
}

Methods: NewGenerator(engine Engine) (*Generator, error), Generate(ctx, templatePath, variables, outputPath) error, GetEngine() Engine.

Registry

Manage templates programmatically with XDG-compliant storage.

reg, err := pkg.NewRegistry()                       // default ~/.local/share/ason/registry.toml
// reg, err := pkg.NewRegistryAt("/custom/path.toml") // custom location
if err != nil {
	log.Fatal(err)
}

reg.Register("api_service", "/templates/api", "API service template")
templates, _ := reg.List() // []TemplateInfo, sorted
reg.Remove("api_service")  // idempotent

Methods: NewRegistry(), NewRegistryAt(path), Register(name, path, description), List(), Remove(name).

Custom engines

The Engine interface (Render, RenderFile) is pluggable — implement it to swap out Pongo2, or use pkg.NewDefaultEngine() for the built-in Pongo2 engine.

Error handling & thread safety

The library exports typed errors that support errors.Is and errors.Unwrap: context.Canceled, context.DeadlineExceeded, *InvalidArgumentError, *InvalidPathError (path-traversal prevention), *VariableValidationError, *GenerationError, and *EngineError.

All public types are thread-safe — Generator and Registry are mutex-protected for concurrent use; custom Engine implementations must provide their own thread safety (the default Pongo2 engine is thread-safe).

See the GoDoc for full API details.

Requirements

Go 1.21+ · Linux, macOS, or Windows · no external CLI dependencies. ason is MIT licensed and maintained in the madstone-tech GitHub org.