{"id":20526348,"url":"https://github.com/logicspark/berryjam","last_synced_at":"2025-07-28T00:09:06.039Z","repository":{"id":165448312,"uuid":"640796782","full_name":"logicspark/berryjam","owner":"logicspark","description":"Open Source Vue.js Component Analyzer - Save time communicating and effort in development to create better and more efficient code","archived":false,"fork":false,"pushed_at":"2023-11-20T02:52:27.000Z","size":1541,"stargazers_count":121,"open_issues_count":5,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-23T01:27:37.959Z","etag":null,"topics":["analyzer","component-analysis","components","hacktoberfest","javascript","nuxt3","reusable-components","scanner","typescript","vue-component-analyzer","vue-scanner","vue3","vuejs"],"latest_commit_sha":null,"homepage":"https://berryjam.dev/","language":"TypeScript","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/logicspark.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-15T06:38:07.000Z","updated_at":"2025-04-16T04:23:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"f0fba81e-a026-4bc4-962c-40faa21818da","html_url":"https://github.com/logicspark/berryjam","commit_stats":null,"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/logicspark/berryjam","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logicspark%2Fberryjam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logicspark%2Fberryjam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logicspark%2Fberryjam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logicspark%2Fberryjam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/logicspark","download_url":"https://codeload.github.com/logicspark/berryjam/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/logicspark%2Fberryjam/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267110192,"owners_count":24037636,"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-07-26T02:00:08.937Z","response_time":62,"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":["analyzer","component-analysis","components","hacktoberfest","javascript","nuxt3","reusable-components","scanner","typescript","vue-component-analyzer","vue-scanner","vue3","vuejs"],"created_at":"2024-11-15T23:13:50.025Z","updated_at":"2025-07-28T00:09:06.009Z","avatar_url":"https://github.com/logicspark.png","language":"TypeScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://www.berryjam.dev/\" target=\"_blank\"\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./assets/img/berryjam_logo_dark.png\" width=\"500\"\u003e\n      \u003cimg alt=\"Berryjam\" src=\"./assets/img/berryjam_logo_light.png\" width=\"500\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003ch1 align=\"center\"\u003eUI Components Analyzer for Vue 3 \u0026 Nuxt\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  Scan your Vue.js codebase for component visibility and actionable insights.\n\u003c/div\u003e  \n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \n  [Issues](../../issues) - [Join our Discord][discord] - [License](#page_facing_up-license) - [Berryjam Cloud][berryjam]\n  \n  Available for: Vue.js (3.X), Nuxt (3.X)\n\n  [![NPM](https://img.shields.io/npm/v/berryjam)](https://www.npmjs.com/package/berryjam)\n  [![License](https://img.shields.io/badge/license-MIT-blue)](/LICENSE.md)\n  [![Discord](https://img.shields.io/badge/chat-on_discord-826deb)][discord]\n  [![Twitter](https://img.shields.io/twitter/follow/berryjamdev?label=Berryjamdev\u0026style=social)][twitter] \n\u003c/div\u003e\n\n\n# :book: Table of Contents\n1. [Why Berryjam](#star-why-berryjam)\n2. [Features](#sparkles-features)\n3. [Limitations](#see_no_evil-limitations)\n4. [Getting Started](#rocket-getting-started)\n5. [Development](#construction-development)\n6. [Contributing](#muscle-contributing)\n7. [Need Help?](#raising_hand-need-help)\n8. [License](#page_facing_up-license)\n9. [Acknowledgement](#acknowledgement)\n\n# :star: Why Berryjam\n\n\u003c!-- TODO: Video Demo of Running on Terminal --\u003e\n\nBerryjam provides a simple way to identify your component usage, props and their relationships. Based on the output from your scan, you can create your own dashboard and run analysis across your project components to improve communications across your development team.\n\n# :sparkles: Features\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cp\u003e1. Scan your project for components\u003c/p\u003e\u003cimg src=\"./assets/img/feature-scan-project.jpg\" /\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cp\u003e2. Analyze components and their relationships\u003c/p\u003e\u003cimg src=\"./assets/img/feature-analyze-components.jpg\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cp\u003e3. Scan Git log for author and datetime\u003c/p\u003e\u003cimg src=\"./assets/img/feature-scan-gitlog.jpg\" /\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003cp\u003e4. Automatically detect props for each component\u003c/p\u003e\u003cimg src=\"./assets/img/feature-detect-props.jpg\" /\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n# :see_no_evil: Limitations\n\n- Berryjam is not compatible with Vue 2 or lower versions. \n\n- Berryjam has been fully tested to work with node version from `16.0` to `18.17.1 (LTS)`. Versions above `18.17.1 (LTS)` should work as well but have not been fully tested.\n\n# :rocket: Getting Started\n\n## Install Berryjam\n\nThere are a few ways you can install Berryjam, namely npm, pnpm and yarn. If you install via npm, here is a single cmd to install this library\n\n```sh\n  npm install berryjam\n```\n\n#### Other options\n\n- pnpm\n\n```sh\n  pnpm add berryjam\n```\n\n- yarn\n\n```sh\n  yarn add berryjam\n```\n\n## Usage\n\nTo start scanning your project, you will first need to import `VueScanner` class and create its instance.\n\n```typescript\nimport { homedir } from 'os';\nimport VueScanner from \"berryjam\"\nimport type { VueScannerOption, ComponentProfile } from \"berryjam\"\n...\nconst pathToScan = '../your-vue-project-path';\nconst option: VueScannerOption = {\n  // this folder will be used to store the exact versions of babel \u0026 vue compiler\n  appDir: `${homedir()}/.vueScanner`,\n  // ... any other options\n}\n// Create a new VueScanner instance with the required parameters\nconst vueScanner = new VueScanner(pathToScan, option);\n...\n// To start scanning without async/await\nvueScanner.scan().then(result =\u003e {\n  // the result will be an array of ComponentProfile\n  // log to see the result\n  console.log(result);\n})\n\n// or, You can use async/await\nasync function whatEverFunction() {\n  const result = await vueScanner.scan();\n}\n\n```\n_Note: For a **Nuxt** project, please ensure that you have a `.nuxt` folder before scanning._\n\n\u003cbr/\u003e\n\nThe `VueScanner` function takes two parameters as follow: \n- The first parameter is the path of the project to be scanned.\n- The second is an option object that utilizes the `VueScannerOption` interface.\n\nHere is the detailed description of each available option within the `VueScannerOption` interface:\n\n### VueScannerOption Interface\n\n| Property   | Type                     | Description                                                         |\n|------------|--------------------------|---------------------------------------------------------------------|\n| `appDir`   | `string`                 | The path of the project directory to be scanned.                    |\n| `output`   | `OutputFormat` (optional)| The desired output format of the scanned result. (JSON by default)  |\n| `ignore`   | `string[]` (optional)    | An array of file names or directory names to exclude from scanning. |\n| `verbose`  | `boolean` (optional)     | Enable verbose mode for more detailed scanning information.         |\n| `debug`    | `boolean` (optional)     | Operate the scanner in debug mode, providing debugging information. |\n\n### OutputFormat Type\n\nThe `OutputFormat` type represents available output formats.\n\n| Type       | Description                                                                                         |\n|------------|-----------------------------------------------------------------------------------------------------|\n| `\"json\"`   | Output the scanned result in JSON format and saved as 'component-profiles.json' within the 'appDir'.|\n| `\"stdout\"` | Display the scanned result directly in the console (stdout).                                        |\n\nThese options and types offer flexibility and customization when using the `VueScanner` function to analyze Vue.js projects.\n\nFor more details on `VueScanner` class, please check out [below](#VueScanner-Overview).\n\n### Output\n\nBy calling the `scan` method, it will scan for Vue components and return `ComponentProfile[]`. Here is an example of how it may look. For demonstration purposes, we have scanned an open-source project called [Koel](https://github.com/koel/koel).\n\n\u003cdetails open\u003e\n  \u003csummary\u003eSample Result\u003c/summary\u003e\n\n```json\n[\n  {\n    \"name\": \"PlaybackControls\",\n    \"type\": \"internal\",\n    \"total\": 1,\n    \"source\": {\n      \"path\": \"/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue\",\n      \"property\": {\n        \"dataLastModified\": \"Sun Feb 04 2018\",\n        \"lastModified\": \"Sun Feb 04 2018\",\n        \"created\": \"2018-02-02T21:12:19.000Z\",\n        \"createdBy\": \"Phan An\",\n        \"updatedBy\": \"Phan An\"\n      }\n    },\n    \"usageLocations\": [\n      {\n        \"name\": \"PlaybackControls\",\n        \"source\": \"/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue\",\n        \"destination\": \"/resources/assets/js/components/layout/app-footer/index.vue\",\n        \"rows\": [\n          9\n        ],\n        \"fileInfo\": {\n          \"path\": \"/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue\",\n          \"property\": {\n            \"dataLastModified\": \"Sun Feb 04 2018\",\n            \"lastModified\": \"Sun Feb 04 2018\",\n            \"created\": \"2018-02-02T21:12:19.000Z\",\n            \"createdBy\": \"Phan An\",\n            \"updatedBy\": \"Phan An\"\n          }\n        }\n      }\n    ],\n    \"children\": {\n      \"total\": 4,\n      \"tags\": [\n        \"LikeButton\",\n        \"icon\",\n        \"PlayButton\",\n        \"RepeatModeSwitch\"\n      ],\n      \"source\": \"/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue\"\n    }\n  },\n  {\n    \"name\": \"PlayButton\",\n    \"type\": \"internal\",\n    \"total\": 1,\n    \"source\": {\n      \"path\": \"/resources/assets/js/components/ui/FooterPlayButton.vue\",\n      \"property\": {\n        \"dataLastModified\": \"Sun Feb 04 2018\",\n        \"lastModified\": \"Sun Feb 04 2018\",\n        \"created\": \"2018-02-02T21:12:19.000Z\",\n        \"createdBy\": \"Phan An\",\n        \"updatedBy\": \"Phan An\"\n      }\n    },\n    \"usageLocations\": [\n      {\n        \"name\": \"PlayButton\",\n        \"source\": \"/resources/assets/js/components/ui/FooterPlayButton.vue\",\n        \"destination\": \"/resources/assets/js/components/layout/app-footer/FooterPlaybackControls.vue\",\n        \"rows\": [\n          11\n        ],\n        \"fileInfo\": {\n          \"path\": \"/resources/assets/js/components/ui/FooterPlayButton.vue\",\n          \"property\": {\n            \"dataLastModified\": \"Sun Feb 04 2018\",\n            \"lastModified\": \"Sun Feb 04 2018\",\n            \"created\": \"2018-02-02T21:12:19.000Z\",\n            \"createdBy\": \"Phan An\",\n            \"updatedBy\": \"Phan An\"\n          }\n        }\n      }\n    ],\n    \"children\": {\n      \"total\": 1,\n      \"tags\": [\n        \"icon\"\n      ],\n      \"source\": \"/resources/assets/js/components/ui/FooterPlayButton.vue\"\n    }\n  },\n]\n```\n\n\u003c/details\u003e\n\n# :construction: Development\n\nThe library uses `Nodejs`, `TypeScript` and `Jest` for development. Since this is a tool for detecting Vue components, you may find the rules on how Vue components in the [built-in-rules](/documentation/built-in-rules) folder.\n\n## How It Works\n\nBerryjam contains 2 classes, namely:\n\n1. `VueScanner` - Use to scan a project for component profiles. It will extract relevant relative values such as source, file path, component name from package.json files and their respective supported files to transform or normalize raw component data which will be mapped to each component profile.\n\n2. `GitService` - If the project has .git folder, it will look for git related information such as author and datetime and map to each component profile.\n\n### VueScanner Overview\n\nWithin the `VueScanner` class, you may call on `scan()` method to start scanning. The method encompasses 5 main steps. There are as follow:\n\n![Five main steps in VueScanner class](/assets/img/vuescanner-overview.png)\n\n| Step                                        | Description                                                                                                                                                                                                     |\n|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n|1. `Group by Related Package.Json`           | Since there are multiple package.json files and supported files (`.vue`, `.js`, `.jsx`, `.ts`, `.tsx` and all files from the `.nuxt` folder (if any)), the system will group and determine the source of origin |\n|2.  `Select Analyzer Lib`                    | To choose the right library that matches the Vue version of your project                                                                                                                                        |\n|3.  `Prepare Alias Paths`                    | To gather all aliases from TS, JS and Vite config files to use for replacement in the 'import' statements                                                                                                       |\n|4.  `Analyze Component Files`                | For each file extension, the system will gather component info, including props                                                                                                                                 |\n|5. `Optimize Analyzed Results`               | Based on the component info, improvements are made by removing duplicates and formatting the component profile in a more structured way                                                                         |\n\n### GitService Overview\n\nBelow are the main methods in the `GitService` class:\n\n| Method       | Description                                                                          |\n| ------------ | ----------------------------------------------------------------------------------   |\n| `gitScanner` | Initiate git log shell commands to scan which will be used by `gitMapping`.          |\n| `gitMapping` | Using the result from `gitScanner` to compare component name and git log filename. If both match, the git information will update into the respective component profile. |\n\n### Dependencies\n\nThird-Party plugins are loaded automatically from Berryjam’s package.json\n\n- Code Parsers\n  - [Babel](https://babeljs.io/)\n  - [Vue](https://www.npmjs.com/package/vue?activeTab=dependencies)\n- Node Modules\n  - path\n  -  fs\n- Others\n  - [glob](https://www.npmjs.com/package/glob)\n  - [lodash](https://www.npmjs.com/package/lodash)\n  - [tsconfig-paths](https://www.npmjs.com/package/tsconfig-paths)\n\nFor more information, please refer to the [documentation](/documentation) folder.\n\n# :muscle: Contributing\n\nWe are thankful and appreciative for all types of contributions. Whether you are helping us report or fix bugs, proposing new features, improving our documentation or spreading the word - we would love to have you as a part of the Berryjam community. Please refer to our [Contributing Guide](/CONTRIBUTING.md) and [Code of Conduct](/CODE_OF_CONDUCT.md).\n\nIf you wish to start contributing right away, navigate to the GitHub [Issues](../../issues) tab and start looking through interesting issues. You may start off by working on issues labeled under `documentation` and `good first issue`.\n\nIf you run into an error or an issue while using Berryjam, you have an idea on how to better Berryjam or perhaps you are looking through the documentation and thinking that it could be improved... please don’t hesitate to submit an issue :sunglasses:\n\nIf you are a Vue.js developer who is not familiar with Node.js., you can submit an issue labeled `code example` on how you create Vue components. Check out our [built-in-rules](/documentation/built-in-rules) for more details.\n\n# :raising_hand: Need Help?\n\nWe are more than happy to help you. If you have any questions, run into any errors or face any problems, please feel free to ask for help in [Berryjam Discord][discord]. Anything related to Berryjam is on the table!\n\n# :page_facing_up: License\n\nBerryjam is distributed under MIT License. Please refer to our [LICENSE.md](/LICENSE.md) file for more details.\n\n# Acknowledgement\n\n- [Babel](https://babeljs.io/)\n- [Glob](https://www.npmjs.com/package/glob)\n- [Img Shields](https://shields.io)\n- [lodash](https://github.com/lodash/lodash)\n- [Node.js](https://nodejs.org/en)\n- [Tsconfig-Paths](https://github.com/dividab/tsconfig-paths)\n- [Vue.js](https://vuejs.org/)\n\n[discord]: https://discord.gg/8SgTS4QdCd\n[twitter]: https://twitter.com/Berryjamdev\n[berryjam]: https://www.berryjam.dev\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogicspark%2Fberryjam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flogicspark%2Fberryjam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flogicspark%2Fberryjam/lists"}