Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Makefile CI Build and Test Codacy Security CodeQL Advanced

namegen

A fast, deterministic name generator written in Go.

namegen generates realistic-looking or fictional names across many language families using compiled-in profiles (no runtime plugins). Output can be made fully reproducible via seeds, making it suitable for games, testing, world-building, and data generation.


Features

  • Many language profiles (English, Japanese, Spanish, Nordic, Slavic, Tamil, Nahuatl, and more)
  • Deterministic randomness via seed (-s)
  • Realism control (-realism 0..100)
  • Gender hints (male, female, neutral)
  • Optional surnames by default ( turn them on with -l)
  • Reverse order (last name first)
  • Batch generation (-c)
  • Dev mode whih prints resolved config (-d)
  • Single static binary - no CGO, no .so plugins

Project layout

  • cmd/namegen/ – CLI entrypoint (imports all compiled-in profiles)
  • api/ – profile interface, deterministic RNG helpers, shared utilities
  • plugins/<name>/ – profiles (each registers itself via init())

Build

From repo root:

make build

Output:

$ ls .
bin/namegen

Run

Show help:

$ ./bin/namegen -h

Examples:

# default (english):
./bin/namegen

# choose a profile:
./bin/namegen -mode japanese

# include last name:
./bin/namegen -mode spanish -l

# reverse (last first):
./bin/namegen -mode spanish -l -r

# generate 10 names:
./bin/namegen -mode english -l -c 10

# deterministic (repeatable):
./bin/namegen -mode english -l -s 42 -realism 80

# gender:
./bin/namegen -mode english -gender female -l -realism 90

# prints a list of all available profiles
./bin/namegen -p 

# dev mode prints the config JSON used:
./bin/namegen -mode japanese -l -c 10 -d

Flags

Flag Meaning
-mode <name> Profile/mode name (compiled-in). Defaults to english.
-l Include last name
-r Reverse output order (last first)
-gender <male, female, neutral> Gender hint passed to profile
-family <key> Optional “family override” (profiles may interpret it differently)
-realism 0...100 0 = fictional phonotactics, 100 = curated/real-looking
-s <seed> Seed (0 / omit = random each run)
-c <count> Number of names to generate
-d Dev mode: prints config JSON
-p List all avilable profiles

Available profiles

These are compiled into the binary via blank imports in cmd/namegen/main.go

  • amharic
  • arabic
  • aramaic
  • baltic
  • celtic
  • chinese
  • english
  • farsi
  • filipino
  • french
  • germanic
  • greek
  • hawaiian
  • hebrew
  • hindi
  • igbo
  • indonesian
  • italian
  • japanese
  • kazakh
  • korean
  • malay
  • maori
  • nahuatl
  • nordic
  • portuguese
  • samoan
  • slavic
  • spanish
  • swahili
  • tamil
  • thai
  • turkish
  • uzbek
  • vietnamese
  • yoruba

If you run a mode that doesn't exist, the CLI falls back to english.

How it works

The CLI passes api.ProfileConfig to the selected profile.

  • Profiles call api.NewRand(cfg) which:
    • returns a deterministic RNG when cfg.Seed != 0
    • returns a time-seeded RNG when cfg.Seed == 0
  • Profiles should use api.PickRand(slice, r) to select items.

Rule of thumb: If you want reproducibility, always pass -s <seed>

Writing a new profile (compiled-in)

  1. Create a folder:
$ mkdir -p plugins/myprofile
  1. Add plugins/myprofile/myprofile.go and paste this minimal skeleton:
package myprofile

import (
	"github.com/nsa-yoda/namegen/api"
)

type myProfile struct{}

const PROFILE = "myprofile"

func init() {
	api.RegisterProfile(PROFILE, Profile)
}

func (p myProfile) Info() map[string]string {
	return map[string]string{
		"name":  PROFILE,
		"notes": "What this profile does",
	}
}

func (p myProfile) Generate(cfg api.ProfileConfig) (api.NameResult, error) {
	r := api.NewRand(cfg)

	first := api.PickRand([]string{"Ada", "Grace", "Linus"}, r)
	last := ""
	if cfg.IncludeLast {
		last = api.PickRand([]string{"Lovelace", "Hopper", "Torvalds"}, r)
	}

	return api.NameResult{First: first, Last: last}, nil
}

var Profile myProfile
  1. Compile it into the binary by adding a blank import to cmd/namegen/main.go:
_ "github.com/nsa-yoda/namegen/plugins/myprofile"
  1. Build and run:
$ make build
$ ./bin/namegen -mode myprofile -l -s 123 -c 5

Library usage (import in your own Go project)

If you want to use NameGen as a library, you import the API package and then load plugins. The easiest way is to import all built-in plugins at once:

package main

import (
	"fmt"

	_ "github.com/nsa-yoda/namegen/all"
	"github.com/nsa-yoda/namegen/api"
)

func main() {
	// List available profiles (registered by imports)
	fmt.Println("profiles:", api.ListProfiles())

	// Grab a profile and generate a name
	p, err := api.GetProfile("english")
	if err != nil {
		panic(err)
	}

	out, err := p.Generate(api.ProfileConfig{
		Seed:        123,
		Realism:     90,
		Gender:      "neutral",
		IncludeLast: true,
	})
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s %s\n", out.First, out.Last)
}

Loading only one plugin (smaller binaries)

If you don't want every built-in profile, import only the plugin(s) you need:

package main

import (
	_ "github.com/nsa-yoda/namegen/plugins/english" // registers “english” plugin/porfile
	"github.com/nsa-yoda/namegen/api"
)

p, _ := api.GetProfile("english")
res, _ := p.Generate(api.ProfileConfig{Seed: 123, IncludeLast: true})

Notes

github.com/nsa-yoda/namegen/all is a convenience package that blank-imports every built-in plugin so their init() functions run and registers the profiles.

If you care about binary size / compile time, prefer importing only the specific plugin packages you need

Notes / gotchas

  • realism is profile-specific behavior. Every profile implements its own blend between curated names and procedural phonotactics.
  • ASCII output by design is the defualt. Some languages normally use diacritics or special punctuation; these profiles intentionally keep output ASCII-friendly.
  • Profile not found fallback. If -mode isn't registered, the CLI logs a warning and uses english.

License

This project is licensed under the MIT license, see LICENSE file

About

A fast, deterministic name generator written in Go

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages