{"id":14155464,"url":"https://github.com/pkgxdev/libpkgx","last_synced_at":"2025-04-12T13:33:15.615Z","repository":{"id":163425450,"uuid":"638902491","full_name":"pkgxdev/libpkgx","owner":"pkgxdev","description":"`import`… but with pkging powers","archived":false,"fork":false,"pushed_at":"2025-03-29T12:35:29.000Z","size":268,"stargazers_count":64,"open_issues_count":10,"forks_count":13,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-09T14:08:23.337Z","etag":null,"topics":["hacktoberfest","library","packaging"],"latest_commit_sha":null,"homepage":"https://npmjs.com/libpkgx","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pkgxdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-10T10:53:35.000Z","updated_at":"2025-03-29T12:33:06.000Z","dependencies_parsed_at":"2023-08-19T20:47:07.654Z","dependency_job_id":"87a458de-a288-46bd-8447-8d1785cb39e1","html_url":"https://github.com/pkgxdev/libpkgx","commit_stats":null,"previous_names":["teaxyz/lib"],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkgxdev%2Flibpkgx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkgxdev%2Flibpkgx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkgxdev%2Flibpkgx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pkgxdev%2Flibpkgx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pkgxdev","download_url":"https://codeload.github.com/pkgxdev/libpkgx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248573606,"owners_count":21126868,"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":["hacktoberfest","library","packaging"],"created_at":"2024-08-17T08:03:25.018Z","updated_at":"2025-04-12T13:33:13.245Z","avatar_url":"https://github.com/pkgxdev.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","library"],"sub_categories":[],"readme":"![pkgx.dev](https://pkgx.dev/banner.png)\n\n[![coverage][]][coveralls]\n\n# libpkgx\n\npkgx aims to provide packaging primitives. This library is a route to that\ngoal. libpkgx can create sandboxed environments for\npackages that have no effect on the wider system without you or your user\nneeding to install [pkgx].\n\n## Getting Started\n\n```sh\n$ npm install libpkgx\n# ^^ https://npmjs.com/libpkgx\n```\n\nOr with [Deno]:\n\n```ts\nimport * as pkgx from \"https://deno.land/x/libpkgx/mod.ts\"\n```\n\n## Usage\n\n```ts\nimport { porcelain } from \"libpkgx\";\nconst { run } = porcelain;\n\nawait run(`python -c 'print(\"Hello, World!\")'`);\n// ^^ installs python and its deps (into ~/.pkgx/python.org/v3.x.y)\n// ^^ runs the command\n// ^^ output goes to the terminal\n// ^^ throws on execution error or non-zero exit code\n// ^^ executes via `/bin/sh` (so quoting and that work as expected)\n```\n\nCapture stdout easily:\n\n```ts\nconst { stdout } = await run(`ruby -e 'puts \", World!\"'`, { stdout: true });\nconsole.log(\"Hello,\", stdout);\n```\n\n\u003e `{ stderr: true }` also works.\n\nIf there’s a non-zero exit code, we `throw`. However, when you need to,\nyou can capture it instead:\n\n```ts\nconst { status } = await run(`perl -e 'exit(7)'`, { status: true });\nassert(status == 7);  // ^^ didn’t throw!\n```\n\n\u003e The run function’s options also takes `env` if you need to supplement or\n\u003e replace the inherited environment (which is passed by default).\n\nNeed a specific version of something? [pkgx] can install any version\nof any package:\n\n```ts\nawait run([\"node^16\", \"-e\", \"console.log(process.version)\"]);\n// =\u003e v16.18.1\n```\n\n\u003e Notice we passed args as `string[]`. This is also supported and is often\n\u003e preferable since shell quoting rules can be tricky. If you pass `string[]`\n\u003e we execute the command directly rather than via `/bin/sh`.\n\nAll of pkgx’s packages are relocatable so you can configure pkgx to install\nwherever you want:\n\n```ts\nimport { hooks, Path, porcelain } from \"libpkgx\";\nconst { install } = porcelain;\nconst { useConfig } = hooks;\n\nuseConfig({ prefix: Path.home().join(\".local/share/my-app\") });\n// ^^ must be done **before** any other pkgx calls\n\nconst go = await install(\"go.dev\");\n// ^^ go.path = /home/you/.local/share/my-app/go.dev/v1.20.4\n```\n\n### Designed for Composibility\n\nThe library is split into [plumbing](src/plumbing) and [porcelain](src/porcelain) (copying git’s lead).\nThe porcelain is what most people need, but if you need more control, dive\ninto the porcelain sources to see how to use the plumbing primitives to get\nprecisely what you need.\n\nFor example if you want to run a command with node’s `spawn` instead it is\nsimple enough to first use our porcelain `install` function then grab the\n`env` you’ll need to pass to `spawn` using our `useShellEnv` hook.\n\nPerhaps what you create should go into the porcelain? If so, please open a PR.\n\n### Logging\n\nMost functions take an optional `logger` parameter so you can output logging\ninformation if you so choose. `pkgx` (cli) has a fairly sophisticated logger, so\ngo check that out if you want. For our porcelain functions we provide a simple\ndebug-friendly logger (`ConsoleLogger`) that will output everything via\n`console.error`:\n\n```ts\nimport { porcelain, plumbing, utils } from \"libpkgx\"\nconst { ConsoleLogger } = utils\nconst { run } = porcelain\n\nconst logger = ConsoleLogger()\nawait run(\"youtube-dl youtu.be/xiq5euezOEQ\", { logger }).exec()\n```\n\n### Caveats\n\nWe have our own implementation of semver because open source has existed for\ndecades and Semantic Versioning is much newer than that. Our implementation is\nquite compatible but not completely so. Use our semver with libpkgx.\nOur implementation is 100% compatible with strings output from node’s own\nsemver.\n\nSetting `useConfig()` is not thread safe. Thus if you are using web workers\nyou must ensure the initial call to `useConfig()` is called on the main thread\nbefore any other calls might happen. We call it explicitly in our code so you\nwill need to call it yourself in such a case. This is not ideal and we’d\nappreciate your help in fixing it.\n\nThe plumbing has no magic. Libraries need well defined behavior.\nYou’ll need to read the docs to use them effectively.\n\nlibpkgx almost certainly will not work in a browser. Potentially it's possible.\nThe first step would be compiling our bottles to WASM. We could use your help\nwith that…\n\nWe use a hook-like pattern because it is great. This library is not itself\ndesigned for React.\n\nWe support the same platforms as [pkgx].\n\n## What Packages are Available?\n\nWe can install anything in the [pantry].\n\nIf something you need is not there, adding to the pantry has been designed to\nbe an easy and enjoyable process. Your contribution is both welcome and\ndesired!\n\nTo see what is available refer to the [pantry] docs or you can run:\n`pkgx pkg search foo`.\n\n\u0026nbsp;\n\n# Interesting Uses\n\n* You can grab cURL’s CA certificates which we pkg and keep up to date\n  (`curl.se/ca-certs`). These are commonly needed across ecosystems but not\n  always easily accessible.\n* grab libraries that wrappers need like openssl or sqlite\n* run a real database (like postgres) easily\n* load local AI models and their engines\n* load libraries and then use ffi to load symbols\n\n\u0026nbsp;\n\n# Contributing\n\nWe would be thrilled to hear your ideas† or receive your pull requests.\n\n\u003e † [discussions][discussion]\n\n## Anatomy\n\nThe code is written with Deno (just like [pkgx]) but is compiled to a\nnode package for wider accessibility (and ∵ [pkgx] is node/electron).\n\nThe library is architected into hooks, plumbing and porcelain. Where the hooks\nrepresent the low level primitives of pkging, the plumbing glues those\nprimitives together into useful components and the porcelain is a user\nfriendly *façade* pattern for the plumbing.\n\n## Supporting Other Languages\n\nWe would love to port this code to every language. We are deliberately keeping\nthe scope *tight*. Probably we would prefer to have one repo per language.\n\npkgx has sensible rules for how packages are defined and installed so writing\na port should be simple.\n\nWe would love to explore how possible writing this in rust and then compiling\nto WASM for all other languages would be. Can you help?\n\nOpen a [discussion] to start.\n\n[discussion]: https://github.com/orgs/pkgxdev/discussions\n[pkgx]: https://github.com/pkgxdev/pkgx\n[Deno]: https://deno.land\n[pantry]: https://github.com/pkgxdev/pantry\n[plumbing]: ./plumbing/\n[porcelain]: ./porcelain/\n[coverage]: https://coveralls.io/repos/github/pkgxdev/libpkgx/badge.svg\n[coveralls]: https://coveralls.io/github/pkgxdev/libpkgx\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkgxdev%2Flibpkgx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpkgxdev%2Flibpkgx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpkgxdev%2Flibpkgx/lists"}