const fs = require('fs') const { promisify } = require('util') const cache = {} const readFile = path => cache[path] = cache[path] || JSON.parse(fs.readFileSync(path)) const readDir = promisify(fs.readdir) const DEPS_FIELDS = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'] function isDependency(path, anotherPath) { const details = readFile(`${path}/package.json`) const anotherDetails = readFile(`${anotherPath}/package.json`) return DEPS_FIELDS.some(field => anotherDetails[field] && anotherDetails[field][details.name]) } async function resolve(folder) { const items = await readDir(folder) const packagesPath = items.filter(path => fs.lstatSync(`${folder}/${path}`).isDirectory()) const copy = packagesPath.slice(0) const result = [] const insert = (path) => { packagesPath .filter((anotherPath) => { return isDependency(`${folder}/${anotherPath}`, `${folder}/${path}`) }) .forEach(insert) if (!result.includes(path)) { result.push(path) const index = copy.indexOf(path) index !== -1 && copy.splice(index, 1) } } let path while (path = copy.pop()) { insert(path) } return result } resolve('../packages') .then(items => console.log(items)) .catch(console.error)