{"id":13467390,"url":"https://github.com/alexanderGugel/ied","last_synced_at":"2025-03-26T02:31:21.655Z","repository":{"id":36033236,"uuid":"40329787","full_name":"alexanderGugel/ied","owner":"alexanderGugel","description":":package: Like npm, but faster - an alternative package manager for Node","archived":false,"fork":false,"pushed_at":"2017-01-10T06:30:18.000Z","size":4245,"stargazers_count":1988,"open_issues_count":43,"forks_count":53,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-03-24T02:14:30.076Z","etag":null,"topics":["node","package-manager"],"latest_commit_sha":null,"homepage":"http://alexandergugel.github.io/ied","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexanderGugel.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-06T22:30:30.000Z","updated_at":"2025-03-15T04:03:46.000Z","dependencies_parsed_at":"2022-07-09T15:37:31.418Z","dependency_job_id":null,"html_url":"https://github.com/alexanderGugel/ied","commit_stats":null,"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexanderGugel%2Fied","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexanderGugel%2Fied/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexanderGugel%2Fied/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexanderGugel%2Fied/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexanderGugel","download_url":"https://codeload.github.com/alexanderGugel/ied/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245576529,"owners_count":20638125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["node","package-manager"],"created_at":"2024-07-31T15:00:55.818Z","updated_at":"2025-03-26T02:31:21.615Z","avatar_url":"https://github.com/alexanderGugel.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Resources","package-manager"],"sub_categories":["[Npm](https://www.npmjs.com)"],"readme":"ied\n===\n\n[![Travis](https://img.shields.io/travis/alexanderGugel/ied.svg)](https://travis-ci.org/alexanderGugel/ied)\n[![npm](https://img.shields.io/npm/v/ied.svg)](https://www.npmjs.com/package/ied)\n[![Inline docs](http://inch-ci.org/github/alexanderGugel/ied.svg?branch=master\u0026style=shields)](http://inch-ci.org/github/alexanderGugel/ied)\n\n```\n__/\\\\\\\\\\\\\\\\\\\\\\__/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\__/\\\\\\\\\\\\\\\\\\\\\\\\____\n _\\/////\\\\\\///__\\/\\\\\\///////////__\\/\\\\\\////////\\\\\\__\n  _____\\/\\\\\\_____\\/\\\\\\_____________\\/\\\\\\______\\//\\\\\\_\n   _____\\/\\\\\\_____\\/\\\\\\\\\\\\\\\\\\\\\\_____\\/\\\\\\_______\\/\\\\\\_\n    _____\\/\\\\\\_____\\/\\\\\\///////______\\/\\\\\\_______\\/\\\\\\_\n     _____\\/\\\\\\_____\\/\\\\\\_____________\\/\\\\\\_______\\/\\\\\\_\n      _____\\/\\\\\\_____\\/\\\\\\_____________\\/\\\\\\_______/\\\\\\__\n       __/\\\\\\\\\\\\\\\\\\\\\\_\\/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\_\\/\\\\\\\\\\\\\\\\\\\\\\\\/___\n        _\\///////////__\\///////////////__\\////////////_____\n```\n\nAn alternative package manager for Node.\n\n* **Concurrent Installations** - `ied` installs sub-dependencies in parallel.\n  This means that the download of a dependency might have been completed before\n  that of its parent or any of its siblings even started.\n\n* **Correct Caching** - Downloaded packages are being cached locally. Similarly\n  to the entry dependencies stored in `node_modules`, they are being identified\n  by their checksums. Therefore we can guarantee the consistency of the cache\n  itself without (manually) invalidating dependencies (e.g. due to overridden\n  version numbers).\n\n* **`node_modules` as CAS** - Packages are always being referenced by their\n  *SHA-1* checksums. Therefore a `node_modules` directory can be considered to\n  be a [Content Addressable\n  Storage](https://en.wikipedia.org/wiki/Content-addressable_storage), meaning\n  that packages are being identified by their contents, not by arbitrary\n  identifiers, such as package names that are not guaranteed to be unique\n  across different registries.\n\n* **Flat `node_modules`** - Due to the *CAS*-based design, conflicts due to\n  naming collisions are more or less impossible. Therefore all dependencies can\n  be stored in a flat directory structure. Circular dependencies and\n  dependencies on different versions of the same packages are still being\n  handled correctly.\n\n* **Guaranteed uniqueness** - Since the directory in which a specific package\n  is being stored is determined by its *shasum*, identical packages can't\n  conflict due to their location in the file system itself. This also means\n  that the same dependency won't be installed more than once. Dependencies\n  don't need to be explicitly declared as `peerDependencies`, since shared\n  sub-dependencies are the default, not an option.\n\n* **Atomic installs** - The atomicity of installs can be ensured on a\n  *package-level*. \"In progress\" downloads are being stored in\n  `node_modules/.tmp` and moved into `node_modules` once their download has\n  been completed. In order to prevent deadlocks, packages that have circular\n  dependencies are exempt from this limitation. In most cases however, the\n  `node_modules` directory is *consistent* at any given point in time during\n  the main installation procedure.\n\n* **Package names as links** - While packages are being referenced by their\n  *shasum* internally, they can still be required via their human-readable\n  equivalent name. Package names themselves are simply symbolic links to the\n  actual content-addressed package itself. A nice side-effect of this design is\n  that in contrast to other package managers, you can not accidentally require\n  a sub-dependency that hasn't been installed as such.\n\n* **Semantic Versioning** - [Semantic version numbers](http://semver.org/) are\n  being resolved correctly.\n\n* **Arbitrary package groups** - Packages can be grouped into \"package groups\",\n  such as `dependencies` and `devDependencies`. Dependencies can be installed\n  exclusively based on the group they are in.\n\n\nInternals\n---------\n\nUnder the hood, `ied` maintains an \"object database\", similar to `git`. Instead\nof storing packages by some arbitrary name, a SHA1-checksum is being generated\nto approximate their contents. The checksums can not only be used for\nguaranteeing a certain level of trust and consistency, but they also simplify\nthe algorithm through which dependencies are being managed.\n\nThe algorithm through which packages are being installed guarantees consistency\nthrough atomic installs. The installation of a package either fails or\nsucceeds, but at no point in time can a dependency itself be required without\nhaving its own sub-dependencies installed (with the exception of shared\ncircular dependencies).\n\nThe checksum of a package is based on the contents of the package itself, not\nof its sub-dependencies. Therefore the validity of a package can be verified by\nhashing the package itself. Subsequent dependency updates have no effect of the\ngenerated checksum.\n\nSince `node_modules` is essentially a file-system based content addressable\nstorage, multiple versions of the same package can co-exist in the same\nproject. In order to expose dependencies via CommonJS, symbolic links are being\ncreated that reference a specific version of the package. This has multiple\nadvantages:\n\n1. Undeclared dependencies that have been installed as sub-dependencies of\n   \"direct\" dependencies are unlikely to be required \"accidentally\".\n\n2. There is no need to \"manually\" (as in additionally to the installation\n   procedure itself) de-duplicate the dependency graph. As long as the\n   uniqueness of filenames itself can be guaranteed on an OS-level, it is\n   *impossible* to install the same package twice. This does not prevent users\n   from installing different versions of the same dependency as long as the\n   content is different (whereas a different version declared in the\n   `package.json` counts as different contents).\n\n3. Shorter pathnames and less problems due to OS-level limitations (as in\n   Windows where the maximum path length is limited).\n\n4. Additional application-level startup performance improvements. `require`\n   needs to traverse less directories. A limited number of symbolic links need\n   to be followed. This performance improvement is primarily useful for\n   continuously running tests, where startup time is actually noticeable for\n   larger test suits.\n\n\n### Directory Structure\n\nThe used directory structure is primarily optimized for reducing the amount of\nIO interaction with the file system during subsequent installations and\nguaranteeing the consistency of installed packages.\n\nA consequence of the\n[`require.resolve`](https://nodejs.org/api/modules.html#modules_all_together)\nalgorithm used by Node, all packages need to be stored in a project-level\n`node_modules` directory. This directory is completely flat on a package-level,\nmeaning that there are no nested packages inside it.\n\nInstead each package is being stored in its content-addressed directory. Such a\ndirectory has two sub-directories:\n\n* **package** - This is where the unpacked package contents is being stored. At\n  no point in time will this directory be modified. This enables us to verify\n  the integrity of the package at a later point in time by comparing the actual\n  checksum to the one defined by other dependents or registries.\n\n* **node_modules** - Sub-dependencies of the dependency installed in `package`\n  are being referenced by symbolic links in `node_modules` of the package\n  itself. `require.resolve` will fall-back to this level after failing to\n  locate a dependency in `package`. This means checked in dependencies are\n  still supported, provided that their sub-dependencies are also available\n  (anywhere in the dependency graph).\n\nOn a project level, the `node_modules` directory contains the fetched packages,\ninstalled dependencies and links that expose the packages to user-land via\n`require`.\n\nA comparison of sample directory structures produced by ied, npm 2 and npm 3 is\navailable as a [GitHub\nGist](https://gist.github.com/alexanderGugel/a10ed5655d366875a280).\n\n\nWhy?\n----\n\nThe original idea was to implement npm's pre-v3 install algorithm in as few\nlines as possible. This goal was achieved in\n[`c4ba56f`](https://github.com/alexanderGugel/ied/tree/c4ba56f7dece738db5b8cb28c20c7f6aa1e64d1d).\n\nCurrently the main goal of this project is to provide a more performant\nalternative to npm.\n\n\nInstallation\n------------\n\nThe easiest way to install ied is using [npm](https://www.npmjs.org/):\n\n```\nnpm i -g ied\n```\n\nAlternatively you can also \"bootstrap\" ied.\nAfter an initial installation via npm, ied will install its own dependencies:\n\n```\ngit clone https://github.com/alexanderGugel/ied ied \u0026\u0026 cd $_ \u0026\u0026 make install\n```\n\nUsage\n-----\n\nThe goal of `ied` is to support ~ 80 per cent of the npm commands that one uses\non a daily basis. Feature parity with npm **other than** with its installation\nprocess itself is not an immediate goal. Raw performance is the primary concern\nduring the development process.\n\nA global [configuration](src/config.js) can be supplied via environment\nvariables. `NODE_DEBUG` can be used in order to debug specific sub-systems. The\nprogress bar will be disabled in that case.\n\nAlthough `run-script` is supported, lifecycle scripts are not.\n\nAt this point in time, the majority of the command API is\n[self-documenting](bin/cmd.js). More extensive documentation will be available\nonce the API is stabilized.\n\nA high-level [USAGE](USAGE.txt) help is also supplied. The main goal is to\nkeep the API predictable for regular npm-users. This means certain flags, such\nas for example `--save`, `--save-dev`, `--save-optional`, are supported.\n\n```\n  ied is a package manager for Node.\n\n  Usage:\n\n    ied [command] [arguments]\n\n  The commands are:\n\n    install     fetch packages and dependencies\n    run         run a package.json script\n    shell       enter a sub-shell with augmented PATH\n    ping        check if the registry is up\n    config      print the used config\n    init        initialize a new package\n    link        link the current package or into it\n    unlink      unlink the current package or from it\n    start       runs `ied run start`\n    stop        runs `ied run stop`\n    build       runs `ied run build`\n    test        runs `ied run test`\n\n  Flags:\n    -h, --help          show usage information\n    -v, --version       print the current version\n    -S, --save          update package.json dependencies\n    -D, --save-dev      update package.json devDependencies\n    -O, --save-optional update package.json optionalDependencies\n    -r, --registry      use a custom registry\n                        (default: http://registry.npmjs.org/)\n    -b, --build         execute lifecycle scripts upon completion\n                        (e.g. postinstall)\n\n  Example:\n    ied install\n    ied install \u003cpkg\u003e\n    ied install \u003cpkg\u003e@\u003cversion\u003e\n    ied install \u003cpkg\u003e@\u003cversion range\u003e\n\n    Can specify one or more: ied install semver@^5.0.1 tape\n    If no argument is supplied, installs dependencies from package.json.\n    Sub-commands can also be called via their shorthand aliases.\n\n  README:  https://github.com/alexanderGugel/ied\n  ISSUES:  https://github.com/alexanderGugel/ied/issues\n```\n\nDevelopment notes\n-----------------\n\nTo run the test suite, run `npm test`. The test suite mocks all HTTP requests,\nwith fixtures cached inside `fixtures/generated/`. If you make new tests that\nperform HTTP requests, it'll be saved there.\n\n```\nnpm test\n```\n\nCredits\n-------\n\nSome ideas and (upcoming) features of `ied` are heavily inspired by\n[**Nix**](http://nixos.org/nix/), a purely functional package manager.\n\nLicense\n-------\n\nLicensed under the MIT license. See [LICENSE](LICENSE.md).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FalexanderGugel%2Fied","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FalexanderGugel%2Fied","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FalexanderGugel%2Fied/lists"}