{"id":13661184,"url":"https://github.com/needle-tools/hybrid-packages","last_synced_at":"2025-10-28T07:07:35.562Z","repository":{"id":108905859,"uuid":"356609921","full_name":"needle-tools/hybrid-packages","owner":"needle-tools","description":"Export UPM packages as .unitypackage files","archived":false,"fork":false,"pushed_at":"2023-11-24T19:29:53.000Z","size":397,"stargazers_count":134,"open_issues_count":3,"forks_count":13,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-10-22T03:59:46.341Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","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/needle-tools.png","metadata":{"files":{"readme":"Readme.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-04-10T14:42:49.000Z","updated_at":"2025-10-18T01:14:18.000Z","dependencies_parsed_at":"2023-04-04T05:34:56.720Z","dependency_job_id":null,"html_url":"https://github.com/needle-tools/hybrid-packages","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/needle-tools/hybrid-packages","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/needle-tools%2Fhybrid-packages","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/needle-tools%2Fhybrid-packages/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/needle-tools%2Fhybrid-packages/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/needle-tools%2Fhybrid-packages/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/needle-tools","download_url":"https://codeload.github.com/needle-tools/hybrid-packages/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/needle-tools%2Fhybrid-packages/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281398027,"owners_count":26494070,"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","status":"online","status_checked_at":"2025-10-28T02:00:06.022Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-08-02T05:01:30.750Z","updated_at":"2025-10-28T07:07:35.545Z","avatar_url":"https://github.com/needle-tools.png","language":"C#","funding_links":[],"categories":["C\\#"],"sub_categories":[],"readme":"# Hybrid Packages\n\n![Unity Version Compatibility](https://img.shields.io/badge/Unity-2018.4%20%E2%80%94%202022.1-brightgreen)\n\nUnity has two separate package formats:\n- `.unitypackage`, a zip-based file format that is used on the Asset Store\n- `UPM package`, to prepare modules for Unity's package manager.\n  \nThe latter is newer, enforces better code and directory structure (AsmDefs required), and generally much easier to work with / add / remove / update.\n\nSo far, it has been impossible to ship UPM packages on the Asset Store or via `.unitypackage` files.  \nThis package fixes that by introducing **Hybrid Packages**, regular .unitypackage files that contain the correct directory structures for UPM.  \nAfter installing this package, you can select assets and folders from the Packages folder to be exported, which \n- allows packages to be uploaded to the Asset Store through the regular Asset Store Tools\n- enables \u003ckbd\u003eAssets/Export Package\u003c/kbd\u003e to export stuff from package folders directly\n\nThe resulting .unitypackage files _do not require any additional setup for users_. This package here is only required for creating those `.unitypackage` files, not for importing them.\n\n**If you switch to Hybrid Packages today, the transition to \"registry-based\" packages will be much more painless, as all your code and content will be ready on day 1.**  \n\n## Update (October 2022): Unity has listened and added Hybrid Packages support to their Asset Store Tools!  \n\nIt's experimental and needs to be explcitily enabled. There's two ways:  \n\n- either add the Hybrid Packages package (this one)!  \n- or add the scripting define `UNITY_ASTOOLS_EXPERIMENTAL` in Project Settings.  \n\n\u003e **Note**: We still recommend installing the Hybrid Packages package as it fixes some current issues in Unity's tool, like selecting packages with `file:..` references.   \n\nThis will unlock a new option in the Asset Store Uploader window:  \n\n![20221030-024915_Unity](https://user-images.githubusercontent.com/2693840/198858071-9e3fc114-3636-4049-a2cf-d451f51297e9.png)\n\n**Fun fact:** the Asset Store Tools ship as Hybrid Package themselves!  \n\n![image](https://user-images.githubusercontent.com/2693840/198858153-57f5f9ba-c1c7-406e-9fb6-06594876a522.png)\n\n\n## Installation 💾\n1. \n    \u003cdetails\u003e\n    \u003csummary\u003eAdd the OpenUPM registry with the \u003ccode\u003ecom.needle\u003c/code\u003e scope to your project\u003c/summary\u003e\n\n    - open \u003ckbd\u003eEdit/Project Settings/Package Manager\u003c/kbd\u003e\n    - add a new Scoped Registry:\n    ```\n    Name: OpenUPM\n    URL:  https://package.openupm.com/\n    Scope(s): com.needle\n    ```\n    - click \u003ckbd\u003eSave\u003c/kbd\u003e\n    \u003c/details\u003e\n2. Add this package:\n   - open \u003ckbd\u003eWindow/Package Manager\u003c/kbd\u003e\n   - click \u003ckbd\u003e+\u003c/kbd\u003e\n   - click \u003ckbd\u003eAdd package from git URL\u003c/kbd\u003e or \u003ckbd\u003eAdd package by name\u003c/kbd\u003e\n   - paste `com.needle.upm-in-unitypackage`\n   - click \u003ckbd\u003eAdd\u003c/kbd\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cem\u003eAlternative: git package (no PackMan updates, not recommended)\u003c/em\u003e\u003c/summary\u003e  \n\n   - open \u003ckbd\u003eWindow/Package Manager\u003c/kbd\u003e\n   - click \u003ckbd\u003e+\u003c/kbd\u003e\n   - click \u003ckbd\u003eAdd package from git URL\u003c/kbd\u003e or \u003ckbd\u003eAdd package by name\u003c/kbd\u003e  \n   - Add `https://github.com/needle-tools/upm-in-unitypackage.git` in Package Manager  \n\n\u003c/details\u003e\n\n## How to use 💡\n\n### Export a .unitypackage that contains files in Packages or entire packages\n1. select what you want to export\n2. hit \u003ckbd\u003eAssets/Export Package\u003c/kbd\u003e (also available via right click on Assets/Folders).  \n\n### Upload Packages to Asset Store directly\n\n1. Install the Asset Store Tools as usual: https://assetstore.unity.com/packages/tools/utilities/asset-store-tools-115\n2. Open \u003ckbd\u003eAsset Store Tools/Asset Store Uploader\u003c/kbd\u003e\n3. Find your draft package in the list (must have already created on Unity Publisher Portal)\n4. Choose the \"Local UPM Package\" upload type\n5. Use the \"Browse\" button to select your package directory\n6. Select additional packages as needed in the \"Extra Packages\" section\n7. Press \u003ckbd\u003eUpload\u003c/kbd\u003e\n\n#### Using an Upload Config to create and upload .unitypackage files\n\nUsing a configuration file makes it easier to specify settings for export, and allows for \"Package Bundles\" (multiple packages in one `.unitypackage`).  \n\nHere's how it works:  \n\n1. Create a folder for your \"package collection\" in Assets, e.g. \"My Package Collection\".\n2. In that folder, right click and create a `Needle/Asset Store Upload Config`.\n3. Add entries to the `Selection`\" array and drag the folders/files into the `Item` field. \n   For packages, drag in the `package.json` since package folders can't be drag-dropped.  \n   This can be a single file, a folder, one or multiple packages, or a combination of these.  \n4. To test your Hybrid Package locally, select your config, and click \u003ckbd\u003eExport for Local Testing\u003c/kbd\u003e.  \n   This produces exactly the same .unitypackage as on Store upload, so you can test this one by importing it into a different/empty project.  \n5. Open \u003ckbd\u003eAsset Store Tools/Asset Store Uploader\u003c/kbd\u003e\n4. Choose the \"Pre-exported unitypackage\" upload type\n5. Select the .unitypackage you already exported that contains package data\n7. Press \u003ckbd\u003eUpload\u003c/kbd\u003e\n\n## Known Issues / Limitations\n- The optional \u003ckbd\u003eValidate\u003c/kbd\u003e step isn't supported yet. Export your package via \u003ckbd\u003eRight Click/Export Package\u003c/kbd\u003e or an Upload Config and test in a separate project for now.\n- Dependencies into other packages shouldn't be exported, so you must turn off \"Include Dependencies\" when exporting a package.\n- The `package.json` of your package can [define dependencies](https://docs.unity3d.com/Manual/upm-manifestPrj.html). However, only dependencies from the Unity Registry will be automatically resolved in empty projects - we'll need to think of a separate mechanism / guidance for people to add dependencies from scoped registries. For now, it's recommended that you guard against missing dependencies via [Version Defines](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html#define-symbols).\n- .unitypackage preview images for hidden folders will not be exported unless you're on 2020.1+ and had that folder in the AssetDatabase in the current session (e.g. the folder was named \"Samples\" and then \"Samples~\" to hide it before export).\n- There's experimental support for .gitignore and .npmignore, but the behaviour isn't exactly the same as with npm/git (e.g. when multiple of these are in different folders, the order they are applied isn't always correct). You can turn this on on the UploadConfig asset.\n- The AssetStore Tools sometimes get stuck in an endless loop when trying to export nearly empty folders or empty multi-package sets. This seems to be an AssetStore Tools bug.\n\n----------\n\n## FAQ / Why should I use this?\n\nHybrid Packages are an in-between solution. Unity is still not ready for a proper, registry-based package workflow for the Asset Store. Hybrid Packages allow Asset Store developers to switch to a package-based workflow today, with some (but not all) of the benefits of that, with no (known) downsides compared to the current workflow.  \nIf you switch to Hybrid Packages today, the transition to \"registry-based\" packages will be much more painless, as all your code and content will be ready on day 1.  \n\n### How are these packaged up by your tool during submission?\nNothing changes, same process as the regular \"Export \u003e Unity Package\" flow or \"Asset Store Tools \u003e Upload\" (which are the same). Our tooling mostly just disables the check for \"is this in assets?\" and thus allows you to upload your embedded/local packages to the AssetStore.  \n\n### When they are unpacked during installation, where do the assets wind up?\nThe files that before went into  \n`Assets/YourContent/\u003call your content\u003e`  \nnow end up in  \n`Packages/com.your.content/ \u003call your content\u003e`.   \nThis is what's called an embedded package. It is mutable, that is, users can change the files. It is not in the library, and files don't get duplicated into the `Library/PackageCache` folder. Also, this folder is not (and should not) be excluded from source control. From a file system perspective, it's really just a move from `Assets/` to `Packages/`, bringing some of the package benefits with it.  \n\nHere's an example of how this looks for the Asset Store Tools themselves, which also ship as Hybrid Package:  \n![image](https://user-images.githubusercontent.com/2693840/198858135-1795f67d-9121-4835-95e4-214c237ecfb7.png)\n\n### How does Unity treat these assets when they are placed in the new (and non-standard) location?\nFor assets, nothing changes, no new/different rules. This is the same as if a user makes a `Packages/com.your.content/` folder and moves the files there (what a good number of users are already doing anyways). For scripts, Unity's rules for packages apply: code needs to be in AsmDefs to be compiled. This enforces better code structure, faster compilation, and is benefictial no matter if in \"Assets\" or \"Packages\".  \n\n### Do these packages appear in the Package Manager at all? If so, can I use the \"Install Sample\" (or whatever it is) feature? How does that work?\nYes, this is one of the main points! Hybrid Packages\n- show up in PackMan\n- can use package.json dependencies\n- can ship samples that can be installed via Package Manager. Samples are shipped with your .unitypackage in a folder called `Samples~` and set up via package.json. (see below for more on this)\n\n### How does this differ from the package lifecycle for packages installed via Package Manager?\nLocal Packages don't come from a registry, they're just \"local\". That is, they can't be updated via `PackageManager/In Project`. They still get updated by users from `Package Manager/My Assets` by downloading the new version and it gets \"unpacked\" over the old, as before. So, same rules still apply for updates: if you removed files, ask users to delete the folder before importing.  \n\n_Before_ the existance of Hybrid Packages, installing Asset Store Content in user projects was mostly a fire-and-forget operation:  \nUsers download a package, install it, and then neither the user nor Package Manager have any information that this content is actually in the project (of course the user can look for the folder, but the point is there's no real \"entry point\" for the content).  \n\n_Now_, with Hybrid Packages, the content actually shows up in clear, structured places after installation:  \n- as a package in the project, under `Packages/Your Content` in the Project Window  \n- in the `In Project` section in Package Manager, with the ability to install Samples  \n- Updates are still done in the `My Assets` section as before.  \n\nWhen the package is _not_ installed, it only shows up in \"My Assets\", as before. No change here.  \n\n### How do I prepare my asset for the package workflow?\nYou create a local or embedded package: you define your own package.json file and add the relevant details such as your package name/version/description/author, set up \"Runtime\" and \"Editor\" folders.  \n\nYou move your code and assets over: make sure that all scripts are part of AsmDef files, that are properly marked for \"Runtime\" or \"Editor\". Mostly, that's it!  \n\n_Recommended:_ Add a documentationUrl in your package.json, pointing at your docs either locally or on the web. This will be opened when people click on \"Documentation\" for your package in Package Manager.  \n\nAlso see \u003ca href=\"#guide-to-packages\"\u003eGuide to Packages\u003c/a\u003e.\n\n### Now that dependencies can be specified via package.json, what happens to the \"Include Dependencies\" functionality in the Asset Store Tools?\nThe \"Include Dependencies\" is now redundant. It never worked great (sometimes including way too many dependencies), and you have much more fine-grained control by adding exactly the dependencies you need to your package.json.  \nThis has the additional benefit that dependencies aren't forcefully added to user project manifests (as with the Asset Store solution) - they are only resolved as long as your package is actually in the project.\n\n### How do I add samples that can be installed via Package Manager?\nIn your package.json, you can declare an array of samples for your package:  \n\n```\"samples\": [ { \"displayName\" : \"..\", \"description\":\"...\", \"path\":\"Samples~/...\" } ]```  \n\nSamples are stored in folders. These all live in a folder called `Samples~` (note the tilde), which is hidden in Unity.  \nWhile you work on your samples, you simply rename the folder to `Samples`, and before submitting, you rename it back to `Samples~`.  \n\nThe advantage of shipping samples this way is that while samples are already downloaded and ready to be used, they don't clutter the asset database of user projects – only once people import the sample is it copied over to their Assets folders, ready to be adjusted as needed.  \n\n### What differences, if any, are there regarding Unity's Special Folders? Is the functionality the same? Do Gizmos and other folders still work as expected?\n\n### Future: How do I prepare my asset for the future \"registry-based\" package workflow?\n\n_Note: some of the below depends on how Unity implements this for Asset Store publishers._\n\nThe main change with \"registry-based\" packages is that they are immutable, which means that users can't change the files in the package (they can still \"embed\" the package and make it locally editable, like you can for all Unity packages).  \n\nBut the goal is that your package is a single thing, nobody changes the content of it. Users then compose their project out of these assets as usual, e.g. they use animation files, models, materials, make new prefab variants, use components, ...  \n\nOne thing that you can't do anymore at this point is write your own files (e.g. settings) into your package once it's in users hands. Thus, your settings should live in a proper place depending on whether they need to be accessible in the Editor only (ProjectSettings/UserSettings) or at runtime (Assets/Resources).  \nIf your code reads/writes from a settings file, this is a good point in time to modernize this, if you haven't already. Make sure settings are accessible via a  SettingsProvider](https://docs.unity3d.com/ScriptReference/SettingsProvider.html?), and are either stored in \"ProjectSettings\", \"UserSettings\" or \"Assets/Resources\" (for settings that need to be available at runtime).  \n\n## Technical Details  \n\nThis is tested with Unity 2018.4, 2019.4, 2020.3 and Asset Store Tools 5.0.4.\n\nAll the functionality to use packages in .unitypackages is already provided by Unity. Just the tooling to create them has too many incorrect/outdated safety checks - so all we're doing here is bypassing those. It's still the same Unity APIs creating / exporting / importing packages.\n\n## Ideas for Future Development\n- Immutable Packages could be shipped in `.unitypackage` as well as `Packages/com.my.package.tgz`, but this needs a bit more work to create an additional archive and include that in the exported package.\n- ~~More safeguards around accidental inclusion of dependencies from other packages~~\n- Ability to show hints/warnigs for people to ask them to manually install dependencies from scoped registries. The Unity Terms of Service currently prohibit doing this automatically.\n\n## If you're Unity\n\nWe're happy to provide guidance on what we needed to change here. This took only a few hours to create, and ideally wouldn't be necessary - `AssetStoreTools.dll` and `.unitypackage` utilities in Unity could just work.\n\n## Guide to Packages\n\n\n**Option 1: Single-Project Workflow**\nA single project where you work on your asset.  \n\n```\nYour Test Project\n├── Assets\n└── Packages\n    ├── manifest.json\n    ├── manifest-lock.json\n    └── com.your.package \"Your package root folder\"\n        ├── package.json \"Specify package name, version, author, dependencies, samples, documentationUrl here\"\n        ├── Changelog.md \"This should follow SemVer conventions. See sample\"\n        ├── Readme.md    \"Some basic info to get started\"\n        ├── Runtime\n        │   ├── Your.Package.asmdef\n        │   └── \"your runtime code and assets\"\n        ├── Editor\n        │   │── Your.Package.Editor.asmdef \"This AsmDef must be set to Editor-only\"\n        │   └── \"your editor code and assets\"\n        └── Samples~ \"This folder is hidden, samples get specified in package.json\"\n            ├── Simple Sample\n            │   └── \"your sample code and files\"\n            └── Complex Sample\n                └── \"your sample code and files\"\n```\n\n**Option 2: Multi-Project Workflow (recommended)**   \nMany packages need to support multiple Unity versions. This has traditionally been pretty cumbersome to maintain, with multiple submodules in different projects, copy-pasting code over, or just hoping everything works.  \nOne of the biggest advantages of a package-based workflow is that cross-version development becomes incredibly easy, as the same package on disk can be referenced by multiple projects. Testing code is as simple as focussing the right Unity Editor instance.    \n\n```\nYour Content Development Folder \"often the git repository root\"\n├── Your Test Project on Unity 2019.4\n│   ├── Assets\n│   └── Packages\n│       ├── manifest.json \"contains the line: \" \"com.your.package\":\"file:../../com.your.package\"\n│       └── manifest-lock.json\n│\n├── Your Test Project on Unity 2020.3\n│   ├── Assets\n│   └── Packages\n│       ├── manifest.json \"contains the line: \" \"com.your.package\":\"file:../../com.your.package\"\n│       └── manifest-lock.json\n│\n├── Your Test Project on Unity 2021.3\n│   ├── Assets\n│   └── Packages\n│       ├── manifest.json \"contains the line: \" \"com.your.package\":\"file:../../com.your.package\"\n│       └── manifest-lock.json\n│\n└── com.your.package \"Your package root folder\"\n        ├── package.json \"Specify package name, version, author, dependencies, samples, documentationUrl here\"\n        ├── Changelog.md \"This should follow SemVer conventions. See sample\"\n        ├── Readme.md    \"Some basic info to get started\"\n        ├── Runtime\n        │   ├── Your.Package.asmdef\n        │   └── \"your runtime code and assets\"\n        ├── Editor\n        │   │── Your.Package.Editor.asmdef \"This AsmDef must be set to Editor-only\"\n        │   └── \"your editor code and assets\"\n        └── Samples~ \"This folder is hidden, samples get specified in package.json\"\n            ├── Simple Sample\n            │   └── \"your sample code and files\"\n            └── Complex Sample\n                └── \"your sample code and files\"\n   \n```\n\n**Complete Example: `package.json`**\n\n```json\n{\n   \"name\": \"com.needle.my-package\",\n   \"version\": \"2.3.0\",\n   \"displayName\": \"My Package\",\n   \"description\": \"Shows how to set up a Package\",\n   \"author\":\n   {\n      \"name\": \"Needle\",\n      \"email\": \"hi@needle.tools\",\n      \"url\": \"https://needle.tools\"\n   },\n   \"unity\": \"2019.4\",\n   \"type\": \"tool\",\n   \"documentationUrl\": \"https://github.com/needle-tools/upm-in-unitypackage#readme\",\n   \"samples\":\n   [\n      {\n         \"displayName\": \"Simple Sample\",\n         \"description\": \"A very simple example, enough to get started.\",\n         \"path\": \"Samples~/Simple Sample\"\n      },\n      {\n         \"displayName\": \"Complex Sample\",\n         \"description\": \"Shows everything this package can do.\",\n         \"path\": \"Samples~/Complex Sample\"\n      }\n   ]\n}\n```\n\n**Complete Example: `Changelog.md`**\n\n```md\n# Changelog\nAll notable changes to this package will be documented in this file.\nThe format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).\n\n## [2.0.0] - 2021-02-12\n- added: new horse\n- fixed: old horse sometimes lost teeth\n\n## [1.1.0] - 2021-01-08\n- added: horse controller and sample\n- fixed: sample didn't actually explain how everything works\n\n## [1.0.0] - 2021-01-05\n- initial release with one horse\n```\n\n**Complete Example: Single-Project Folder Structure with settings**\n\n```\nYour Test Project\n├── Assets\n│   └── Resources\n│       └── YourPackageRuntimeSettings.asset \"Your package should generate this if needed. Note, Users might move it somewhere else!\"\n├── Packages\n│   ├── manifest.json\n│   ├── manifest-lock.json\n│   └── com.your.package \"Your package root folder\"\n│       ├── package.json \"Specify package name, version, author, dependencies, samples, documentationUrl here\"\n│       ├── Changelog.md \"This should follow SemVer conventions. See sample\"\n│       ├── Readme.md    \"Some basic info to get started\"\n│       ├── Runtime\n│       │   ├── Your.Package.asmdef\n│       │   └── \"your runtime code and assets\"\n│       ├── Editor\n│       │   │── Your.Package.Editor.asmdef \"This AsmDef must be set to Editor-only\"\n│       │   └── \"your editor code and assets\"\n│       └── Samples~ \"This folder is hidden, samples get specified in package.json\"\n│           ├── Simple Sample\n│           │   └── \"your sample code and files\"\n│           └── Complex Sample\n│               └── \"your sample code and files\"\n├── ProjectSettings\n│   └── YourPackageProjectSettings.asset \"If your package has project-specific settings, put them here\"\n└── UserSettings\n    └── YourPackageUserSettings.asset \"If your package has user-specific settings, put them here\"\n```\n\n**Complete Example: Settings Provider**  \n```TODO // Move somewhere else```\n\n## Contact ✒️\n\u003cb\u003e[🌵 needle — tools for unity](https://needle.tools)\u003c/b\u003e • \n[@NeedleTools](https://twitter.com/NeedleTools) • \n[@marcel_wiessler](https://twitter.com/marcel_wiessler) • \n[@hybridherbst](https://twitter.com/hybridherbst) • \n[Needle Discord](https://discord.gg/CFZDp4b)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneedle-tools%2Fhybrid-packages","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneedle-tools%2Fhybrid-packages","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneedle-tools%2Fhybrid-packages/lists"}