{"id":12159,"library":"totalist","title":"totalist","description":"totalist is a highly optimized, minimalist (under 250 bytes gzipped) utility for recursively listing all files within a specified directory in Node.js. It enables developers to efficiently traverse file systems and apply a custom callback function to each file found, providing the relative path, absolute path, and the `fs.Stats` object directly. The package offers both asynchronous (default, since Node.js 8.x) and synchronous (since Node.js 6.x) modes to accommodate various application contexts and performance requirements. The current stable version is 3.0.1, which includes native ESM support via `exports` maps. Its primary differentiators are its minuscule footprint, direct integration with `fs.Stats` within the callback, and the avoidance of generating intermediate large file lists, making it suitable for performance-critical scenarios.","status":"active","version":"3.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/lukeed/totalist","tags":["javascript","list","recursive","files","glob","tree","typescript"],"install":[{"cmd":"npm install totalist","lang":"bash","label":"npm"},{"cmd":"yarn add totalist","lang":"bash","label":"yarn"},{"cmd":"pnpm add totalist","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the default async version. In v3+, `require` might work depending on bundler/Node.js version, but direct ESM import is preferred. This must be `await`ed.","wrong":"const { totalist } = require('totalist');","symbol":"totalist","correct":"import { totalist } from 'totalist';"},{"note":"This imports the synchronous version, suitable for contexts where async/await is not an option or desired. ESM import is preferred in v3+.","wrong":"const { totalist } = require('totalist/sync');","symbol":"totalist (sync)","correct":"import { totalist } from 'totalist/sync';"},{"note":"The callback receives an `fs.Stats` object. Import `Stats` type from Node's built-in 'fs' module for TypeScript.","symbol":"fs.Stats type","correct":"import type { Stats } from 'fs';"}],"quickstart":{"code":"import { totalist } from 'totalist/sync';\nimport { resolve } from 'path';\nimport { fileURLToPath } from 'url';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\n\n// Create a dummy directory for demonstration\nconst __dirname = fileURLToPath(new URL('.', import.meta.url));\nconst testDir = resolve(__dirname, 'temp_files');\nif (!existsSync(testDir)) {\n  mkdirSync(testDir, { recursive: true });\n}\nwriteFileSync(resolve(testDir, 'file1.js'), 'console.log(\"file1\");');\nwriteFileSync(resolve(testDir, 'style.css'), 'body { color: red; }');\nwriteFileSync(resolve(testDir, 'another.js'), 'console.log(\"file2\");');\nmkdirSync(resolve(testDir, 'subdir'), { recursive: true });\nwriteFileSync(resolve(testDir, 'subdir', 'nested.txt'), 'nested content');\n\nconst scripts = new Set();\nconst styles = new Set();\nconst others = new Set();\n\ntry {\n  totalist(testDir, (name, abs, stats) => {\n    if (name.endsWith('.js')) {\n      scripts.add(abs);\n    } else if (name.endsWith('.css')) {\n      styles.add(abs);\n    } else {\n      others.add(abs);\n    }\n    console.log(`Processing: ${name} (size: ${stats.size} bytes)`);\n  });\n\n  console.log('\\n--- Summary ---');\n  console.log('JavaScript files:', [...scripts]);\n  console.log('CSS files:', [...styles]);\n  console.log('Other files:', [...others]);\n} catch (error) {\n  console.error('Error listing files:', error);\n}\n\n// Clean up dummy directory (optional, but good for examples)\n// import { rmSync } from 'fs';\n// rmSync(testDir, { recursive: true, force: true });","lang":"typescript","description":"This quickstart demonstrates how to use `totalist/sync` to recursively scan a directory and categorize files based on their extensions. It sets up a temporary directory with various files and then logs the categorized absolute paths and file sizes."},"warnings":[{"fix":"Upgrade Node.js to a stable version (14+) or use `totalist` v2.x if upgrading Node.js is not possible.","message":"Version 3.0.0 introduced native ESM support via the `exports` mapping in `package.json`. This may cause breaking changes for Node.js versions 13.0 through 13.7 due to their experimental and rapidly evolving module resolution behavior. Users on these specific Node.js versions should upgrade to a later stable release (14+ recommended) or remain on `totalist` v2.x.","severity":"breaking","affected_versions":"3.0.0"},{"fix":"Ensure `await totalist(dir, callback);` is used within an `async` function, or chain with `.then(() => { ... })`.","message":"The default `totalist` export is asynchronous and returns a Promise. It must be `await`ed or handled within a Promise chain to ensure all files are processed before subsequent code executes. Failing to `await` it will result in the function returning immediately without processing files, potentially leading to incorrect program state.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Choose the correct import path based on your required execution mode: `import { totalist } from 'totalist';` for async, or `import { totalist } from 'totalist/sync';` for sync.","message":"There are two distinct modes: asynchronous (`totalist`) and synchronous (`totalist/sync`). Incorrectly importing the async version when synchronous behavior is expected, or vice-versa, can lead to unexpected execution flow or errors. The sync version requires `import { totalist } from 'totalist/sync';`.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For ESM projects, use `import { totalist } from 'totalist';` or `import { totalist } from 'totalist/sync';`. If still encountering issues in a CommonJS context, ensure your Node.js version is compatible with `exports` maps or consider using `totalist` v2.x.","cause":"Attempting to use `require` for `totalist` in a pure ESM context, or using a CommonJS `require` call that doesn't correctly resolve the module's default export when `exports` are defined.","error":"TypeError: totalist is not a function"},{"fix":"Always `await` the asynchronous `totalist` call: `await totalist(dir, callback);`. Ensure the calling function is marked `async`.","cause":"The asynchronous `totalist` function was called but not `await`ed, leading to subsequent code attempting to use data (like `stats.size`) before the callback had a chance to populate it.","error":"UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'size' of undefined"},{"fix":"Verify the package is installed correctly (`npm install totalist`). Ensure your import statement is exactly `import { totalist } from 'totalist/sync';` and your bundler/Node.js environment supports subpath exports.","cause":"This error typically indicates that the module resolution failed to locate the synchronous variant of totalist, possibly due to an incorrect path, a non-standard module resolution setup, or a problem with the installed package.","error":"Error: Cannot find module 'totalist/sync'"}],"ecosystem":"npm"}