A project scaffolding tool for Go, inspired by gonew with additional features.
- Clone templates from GitHub, Codeberg, or any Git host
- Use local directories as templates
- Automatic module path rewriting in
go.modand all.gofiles - Template variable substitution (
__VarName__→Value) - Initialize git repository with initial commit (optional)
- Support for specific tags (
@v1.0.0), branches (@main), or commits (@abc1234) - Optional string replacement in additional file types
- Go 1.24 or later (for building from source or
go install) - Git (for cloning remote templates)
brew tap oliverandrich/tap
brew install gohatchgo install github.com/oliverandrich/gohatch@latestPre-built binaries for Linux, macOS, and Windows are available on the Releases page.
git clone https://github.com/oliverandrich/gohatch.git
cd gohatch
go build -o gohatch ./cmd/gohatchTo install into your $GOPATH/bin:
go install ./cmd/gohatchgohatch [options] <source> <module> [directory]| Argument | Description |
|---|---|
source |
Template source (see formats below) |
module |
New Go module path |
directory |
Output directory (optional, defaults to last element of module) |
| Flag | Description |
|---|---|
-e, --extension |
Additional file extensions or filenames for module replacement |
-v, --var |
Set template variable (e.g., --var Author="Name") |
-f, --force |
Proceed even if template has no go.mod |
--no-git-init |
Skip git repository initialization |
--keep-config |
Keep .gohatch.toml config file in output |
--dry-run |
Show what would be done without making any changes |
--verbose |
Show detailed progress output |
| Format | Example |
|---|---|
| GitHub shorthand | user/repo |
| Full URL | github.com/user/repo |
| Other Git hosts | codeberg.org/user/repo |
| Specific tag | user/repo@v1.0.0 |
| Specific branch | user/repo@main |
| Specific commit | user/repo@abc1234 |
| Local directory | ./my-template |
Note: gohatch automatically detects whether the version is a tag, branch, or commit hash by querying the remote repository.
Create a new project from a GitHub template:
gohatch user/go-template github.com/me/myappUse a specific tag:
gohatch user/go-template@v1.0.0 github.com/me/myappUse a specific branch:
gohatch user/go-template@main github.com/me/myappSpecify output directory:
gohatch user/go-template github.com/me/myapp ./projects/myappAlso replace module path in config files:
gohatch -e toml -e yaml user/go-template github.com/me/myappReplace in specific files (by exact name):
gohatch -e yml -e justfile -e Makefile user/go-template github.com/me/myappUse a local template:
gohatch ./my-template github.com/me/myappPreview what would be done (dry-run):
gohatch --dry-run user/go-template github.com/me/myappUse a non-Go template (skip go.mod validation):
gohatch --force user/non-go-template github.com/me/myappTemplates can include placeholders that get replaced during scaffolding. Placeholders use dunder-style syntax: __VarName__.
| Variable | Default Value |
|---|---|
ProjectName |
Output directory name |
Use the -v or --var flag to set variables:
gohatch --var Author="Oliver Andrich" user/go-template github.com/me/myappMultiple variables:
gohatch -v ProjectName=MyApp -v Author="Oliver Andrich" user/go-template github.com/me/myappIn your template files:
package main
const AppName = "__ProjectName__"
const Author = "__Author__"After scaffolding with --var Author="Oliver":
package main
const AppName = "myapp"
const Author = "Oliver"Variables are replaced in .go files and any additional extensions or filenames specified with -e.
Each -e pattern is treated as both a potential filename and extension:
ymlmatches files namedymlAND files with.ymlextensionjustfilematches files namedjustfileAND files with.justfileextension
Variables can also be used in directory and file names:
Template structure: After scaffolding:
cmd/__ProjectName__/main.go → cmd/myapp/main.go
__ProjectName___test.go → myapp_test.go
This allows you to create templates where the directory structure adapts to the project name.
Templates can include a .gohatch.toml configuration file to specify default settings. This eliminates the need to pass -e flags manually when using the template.
Create a .gohatch.toml file in your template root:
# Optional: schema version (defaults to 1)
version = 1
# File extensions/names for module path and variable replacement
extensions = ["toml", "yaml", "justfile", "Makefile"]- The config file is automatically read after fetching the template
- Extensions from the config are merged with any
-eflags passed on the command line - The
.gohatch.tomlfile is automatically removed from the output (use--keep-configto retain it)
Template with .gohatch.toml:
extensions = ["toml", "yaml", "justfile"]Now users can simply run:
gohatch user/template github.com/me/myappInstead of:
gohatch -e toml -e yaml -e justfile user/template github.com/me/myappjust build # Build binary to build/gohatch
just test # Run tests
just fmt # Format code
just lint # Run linter
just check # Run fmt, lint, and test
just clean # Remove build artifacts
just install # Install to $GOPATH/bin
just release # Create release with goreleaser
just release-snapshot # Local test build without publishingThis project is licensed under the European Union Public License 1.2 (EUPL-1.2).