{"id":17747608,"url":"https://github.com/lucidd/scala-js-chrome","last_synced_at":"2025-09-02T15:34:31.655Z","repository":{"id":25560933,"uuid":"28994144","full_name":"lucidd/scala-js-chrome","owner":"lucidd","description":"ScalaJS bindings for Chrome Extention/App and ChromeOS APIs","archived":false,"fork":false,"pushed_at":"2022-07-04T01:56:44.000Z","size":345,"stargazers_count":78,"open_issues_count":14,"forks_count":33,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-07-26T07:22:19.567Z","etag":null,"topics":["chrome-api","chrome-apps","chrome-extension","sbt","scala","scalajs"],"latest_commit_sha":null,"homepage":null,"language":"Scala","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/lucidd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-09T01:06:06.000Z","updated_at":"2025-02-11T13:13:38.000Z","dependencies_parsed_at":"2022-08-23T08:50:39.101Z","dependency_job_id":null,"html_url":"https://github.com/lucidd/scala-js-chrome","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/lucidd/scala-js-chrome","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucidd%2Fscala-js-chrome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucidd%2Fscala-js-chrome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucidd%2Fscala-js-chrome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucidd%2Fscala-js-chrome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucidd","download_url":"https://codeload.github.com/lucidd/scala-js-chrome/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucidd%2Fscala-js-chrome/sbom","scorecard":{"id":602543,"data":{"date":"2025-08-11","repo":{"name":"github.com/lucidd/scala-js-chrome","commit":"603740b0290ed845cb34bbbf78e374aaac083781"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Code-Review","score":8,"reason":"Found 9/11 approved changesets -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-21T00:47:11.779Z","repository_id":25560933,"created_at":"2025-08-21T00:47:11.779Z","updated_at":"2025-08-21T00:47:11.779Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273306157,"owners_count":25082070,"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-09-02T02:00:09.530Z","response_time":77,"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":["chrome-api","chrome-apps","chrome-extension","sbt","scala","scalajs"],"created_at":"2024-10-26T09:05:56.194Z","updated_at":"2025-09-02T15:34:31.621Z","avatar_url":"https://github.com/lucidd.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chrome for Scala.js [![Build Status](https://travis-ci.org/lucidd/scala-js-chrome.svg?branch=master)](https://travis-ci.org/lucidd/scala-js-chrome) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lucidd/scala-js-chrome?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) [![Latest version](https://index.scala-lang.org/lucidd/scala-js-chrome/scala-js-chrome/latest.svg?color=orange)](https://index.scala-lang.org/lucidd/scala-js-chrome/scala-js-chrome) [![Javadocs](https://www.javadoc.io/badge/net.lullabyte/scala-js-chrome_sjs0.6_2.12.svg)](https://www.javadoc.io/doc/net.lullabyte/scala-js-chrome_sjs0.6_2.12)\n\nThe goal of this project is to provide an easy and typesafe way to create Chrome\napps and extensions in Scala using the [Scala.js](https://www.scala-js.org/) project.\n\n## Chrome API bindings\n\nThe bindings provide access to the Chrome app and extension APIs. There are two\nlevels for each API. One that provides the raw JavaScript bindings and a second\none which wraps the raw API in a more Scala idiomatic way.\n\nThe package structure is similar to the original JavaScript API.\n\n```javascript\n// original JavaScript\nchrome.system.cpu.getInfo(function(info){\n  if (chrome.runtime.lastError === undefined) {\n    console.log(info);\n  } else {\n    console.log(\"ohoh something went wrong!\");\n  }\n});\n```\n\n```scala\n// raw bindings\nchrome.system.cpu.bindings.CPU.getInfo((info: CPUInfo) =\u003e {\n    if (chrome.runtime.bindings.Runtime.lastError.isEmpty) {\n        println(info)\n    } else {\n        println(\"ohoh something went wrong!\")\n    }\n})\n\n// Scala idiomatic way using Future\nchrome.system.cpu.CPU.getInfo.onComplete {\n  case Success(info) =\u003e println(info)\n  case Failure(error) =\u003e println(\"ohoh something went wrong!\")\n}\n```\n\nThe Scala idiomatic binding provides the following general changes:\n\n- Futures instead of callbacks\n- Error handling using types like `Future` / `Try` instead of global error \nvariable.\n- Using `Option` for things that may or may not be defined.\n\n## SBT Plugin\n\nThe job of the SBT plugin is to help with common tasks for developing Chrome\napps/extensions. It also provides a way to configure your app/extension in your\nSBT file and automatically generate the manifest file.\n\n- `chromePackage` will create a ZIP file you can upload to the Chrome Web Store.\n- `chromeUnpackedOpt` (or `chromeUnpackedFast`) will build your projects with (or without) optimizations enabled. The\noutput will be in `target/chrome/unpacked-opt` (or `target/chrome/unpacked-fast`) and can be loaded by Chrome as an\nunpacked extension/app.\n\n## Getting Started\n\nAdd this to your `project/plugins.sbt`:\n\n```scala\naddSbtPlugin(\"net.lullabyte\" % \"sbt-chrome-plugin\" % \"0.5.0\")\n```\n\nAdd this to your project dependencies:\n\n```scala\n\"net.lullabyte\" %%% \"scala-js-chrome\" % \"0.5.0\"\n```\n\n### with [scalajs-bundler](https://scalacenter.github.io/scalajs-bundler/)\nto use the `\u003cproject-name\u003e-f{ast,ull}opt-bundle.js` generated by [scalajs-bundler](https://scalacenter.github.io/scalajs-bundler) add the following to your `build.sbt`:\n\n```scala\nfastOptJsLib := Attributed.blank((webpack in (Compile, fastOptJS)).value.head)\nfullOptJsLib := Attributed.blank((webpack in (Compile, fullOptJS)).value.head)\n```\n\n_NOTE:_ if code seems to be executing duplicate times unintentionally, try removing these lines from the project's `build.sbt`\n\n```scala\nscalaJSUseMainModuleInitializer := true\nscalaJSUseMainModuleInitializer in Test := false\n```\n\n### Creating a basic Window\n\n```scala\nimport chrome.app.runtime.bindings.LaunchData\nimport chrome.app.window.Window\nimport utils.ChromeApp\n\nimport scalajs.concurrent.JSExecutionContext.Implicits.queue\n\nobject ChromeAppExample extends ChromeApp {\n\n  override def onLaunched(launchData: LaunchData): Unit = {\n    println(\"hello world from scala!\")\n    Window.create(\"assets/html/App.html\").foreach { window =\u003e\n      /**\n         Access to the document of the newly created window.\n         From here you can change the HTML of the window with whatever\n         library you want to use.\n      */\n      window.contentWindow.document\n    }\n  }\n\n}\n```\n\nFor a more complete example see [chrome-system-monitor](https://github.com/lucidd/chrome-system-monitor)\nand [scala-js-chrome examples](https://github.com/lucidd/scala-js-chrome/tree/master/examples).\n\n### UI Libraries\n\nThere are already multiple libraries to manipulate HTML and build your UI\navailable for Scala.js:\n\n- [scala-js-dom](https://github.com/scala-js/scala-js-dom) For simple dom access\n- [scalatags](https://github.com/lihaoyi/scalatags) Scala DSL for creating HTML\n- [scalajs-react](https://github.com/japgolly/scalajs-react) Bindings for using react.js\n- [scalacss](https://github.com/japgolly/scalacss) Typesafe way to write CSS\n  with Scala\n- [Binding.scala](https://github.com/ThoughtWorksInc/Binding.scala) Reactive data-binding for Scala\n\n### Known Issues\n\nIn Chrome apps and extensions there are multiple places where you can run\nJavaScript. Normally you split your logic into different files and load them into\nwhatever context they need to run. Since Scala.js compiles your whole project\ninto one big file all contexts need to load this big file with all the logic\neven if they only need a small subset. This can cause your app you use more\nmemory then it need to. In some cases this can be worked around for example the\na background page can manipulate the DOM of an App window so you don't need any\nJavaScript at all in the window itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucidd%2Fscala-js-chrome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucidd%2Fscala-js-chrome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucidd%2Fscala-js-chrome/lists"}