Skip to content

Instantly share code, notes, and snippets.

@ali-master
Last active May 29, 2025 22:57
Show Gist options
  • Save ali-master/b1fad0a635d03ae168e67e6f1de89a64 to your computer and use it in GitHub Desktop.
Save ali-master/b1fad0a635d03ae168e67e6f1de89a64 to your computer and use it in GitHub Desktop.
Generate beautiful, memorable, and poetic API keys and unique identifiers for your applications.

Keyfleur Poetic Generator

TypeScript License

Generate beautiful, memorable, and poetic API keys and unique identifiers for your applications.

Overview

Keyfleur creates human-readable, aesthetically pleasing API keys and unique identifiers inspired by natural language patterns and poetry. Unlike traditional random strings, Keyfleur keys are designed to be both functional and beautiful.

Gleam-LucidFire-Radiant
SyrelRa-ArLeriS
Nova-437-Eclipse
Pulse88.88esluP

Features

  • 🌈 Multiple generation modes (haiku, lace, sonnet, etc.)
  • 🎨 Thematic word collections (celestial, oceanic, forest, etc.)
  • 🔒 Unique and memorable keys suitable for API tokens, user IDs, and more
  • 💻 Fully typed TypeScript implementation
  • 📦 Zero dependencies

Installation

# NPM
npm install keyfleur

# Yarn
yarn add keyfleur

# PNPM
pnpm add keyfleur

Usage

Basic Usage

import { poeticKey } from 'keyfleur';

// Generate a key with default settings (haiku mode, haiku theme)
const key = poeticKey();
console.log(key); // e.g., "LyrAeli-NuviaSirune-OriaEvara"

// Specify a mode and theme
const celestialKey = poeticKey('sigil', 'celestial');
console.log(celestialKey); // e.g., "Nebula-342-Comet"

Available Modes

  • haiku - Creates a three-part key based on syllable counts (5-7-5)
  • lace - Generates a palindrome-like pattern
  • mirrora - Creates a mirrored syllable pattern
  • rune - Combines a haiku with a time-based rune
  • sonnet - Creates a two-part key with syllable embellishments
  • sigil - Generates a word-number-word pattern
  • seed - Creates a word prefix with hexadecimal suffix
  • mantra - Repeats a word with a final different word
  • quartz - Creates a complex pattern with reversed text and numbers

Available Themes

  • haiku - Abstract poetic terms
  • nocturnal - Night and darkness-related words
  • sunny - Light and brightness-related words
  • floreal - Flower and plant-related words
  • oceanic - Ocean and sea-related words
  • crystalline - Crystal and gem-related words
  • mythic - Mythology and legend-related words
  • forest - Forest and woodland-related words
  • desert - Desert and arid-related words
  • celestial - Astronomy and space-related words
  • library - Books and writing-related words
  • decay - Entropy and decay-related words
  • steampunk - Steampunk and mechanical-related words

Advanced Usage

import { poeticKey, THEMES, MODES, ThemeKey, ModeKey } from 'keyfleur';

// Generate multiple keys
const generateKeys = (count: number, mode: ModeKey, theme: ThemeKey) => {
  return Array.from({ length: count }, () => poeticKey(mode, theme));
};

// Get 5 crystalline-themed quartz keys
const crystalKeys = generateKeys(5, 'quartz', 'crystalline');
console.log(crystalKeys);

// Custom function to verify a key is in expected format
const isValidSigilKey = (key: string): boolean => {
  const parts = key.split('-');
  return parts.length === 3 && 
         /^[A-Z][a-z]+$/.test(parts[0]) && 
         /^\d{3}$/.test(parts[1]) && 
         /^[A-Z][a-z]+$/.test(parts[2]);
};

const key = poeticKey('sigil', 'mythic');
console.log(`Key ${key} is ${isValidSigilKey(key) ? 'valid' : 'invalid'}`);

CLI Usage

When installed globally, Keyfleur can be used from the command line:

# Install globally
npm install -g keyfleur

# Generate a key with default settings
keyfleur

# Generate keys with specific mode and theme
keyfleur --mode=sigil --theme=celestial

# Generate multiple keys
keyfleur --count=5 --mode=seed --theme=steampunk

Use Cases

  • API Keys and tokens that are easy to read and share
  • Session identifiers with aesthetic appeal
  • Temporary access codes and passphrases
  • Creative project names and codenames
  • Game save IDs or world seeds
  • Document and content identifiers
  • Memorable reference codes

Customization

You can extend Keyfleur with your own themes and modes:

import { THEMES, MODES, ThemeKey, ModeKey } from 'keyfleur';

// Add a custom theme
const customThemes = {
  ...THEMES,
  'cyberpunk': [
    'neon', 'grid', 'hack', 'node', 'cyber', 'jack', 'bit', 'flux',
    'pulse', 'wire', 'data', 'net', 'code', 'pixel', 'virt', 'synth'
  ]
};

// Add a custom mode function
const customModes = {
  ...MODES,
  'trinity': (theme: ThemeKey) => {
    const words = customThemes[theme] || customThemes['haiku'];
    const randomWords = Array.from(
      { length: 3 }, 
      () => words[Math.floor(Math.random() * words.length)]
    ).map(w => w.charAt(0).toUpperCase() + w.slice(1));
    
    return randomWords.join('~');
  }
};

// Use your custom mode and theme
function customPoeticKey(
  mode: ModeKey | 'trinity' = 'haiku', 
  theme: ThemeKey | 'cyberpunk' = 'haiku'
): string {
  const themeWords = customThemes[theme as ThemeKey] ? theme : 'haiku';
  const modeFunc = customModes[mode as ModeKey] || customModes['haiku'];
  return modeFunc(themeWords as ThemeKey);
}

console.log(customPoeticKey('trinity', 'cyberpunk')); // e.g., "Neon~Synth~Code"

Technical Details

Keyfleur uses various linguistic patterns and algorithms to generate keys:

  • Syllable estimation - Analyzes word structure to approximate syllable counts
  • Word selection - Chooses thematically appropriate words from curated collections
  • Pattern generation - Applies various patterns and transformations to create diverse key styles

All keys are designed to be URL-safe, human-readable, and aesthetically pleasing.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request
// === Type Definitions ===
type ThemeKey = 'haiku' | 'nocturnal' | 'sunny' | 'floreal' | 'oceanic' |
'crystalline' | 'mythic' | 'forest' | 'desert' | 'celestial' |
'library' | 'decay' | 'steampunk';
type ModeKey = 'haiku' | 'lace' | 'mirrora' | 'rune' | 'sonnet' |
'sigil' | 'seed' | 'mantra' | 'quartz';
type ThemeWords = Record<ThemeKey, string[]>;
type ModeFunction = (theme: ThemeKey) => string;
type ModeFunctions = Record<ModeKey, ModeFunction>;
// === THEME WORDS ===
const THEMES: ThemeWords = {
'haiku': [
'nyrae','soliv','virel','ethae','omura','lyr','aeli','sirune','nuvia','evara',
'halen','ilari','tyrel','elune','kairi','syrel','narun','velia','orune','faeli'
],
'nocturnal': [
'luna','night','star','owl','dusk','twilight','midnight','shade','echo','eclipse',
'gloom','moth','raven','void','mist','sleep','howl','nova','quiet','shiver',
'dark','silence','phantom','crescent','hollow','dream','veil','crypt','umbra','noir'
],
'sunny': [
'sol','sun','ray','bright','day','dawn','shine','gold','beam','sky',
'flare','light','summer','glow','warmth','clear','zenith','haze','amber','bliss',
'gleam','glint','sunrise','radiant','beam','halo','lucid','fire','flare','glory'
],
'floreal': [
'rose','lily','petal','bloom','ivy','orchid','daisy','violet','primrose','stem',
'pollen','sprout','bud','blossom','flora','camellia','garden','leaf','nectar','thistle',
'lavender','tulip','clover','hyacinth','marigold','chrysant','wisteria','magnolia','peony','fern'
],
'oceanic': [
'wave','coral','foam','drift','deep','pearl','tide','gull','salt','whale',
'kelp','abyss','current','surf','ocean','marina','shoal','siren','lagoon','shell',
'reef','seastar','nautilus','spray','undertow','isle','brine','anchor','swell','ripple'
],
'crystalline': [
'crystal','gem','shard','opal','quartz','glint','ice','snow','frost','facet',
'prism','glass','clear','gleam','diamond','shine','mirror','spark','flake','glow',
'glacier','amethyst','glisten','translucent','silica','bismuth','halo','chime','lucent','citrine'
],
'mythic': [
'aether','wyrm','oracle','sigil','blade','fable','mythos','grimoire','phoenix','echo',
'titan','nymph','elysium','lore','rune','arcane','wyrd','hero','legend','shade',
'sphinx','hydra','oblivion','divine','hex','omen','ritual','saga','daemon','prophecy'
],
'forest': [
'moss','bark','deer','grove','tree','fern','owl','leaf','fox','thicket',
'pine','birch','root','sap','fungus','log','trail','wild','branch','meadow',
'cedar','acorn','willow','glade','lichen','bluff','elm','spruce','hedge','nest'
],
'desert': [
'sand','dune','mirage','sun','dry','camel','cactus','arid','scorch','salt',
'wind','dust','stone','haze','burn','sol','flame','crack','barren','sizzle',
'ember','serpent','blister','parch','ash','glare','mesa','quartz','sirocco','ridge'
],
'celestial': [
'nova','orbit','comet','moon','star','sol','galaxy','void','pulse','flare',
'venus','eclipse','plasma','space','light','sphere','sky','drift','saturn','zero',
'nebula','equinox','zenith','meteor','lunar','solstice','mercury','aster','axis','horizon'
],
'library': [
'scroll','ink','book','page','shelf','quiet','dust','study','read','verse',
'prose','codex','folio','scribe','script','glyph','letter','note','pen','volume',
'archive','index','library','margin','annotation','spine','binding','tome','quill','text'
],
'decay': [
'rot','rust','moss','mold','crack','fade','peel','dust','crumble','ash',
'time','void','wilt','droop','filth','wear','flaw','scratch','stain','dull',
'brittle','smudge','erode','fracture','debris','decay','fester','grime','soot','relic'
],
'steampunk': [
'gear','steam','cog','brass','pipe','gauge','valve','weld','bolt','clock',
'spark','smoke','engine','vane','dial','joint','helm','rivets','boiler','coil',
'piston','frame','rotor','socket','vent','torque','copper','chrono','lever','mech'
]
};
const SOFT_CONS: string = 'flmnrschv';
const VOWELS: string = 'aeiouy';
const RUNES: string[] = ['now+1d','now-2h','dawn','midnight','solstice','infinite','epoch'];
/**
* Generates a random syllable using soft consonants and vowels
*/
function syllable(): string {
return getRandomChar(SOFT_CONS) + getRandomChar(VOWELS);
}
/**
* Returns a random character from the provided string
*/
function getRandomChar(chars: string): string {
return chars.charAt(Math.floor(Math.random() * chars.length));
}
/**
* Returns a random integer between min (inclusive) and max (inclusive)
*/
function getRandomInt(min: number, max: number): number {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* Returns a random element from an array
*/
function getRandomElement<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
/**
* Estimate the number of syllables in a word
*/
function estimateSyllables(word: string): number {
if (!word || typeof word !== 'string') {
return 0;
}
word = word.toLowerCase();
const vowels = 'aeiouy';
let count = 0;
let prevChar = '';
for (const char of word) {
if (vowels.includes(char) && !vowels.includes(prevChar)) {
count++;
}
prevChar = char;
}
if (word.endsWith("e") && count > 1) {
count--;
}
return Math.max(1, count);
}
/**
* Generate haiku by finding words with specific syllable counts
*/
function haiku(theme: ThemeKey): string {
// Create a flattened array of all words
const allWords: string[] = Object.values(THEMES[theme]).flat().filter(word => word);
// Shuffle the array
const shuffledWords = [...allWords].sort(() => Math.random() - 0.5);
const usedWords = new Set<string>();
function findWords(targetSyllables: number): string[] {
const result: string[] = [];
let total = 0;
for (const word of shuffledWords) {
if (!word || usedWords.has(word)) {
continue;
}
const syll = estimateSyllables(word);
if (syll === 0) {
continue;
}
if (total + syll <= targetSyllables) {
result.push(word.charAt(0).toUpperCase() + word.slice(1));
usedWords.add(word);
total += syll;
if (total === targetSyllables) {
break;
}
}
}
return total === targetSyllables ? result : [];
}
const line1 = findWords(5);
const line2 = findWords(7);
const line3 = findWords(5);
if (!line1.length || !line2.length || !line3.length) {
return "incomplete-haiku";
}
return [line1.join(''), line2.join(''), line3.join('')].join('-');
}
/**
* Generate a lace pattern key
*/
function lace(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const word = getRandomElement(roots);
const mid = syllable();
return `${word}${mid}-${mid.split('').reverse().join('')}${word.split('').reverse().join('')}`;
}
/**
* Generate a mirrora key
*/
function mirrora(_: ThemeKey): string {
const s = syllable();
return `${s.split('').reverse().join('')}-${s}`;
}
/**
* Generate a rune key
*/
function runeKey(theme: ThemeKey): string {
const base = haiku(theme).charAt(0).toUpperCase() + haiku(theme).slice(1);
const rune = getRandomElement(RUNES);
return `${base}_${rune}`;
}
/**
* Generate a sonnet key
*/
function sonnet(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const firstWord = getRandomElement(roots);
const secondWord = getRandomElement(roots);
const firstSyll = syllable().slice(0, 2);
const secondSyll = syllable().slice(0, 2);
return `${firstWord.charAt(0).toUpperCase() + firstWord.slice(1)}${firstSyll}-${secondWord.charAt(0).toUpperCase() + secondWord.slice(1)}${secondSyll}`;
}
/**
* Generate a sigil key
*/
function sigil(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const firstWord = getRandomElement(roots);
const secondWord = getRandomElement(roots);
return `${firstWord.charAt(0).toUpperCase() + firstWord.slice(1)}-${getRandomInt(100, 999)}-${secondWord.charAt(0).toUpperCase() + secondWord.slice(1)}`;
}
/**
* Generate a seed key
*/
function seed(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const word = getRandomElement(roots);
const wordPrefix = word.slice(0, 4);
const randomHex = getRandomInt(0x1000, 0x9999).toString(16);
return `${wordPrefix.charAt(0).toUpperCase() + wordPrefix.slice(1)}-${randomHex}`;
}
/**
* Generate a mantra key
*/
function mantra(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const word = getRandomElement(roots);
const secondWord = getRandomElement(roots);
return `${word.charAt(0).toUpperCase() + word.slice(1)}-${word.charAt(0).toUpperCase() + word.slice(1)}-${secondWord.charAt(0).toUpperCase() + secondWord.slice(1)}`;
}
/**
* Generate a quartz key
*/
function quartz(theme: ThemeKey): string {
const roots = THEMES[theme] || THEMES['haiku'];
const root = getRandomElement(roots);
const capitalized = root.charAt(0).toUpperCase() + root.slice(1);
const rev = capitalized.split('').reverse().join('').slice(0, 4);
const num = getRandomInt(10, 99).toString();
return `${capitalized}${num}.${num}${rev}`;
}
// Mode functions dictionary
const MODES: ModeFunctions = {
'haiku': haiku,
'lace': lace,
'mirrora': mirrora,
'rune': runeKey,
'sonnet': sonnet,
'sigil': sigil,
'seed': seed,
'mantra': mantra,
'quartz': quartz
};
/**
* Generate a poetic key with the given mode and theme
*/
function poeticKey(mode: ModeKey = 'haiku', theme: ThemeKey = 'haiku'): string {
const func = MODES[mode] || MODES['haiku'];
return func(theme);
}
/**
* Command line interface implementation
*/
function main(): void {
// In a Node.js environment, you would use something like yargs or commander
// For a browser environment, this would be adapted differently
const args = {
theme: 'haiku' as ThemeKey,
mode: 'haiku' as ModeKey,
count: 1
};
// Parse command line arguments would go here
// For demonstration, we just use the defaults
for (let i = 0; i < args.count; i++) {
console.log(poeticKey(args.mode, args.theme));
}
}
// Export the functions for module use
export {
poeticKey,
ThemeKey,
ModeKey,
THEMES,
MODES
};
// Run the main function if this is the main module
if (require.main === module) {
main();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment