npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

es-toolkit-clean

v1.2.0

Published

A lightweight, TypeScript-first library for cleaning JavaScript objects by removing undefined values, empty strings, empty arrays, functions, and other unwanted properties. Built on es-toolkit for superior performance.

Downloads

129

Readme

es-toolkit-clean

A lightweight, TypeScript-first library for cleaning JavaScript objects by removing undefined values, empty strings, empty arrays, functions, and other unwanted properties. Built on es-toolkit for superior performance.

Why es-toolkit-clean?

Sometimes API responses contain properties filled with empty strings, undefined values, or functions that you want to remove. This library provides a configurable way to clean your data structures, similar to a more powerful version of _.compact for objects.

Features

  • 🧹 Smart cleaning - Removes empty strings, undefined values, empty arrays, and functions by default
  • 🔧 Fully configurable - Customize how each data type should be processed
  • 📦 Lightweight - Small bundle size (ESM: ~4.21KB, CJS: ~7.37KB) uncompressed.
  • 📱 Universal - Works in Node.js, browsers, and edge environments
  • 🚀 TypeScript-first - Full TypeScript support with comprehensive type definitions
  • High performance - Built on es-toolkit for optimal speed
  • 🎯 Dual format - Supports both ESM and CommonJS

Installation

npm install es-toolkit-clean
pnpm add es-toolkit-clean
yarn add es-toolkit-clean

Quick Start

import clean from 'es-toolkit-clean'

const messy = {
  name: 'John',
  email: '',           // Empty string - will be removed
  age: 0,             // Zero - will be kept
  active: true,       // Boolean - will be kept  
  score: null,        // Null - will be kept
  undefined: undefined, // Undefined - will be removed
  fn: () => {},       // Function - will be removed
  tags: ['', 'valid', ' '], // Mixed array - empty strings removed
  nested: {
    value: 'keep',
    empty: '',
    spaces: '   '
  }
}

const cleaned = clean(messy)
console.log(cleaned)
// Output:
// {
//   name: 'John',
//   age: 0,
//   active: true,
//   score: null,
//   tags: ['valid'],
//   nested: { value: 'keep' }
// }

Core API

clean(obj) - Default Export

The main function for cleaning any data structure with default settings.

import clean from 'es-toolkit-clean'

// Clean an object
const result = clean({ name: 'test', empty: '', valid: 42 })
// → { name: 'test', valid: 42 }

// Clean an array
const cleanArray = clean(['valid', '', ' ', 'another'])
// → ['valid', 'another']

// Clean a string
const cleanString = clean('  hello world  ')
// → 'hello world'

createCleaner(config) - Custom Cleaning

Create a custom cleaner with specific configuration for different data types.

import { createCleaner, defaultProcessors } from 'es-toolkit-clean'

// Remove null values (default behavior keeps them)
const strictCleaner = createCleaner({
  ...defaultProcessors,
  isNull: () => undefined  // Remove nulls instead of keeping them
})

const result = strictCleaner({ 
  name: 'test', 
  value: null, 
  empty: '' 
})
// → { name: 'test' }

// Keep functions (default behavior removes them)
const keepFunctions = createCleaner({
  ...defaultProcessors,
  isFunction: (fn) => fn  // Keep functions instead of removing them
})

const withFn = keepFunctions({ 
  name: 'test', 
  callback: () => 'hello',
  empty: ''
})
// → { name: 'test', callback: [Function] }

createProcessor(config) - Custom Value Processing

Create a custom processor for handling individual values.

import { createProcessor, defaultProcessors } from 'es-toolkit-clean'

// Custom string processing
const customProcessor = createProcessor({
  ...defaultProcessors,
  isString: (str) => {
    const trimmed = str.trim()
    return trimmed ? trimmed.toUpperCase() : undefined
  }
})

const processor = customProcessor
const result = processor('  hello world  ', processor)
// → 'HELLO WORLD'

processValue(value, processor) - Process Single Values

Process individual values using the default or a custom processor.

import { processValue, createProcessor } from 'es-toolkit-clean'

// Using default processor
const cleaned = processValue('  hello  ', processValue)
// → 'hello'

// Using custom processor
const upperProcessor = createProcessor({
  isString: (str) => str.trim().toUpperCase() || undefined
})
const result = processValue('  hello  ', upperProcessor)
// → 'HELLO'

Configuration Options

The defaultProcessors object defines how each data type is handled:

import { defaultProcessors } from 'es-toolkit-clean'

// Default configuration:
const config = {
  isArray: cleanArray,        // Recursively clean arrays, remove if empty
  isBoolean: identity,        // Keep all boolean values  
  isDate: identity,          // Keep all date values
  isFunction: noop,          // Remove all functions
  isNull: identity,          // Keep all null values
  isNumber: identity,        // Keep all number values (including 0)
  isObjectLike: cleanObject,  // Clean class instances, convert to plain objects
  isPlainObject: cleanObject, // Recursively clean objects, remove if empty  
  isString: cleanString,     // Trim whitespace, remove if empty
  isUndefined: noop,         // Remove all undefined values
}

Customization Examples

import { createCleaner, defaultProcessors } from 'es-toolkit-clean'

// Remove all falsy values except 0
const removeFalsy = createCleaner({
  ...defaultProcessors,
  isNull: () => undefined,
  isBoolean: (val) => val || undefined,
  isString: (str) => str.trim() || undefined
})

// Custom number processing
const positiveNumbers = createCleaner({
  ...defaultProcessors,
  isNumber: (num) => num > 0 ? num : undefined
})

// Custom array processing  
const nonEmptyArrays = createCleaner({
  ...defaultProcessors,
  isArray: (arr, clean) => {
    const cleaned = arr.map(item => clean(item, clean))
      .filter(item => item !== undefined)
    return cleaned.length >= 2 ? cleaned : undefined // Require at least 2 items
  }
})

Advanced Examples

Complex Object Cleaning

import clean from 'es-toolkit-clean'

const apiResponse = {
  user: {
    id: 123,
    name: 'John Doe',
    email: '',
    phone: '   ',
    profile: {
      bio: '',
      avatar: 'https://example.com/avatar.jpg',
      settings: {
        theme: '',
        notifications: true,
        metadata: {}
      }
    }
  },
  posts: [
    { title: 'Hello', content: '', tags: ['', 'intro'] },
    { title: '', content: '', tags: [] },
    { title: 'World', content: 'Content here', tags: ['update', ''] }
  ],
  emptyArray: [],
  nullValue: null,
  undefinedValue: undefined
}

const cleaned = clean(apiResponse)
console.log(cleaned)
// Output:
// {
//   user: {
//     id: 123,
//     name: 'John Doe',
//     profile: {
//       avatar: 'https://example.com/avatar.jpg',
//       settings: {
//         notifications: true
//       }
//     }
//   },
//   posts: [
//     { title: 'Hello', tags: ['intro'] },
//     { title: 'World', content: 'Content here', tags: ['update'] }
//   ],
//   nullValue: null
// }

Working with Different Data Types

import clean from 'es-toolkit-clean'

// Array cleaning
const messyArray = ['valid', '', '  ', null, undefined, 0, false, 'another']
const cleanedArray = clean(messyArray)
// → ['valid', null, 0, false, 'another']

// String cleaning  
const messyString = '   hello world   '
const cleanedString = clean(messyString)
// → 'hello world'

// Nested structures
const nested = {
  level1: {
    level2: {
      level3: {
        value: '',
        keep: 'this'
      },
      empty: ''
    },
    alsoEmpty: []
  }
}
const cleanedNested = clean(nested)
// → { level1: { level2: { level3: { keep: 'this' } } } }

Class Instance Cleaning

The library automatically handles class instances by converting them to plain objects while cleaning their properties:

import clean, { createCleaner } from 'es-toolkit-clean'

class User {
  constructor(data) {
    this.name = data.name
    this.email = data.email
    this.role = data.role
  }
}

class ApiResponse {
  constructor(data) {
    this.user = new User(data.user)
    this.metadata = data.metadata
    this.timestamp = new Date()
  }
}

const response = new ApiResponse({
  user: {
    name: 'John',
    email: '',        // Empty string - will be removed
    role: 'admin'
  },
  metadata: {
    version: '',      // Empty string - will be removed  
    source: 'api'
  }
})

const cleaned = clean(response)
console.log(cleaned)
// Output: Plain object (not ApiResponse instance)
// {
//   user: { name: 'John', role: 'admin' },
//   metadata: { source: 'api' },
//   timestamp: 2025-06-10T12:00:00.000Z
// }

// Class instances become plain objects
console.log(cleaned.constructor.name) // → 'Object'
console.log(response.constructor.name) // → 'ApiResponse'

The library intelligently distinguishes between:

  • Class instances (converted to plain objects and cleaned)
  • Plain objects (cleaned in place)
  • Special objects (Date, RegExp, Map, Set, Error - preserved as-is)
import clean from 'es-toolkit-clean'

const mixed = {
  classInstance: new User({ name: 'test', email: '' }),
  plainObject: { value: 'keep', empty: '' },
  date: new Date(),
  regex: /pattern/g,
  map: new Map([['key', 'value']]),
  set: new Set([1, 2, 3])
}

const result = clean(mixed)
// → {
//     classInstance: { name: 'test' },  // Class → plain object, cleaned
//     plainObject: { value: 'keep' },   // Plain object, cleaned
//     date: 2025-06-10T12:00:00.000Z,   // Date preserved
//     regex: /pattern/g,                // RegExp preserved
//     map: Map(1) { 'key' => 'value' }, // Map preserved
//     set: Set(3) { 1, 2, 3 }           // Set preserved
//   }

Helper Functions

The library also exports individual helper functions for specific use cases:

import { cleanArray, cleanObject, cleanString } from 'es-toolkit-clean'

// Clean individual strings
const cleaned = cleanString('  hello  ') // → 'hello'
const empty = cleanString('   ') // → undefined

// Clean arrays with custom processor
import { createProcessor } from 'es-toolkit-clean'
const processor = createProcessor()
const cleanedArray = cleanArray(['test', '', 'valid'], processor)
// → ['test', 'valid']

// Clean objects with custom processor  
const cleanedObject = cleanObject({ 
  name: 'test', 
  empty: '', 
  value: 42 
}, processor)
// → { name: 'test', value: 42 }

TypeScript Support

The library is written in TypeScript and provides comprehensive type definitions:

import clean, { 
  createCleaner, 
  createProcessor, 
  defaultProcessors,
  type ProcessorConfig,
  type CleanerFunction 
} from 'es-toolkit-clean'

// Custom processor with full type safety
const customCleaner: CleanerFunction = createCleaner({
  ...defaultProcessors,
  isString: (str: string): string | undefined => {
    return str.length > 5 ? str.toLowerCase() : undefined
  }
})

interface User {
  name: string
  email?: string
  age: number
}

const user: User = { name: 'John', email: '', age: 25 }
const cleaned = clean(user) // Fully typed

Performance

Built on es-toolkit, this library offers excellent performance characteristics:

  • Tree-shakable: Only include the functions you use
  • Zero dependencies: Apart from es-toolkit core functions
  • Optimized algorithms: Efficient recursive processing
  • Memory efficient: Creates new objects without mutating originals

Development

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Build the library
pnpm build

# Type checking
pnpm typecheck

# Linting
pnpm lint

API Reference

Functions

| Function | Description | Parameters | Returns | |----------|-------------|------------|---------| | clean(obj) | Clean any data structure with default settings | obj: unknown | unknown | | createCleaner(config) | Create custom cleaner function | config: Partial<ProcessorConfig> | (obj: unknown) => unknown | | createProcessor(config) | Create custom value processor | config: Partial<ProcessorConfig> | CleanerFunction | | processValue(value, processor) | Process single value | value: unknown, processor: CleanerFunction | unknown |

Configuration

| Property | Type | Default Behavior | Customizable | |----------|------|------------------|--------------| | isArray | (arr: unknown[], clean: CleanerFunction) => unknown | Recursively clean, remove if empty | ✅ | | isBoolean | (val: boolean) => unknown | Keep all booleans | ✅ | | isDate | (date: Date) => unknown | Keep all dates | ✅ | | isFunction | (fn: Function) => unknown | Remove all functions | ✅ | | isNull | (val: null) => unknown | Keep all nulls | ✅ | | isNumber | (num: number) => unknown | Keep all numbers | ✅ | | isObjectLike | (obj: Record<string, unknown>, clean: CleanerFunction) => unknown | Clean class instances, convert to plain objects | ✅ | | isPlainObject | (obj: Record<string, unknown>, clean: CleanerFunction) => unknown | Recursively clean, remove if empty | ✅ | | isString | (str: string) => unknown | Trim, remove if empty | ✅ | | isUndefined | (val: undefined) => unknown | Remove all undefined | ✅ |

License

MIT © Serhii Siryk

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.