Neo Zero

colors

Pool

Zero-dependency terminal colors - Fast, modern, tree-shakeable alternative to chalk

$ lpm install @lpm.dev/neo.colors

@lpm.dev/neo.colors

Zero-dependency terminal colors - Fast, modern, tree-shakeable alternative to chalk

Features

  • Zero dependencies - No node_modules bloat
  • 5-10% faster than chalk
  • 33% smaller gzipped bundle
  • 100% chalk-compatible API - Drop-in replacement
  • Full TypeScript support - Strict mode, zero any types
  • ESM + CommonJS - Works everywhere
  • Tree-shakeable - Import only what you need
  • Auto color detection - Respects NOCOLOR, FORCECOLOR, CI environments
  • 16m colors - RGB, hex, 256-color palette
  • 100% test coverage - Battle-tested

Quick Start

lpm install @lpm.dev/neo.colors
import colors from '@lpm.dev/neo.colors'

console.log(colors.red('Error!'))
console.log(colors.green.bold('Success!'))
console.log(colors.blue.underline('https://example.com'))

Why @lpm.dev/neo.colors?

Chalk went ESM-only

Chalk v5 dropped CommonJS support, breaking millions of projects. @lpm.dev/neo.colors supports both ESM and CommonJS out of the box.

Dependencies Add Up

Chalk used to have 4 dependencies totaling ~1,200 lines of code. We've inlined and optimized everything into a single, zero-dependency package.

Modern & Fast

Built from the ground up with: - Node 18+ target (modern JavaScript features) - TypeScript-first architecture - Performance-optimized algorithms - Tree-shakeable exports

See benchmarks →

API

Basic Colors

import colors from '@lpm.dev/neo.colors'

// Foreground colors
colors.black('text')
colors.red('text')
colors.green('text')
colors.yellow('text')
colors.blue('text')
colors.magenta('text')
colors.cyan('text')
colors.white('text')
colors.gray('text')     // or .grey

// Background colors
colors.bgBlack('text')
colors.bgRed('text')
colors.bgGreen('text')
colors.bgYellow('text')
colors.bgBlue('text')
colors.bgMagenta('text')
colors.bgCyan('text')
colors.bgWhite('text')
colors.bgGray('text')   // or .bgGrey

// Bright colors
colors.redBright('text')
colors.greenBright('text')
// ... and more

Styles

colors.bold('text')
colors.dim('text')
colors.italic('text')
colors.underline('text')
colors.inverse('text')
colors.hidden('text')
colors.strikethrough('text')

Chaining

// Chain any combination of colors and styles
colors.red.bold('Error!')
colors.green.bold.underline('Success!')
colors.blue.bgWhite.bold('Info')

// Order doesn't matter - they all stack
colors.bold.red('text')  // same as
colors.red.bold('text')

RGB & Hex Colors

// RGB (0-255 for each channel)
colors.rgb(255, 0, 0)('Bright red')
colors.bgRgb(0, 255, 0)('Green background')

// Hex colors
colors.hex('#ff0000')('Red from hex')
colors.bgHex('#00ff00')('Green bg from hex')

// Shorthand hex
colors.hex('#f00')('Also red')

// Chain with other styles
colors.hex('#ff6b6b').bold.underline('Fancy!')

256-Color Palette

// Use any color from the 256-color palette (0-255)
colors.ansi256(196)('Bright red')
colors.bgAnsi256(21)('Blue background')

Tree-Shakeable Imports

// Import only what you need for optimal bundle size
import { red, bold, green } from '@lpm.dev/neo.colors'

console.log(red('Error'))
console.log(bold(green('Success')))

Custom Instances

import { createColors } from '@lpm.dev/neo.colors'

// Force specific color level
const colors = createColors({ level: 3 }) // 0=none, 1=16, 2=256, 3=16m

// Disable colors
const noColors = createColors({ enabled: false })
const text = noColors.red('text') // → 'text' (no colors)

TypeScript

import colors, { StyleFunction } from '@lpm.dev/neo.colors'

const colorize: StyleFunction = colors.red.bold

// All types are exported
import type { ColorLevel, ColorSupport, ColorOptions } from '@lpm.dev/neo.colors'

Environment Variables

NO_COLOR

Disables colors when set (any value): bash NO_COLOR=1 node app.js

FORCE_COLOR

Forces color output: bash FORCE_COLOR=1 node app.js # Force basic colors (level 1) FORCE_COLOR=2 node app.js # Force 256 colors (level 2) FORCE_COLOR=3 node app.js # Force 16 million colors (level 3)

CLI Flags

node app.js --color        # Force colors
node app.js --no-color     # Disable colors
node app.js --color=256    # Force 256-color mode
node app.js --color=16m    # Force truecolor mode

Color Detection

@lpm.dev/neo.colors automatically detects terminal capabilities:

  1. CLI flags (--color, --no-color) - highest priority
  2. FORCE_COLOR environment variable
  3. NO_COLOR environment variable
  4. CI environments (GitHub Actions, Travis, Jenkins, etc.)
  5. Terminal capabilities (COLORTERM, TERM, TERM_PROGRAM)
  6. Platform detection (Windows 10+, macOS, Linux)
  7. TTY check - fallback
import { detectColorSupport } from '@lpm.dev/neo.colors'

const support = detectColorSupport()
console.log(support)
// {
//   level: 3,          // 0=none, 1=16, 2=256, 3=16m
//   hasBasic: true,    // 16 colors
//   has256: true,      // 256 colors
//   has16m: true       // 16 million colors (truecolor)
// }

Migration from Chalk

@lpm.dev/neo.colors is a drop-in replacement for chalk:

- import chalk from 'chalk'
+ import colors from '@lpm.dev/neo.colors'

- console.log(chalk.red.bold('Error!'))
+ console.log(colors.red.bold('Error!'))

API Differences

99% compatible. Minor differences: - Template literals are not supported (use string concatenation instead) - Some rarely-used features may differ slightly

For most use cases, it's a perfect drop-in replacement!

Examples

Error Messages

import colors from '@lpm.dev/neo.colors'

console.error(colors.red.bold('Error:'), colors.red('File not found'))
console.warn(colors.yellow.bold('Warning:'), colors.yellow('Deprecated API'))
console.log(colors.green.bold('✓'), colors.green('Build successful!'))

Pretty Logs

const timestamp = colors.gray(new Date().toISOString())
const level = colors.cyan.bold('[INFO]')
const message = colors.white('Server started')
const url = colors.blue.underline('http://localhost:3000')

console.log(`${timestamp} ${level} ${message} on ${url}`)
// → [gray]2025-01-15T10:30:00.000Z[/gray] [cyan][INFO][/cyan] Server started on [blue]http://localhost:3000[/blue]

Progress Indicators

const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
let i = 0

setInterval(() => {
  process.stdout.write(`\r${colors.cyan(spinner[i])} Loading...`)
  i = (i + 1) % spinner.length
}, 80)

Diff Output

console.log(colors.green('+ Added line'))
console.log(colors.red('- Removed line'))
console.log(colors.dim('  Unchanged line'))

Performance

See BENCHMARKS.md for detailed performance comparison.

Summary: - ✅ 5-10% faster than chalk - ✅ 33% smaller gzipped - ✅ 60% less code

Browser Support

@lpm.dev/neo.colors is designed for Node.js environments (CLI tools, build scripts, servers). For browser-based coloring, consider CSS.

License

MIT © neo

Credits

Inspired by chalk and built with modern JavaScript.

colorschalkterminalansicolorstyleneocliconsoleformattingmoderntypescriptzero-dependencytree-shakeable
Unlimited AccessInstall as many Pool packages as you need.
Fund Real WorkEvery install you run sends revenue directly to the developer who built it.

Taxes calculated at checkout based on your location.

Weekly Installs
1
Version
1.0.0
Published
LicenseMIT
Size67.28 KB
Files10
Node version>= 18
TypeScriptYes
Colors by Neo - Zero-dependency terminal colors - Fast, modern, tr... | LPM