Utify is a powerful Go library for displaying styled messages in the terminal with comprehensive logging support. Features include colored terminal output, structured JSON logging, configurable log targets, and extensive customization options.
- Modular Architecture: Complete restructure from single-file to organized packages
- Structured JSON Logging: Automatic logging to configurable file targets
- Log-Only Functions: New
Log*()functions for logging without terminal output - Icon System: Smart icon support with Nerd Font detection and Unicode fallback
- Better Testing: Comprehensive unit, integration, and benchmark tests
- Enhanced Examples: Organized examples with dedicated demos
- Improved Documentation: Updated with new features and architecture
- 🎨 Styled Terminal Output: Easily print messages with predefined styles for success, error, warning, info, and more.
- 📝 Structured JSON Logging: Automatically log all messages to a configurable file in a structured JSON format, including timestamp, level, and message.
- 🔧 Customizable Options: Fine-tune the output with options for bold/italic text, color control, and icon visibility.
- 🎯 Smart Icon System: Automatically detects Nerd Font support in the terminal and provides Unicode emoji fallbacks.
- 🎣 Extensible Callbacks: Hook into message events to trigger custom logic, such as metrics or notifications.
- ⛓️ Fluent API: Chain methods together for a readable and expressive configuration.
- 🤫 Silent Error Handling: Error-type messages return a special
utify.ErrSilentto avoid disrupting program flow. - ✍️ Formatted Output: All message functions have a formatted version (e.g.,
Successf) for easy string interpolation. - 📝 Log-Only Functions: Log messages without printing them to the terminal.
- 📦 Predefined Message Types: A wide range of predefined message types for common actions (e.g.,
Install,Delete,Update).
go get github.com/jsas4coding/utifypackage main
import (
"github.com/jsas4coding/utify"
)
func main() {
opts := utify.OptionsDefault()
// Print to terminal AND log to file
utify.Success("Operation completed!", opts)
utify.Error("An error occurred!", opts)
utify.Warning("Pay attention!", opts)
utify.Info("Here is some info.", opts)
utify.Debug("Debug message.", opts)
utify.Critical("System failure!", opts)
}All methods print the message to stdout AND log it to a structured JSON log file. Methods that represent errors (Error, Critical, Debug) return the sentinel utify.ErrSilent.
To get the output and handle it manually, use the Get* functions:
text, err := utify.GetError("Oops!", opts)Customize output using chained methods:
| Method | Effect |
|---|---|
.WithBold() |
Makes the message bold |
.WithItalic() |
Makes the message italic |
.WithoutColor() |
Disables all ANSI color codes |
.WithIcon() |
Enables icons for messages |
.WithoutIcon() |
Disables icons for messages |
.WithoutStyle() |
Disables all styling (bold, italic, etc.) |
.WithExit() |
Exits the program (os.Exit(1)) after showing error |
.WithCallback(fn) |
Executes callback after message (disables exit) |
opts := utify.OptionsDefault().
WithBold().
WithIcon().
WithoutColor()
utify.Warning("This is bold with icon but no color", opts)Utify includes a smart icon system with automatic Nerd Font detection and Unicode fallback:
- Automatic Detection: Detects Nerd Font capability in supported terminals
- Fallback Support: Uses regular Unicode emoji when Nerd Fonts aren't available
- Manual Control: Force specific icon types or disable icons entirely
// Enable icons (uses auto-detection)
opts := utify.OptionsDefault().WithIcon()
utify.Success("Operation completed!", opts)
// Disable icons
opts := utify.OptionsDefault().WithoutIcon()
utify.Success("No icon here", opts)// Force Nerd Font icons (if available in terminal)
utify.ForceNerdFont()
// Force regular Unicode icons
utify.ForceRegularIcons()
// Disable all icons
utify.DisableIcons()
// Check current settings
fmt.Printf("Icon type: %v\n", utify.GetIconType())
fmt.Printf("Nerd Font detected: %v\n", utify.IsNerdFontDetected())Set NERD_FONT_ENABLED=true to force Nerd Font usage:
NERD_FONT_ENABLED=true ./my-app| Icon Type | Description | Example |
|---|---|---|
| Regular | Unicode emoji (default) | ✅ ❌ |
| Nerd Font | Font Awesome icons | Various Nerd Font glyphs |
| None | No icons displayed | (text only) |
Note: Nerd Font icons require a compatible Nerd Font installed in your terminal. If icons appear blank, your terminal doesn't have the required font glyphs.
Utify automatically logs all messages to a structured JSON log file with configurable targets:
- Default location:
/var/log/{binary_name}.log - Fallback: Current directory if
/var/logis not writable - Format: Structured JSON with timestamp, level, message, type, and binary name
// Change log file location
err := utify.SetLogTarget("./my-app.log")
if err != nil {
fmt.Printf("Failed to set log target: %v\n", err)
}
// Get current log location
fmt.Printf("Logging to: %s\n", utify.GetLogTarget())
// Disable/enable logging
utify.SetLoggingEnabled(false) // Disable logging
utify.SetLoggingEnabled(true) // Re-enable logging
// Check if logging is enabled
if utify.IsLoggingEnabled() {
fmt.Println("Logging is active")
}
// Clean up (close log file)
defer utify.CloseLogger()Use these functions to log messages WITHOUT printing to stdout:
// Log-only functions (no terminal output)
utify.LogSuccess("Operation completed silently")
utify.LogError("Error logged only")
utify.LogInfo("Background info logged")
// Formatted log-only functions
utify.LogSuccessf("Processed %d items", 42)
utify.LogErrorf("Failed to connect to %s", "database"){
"timestamp": "2025-07-27T16:30:45Z",
"level": "SUCCESS",
"message": "Operation completed",
"type": "success",
"binary": "my-app"
}If you want to hook into messages (e.g. for logging, metrics), use .WithCallback(...):
callback := func(t utify.MessageType, msg string) {
fmt.Printf("\ud83d\udce3 Callback triggered: [%s] %s\n", t, msg)
}
opts := utify.OptionsDefault().
WithCallback(callback)
utify.Critical("Oops!", opts)️ When .WithCallback() is used, .WithExit() is ignored — and vice-versa.
The examples/ directory contains a set of applications that demonstrate how to use the various features of Utify.
basic: A simple application that shows how to use the basic message functions.colors: A demonstration of how to customize the color scheme.icons: An example of how to use the icon system, including forcing different icon types.callbacks: A demonstration of how to use callbacks to hook into message events.logging-demo: An application that shows how to use the logging features, including setting a custom log target.
To run an example, navigate to its directory and use go run:
cd examples/basic
go run main.goGeneral Status
Success(text, opts),Error(text, opts),Warning(text, opts)Info(text, opts),Debug(text, opts),Critical(text, opts)
Common Actions
Delete(text, opts),Update(text, opts),Install(text, opts)Upgrade(text, opts),Edit(text, opts),New(text, opts)
I/O Operations
Download(text, opts),Upload(text, opts),Sync(text, opts),Search(text, opts)
General Status
LogSuccess(text),LogError(text),LogWarning(text)LogInfo(text),LogDebug(text),LogCritical(text)
Common Actions
LogDelete(text),LogUpdate(text),LogInstall(text)LogUpgrade(text),LogEdit(text),LogNew(text)
I/O Operations
LogDownload(text),LogUpload(text),LogSync(text),LogSearch(text)
GetSuccess(text, opts) (string, error)GetError(text, opts) (string, error)- And all other message types...
Each function has a formatted version with f suffix:
// Output + Log
utify.Successf("Success %d: %s", opts, 200, "OK")
// Log only
utify.LogSuccessf("Processed %d items", 42)
// Get formatted
result, err := utify.GetCriticalf("Crash code %d", opts, 42)If you need full control, use Echo(...):
opts := utify.OptionsDefault().
WithBold().
WithoutIcon()
utify.Echo(utify.MessageInstall, "Installing package...", opts)Return:
(text string, err error)If it's an error-type message, the error returned will be:
utify.ErrSilentRun all tests:
make testRun specific test suites:
make test-unit # Unit tests only
make test-integration # Integration tests only
make bench # Performance benchmarksCoverage reports:
make coverage # Text coverage report
make coverage-html # HTML coverage reportOther commands:
make build # Build the project
make lint # Run linters (requires golangci-lint)
make docs # Validate documentation
make clean # Clean up artifactsLicensed under the MIT License.
utify/
├── pkg/ # Core packages
│ ├── colors/ # ANSI color constants
│ ├── messages/ # Message type definitions
│ ├── options/ # Configuration options
│ ├── formatter/ # Output formatting logic
│ └── logger/ # Structured JSON logging
├── internal/tests/ # Test utilities
├── examples/ # Usage examples
│ ├── basic/ # Basic usage
│ ├── colors/ # Custom colors
│ ├── callbacks/ # Callback functionality
│ └── logging-demo/ # Logging examples
└── tests/ # Test suites
├── unit/ # Unit tests
├── integration/ # Integration tests
└── benchmarks/ # Performance tests
Feel free to open issues, discuss features, or submit PRs! Let's make terminals beautiful, together.
Development:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Run
make testandmake docsto ensure quality - Submit a pull request