{"id":13398019,"url":"https://github.com/schmich/instascan","last_synced_at":"2026-10-19T01:09:22.937Z","repository":{"id":39618272,"uuid":"61934962","full_name":"schmich/instascan","owner":"schmich","description":"HTML5 QR code scanner using your webcam","archived":false,"fork":false,"pushed_at":"2021-12-15T13:21:36.000Z","size":2114,"stargazers_count":3022,"open_issues_count":193,"forks_count":852,"subscribers_count":94,"default_branch":"master","last_synced_at":"2026-10-13T09:43:12.419Z","etag":null,"topics":["browser","camera","emscripten","html5","javascript","qr-code","qrcode","quick-response","video","webcam","zxing"],"latest_commit_sha":null,"homepage":"https://schmich.github.io/instascan/","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/schmich.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":"2016-06-25T08:52:12.000Z","updated_at":"2026-10-09T03:20:07.000Z","dependencies_parsed_at":"2022-08-09T15:06:56.667Z","dependency_job_id":null,"html_url":"https://github.com/schmich/instascan","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/schmich/instascan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/schmich","download_url":"https://codeload.github.com/schmich/instascan/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/schmich%2Finstascan/sbom","scorecard":{"id":804045,"data":{"date":"2025-08-11","repo":{"name":"github.com/schmich/instascan","commit":"b0f9519f2dd2a6661e67066d6ed678e621dd5ce2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"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":"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":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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":"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":"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":"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":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.0.0 not signed: https://api.github.com/repos/schmich/instascan/releases/5269552","Warn: release artifact 0.0.3 not signed: https://api.github.com/repos/schmich/instascan/releases/3678056","Warn: release artifact 1.0.0 does not have provenance: https://api.github.com/repos/schmich/instascan/releases/5269552","Warn: release artifact 0.0.3 does not have provenance: https://api.github.com/repos/schmich/instascan/releases/3678056"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"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":"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"}}]},"last_synced_at":"2025-08-23T11:17:50.488Z","repository_id":39618272,"created_at":"2025-08-23T11:17:50.488Z","updated_at":"2025-08-23T11:17:50.488Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38344170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-18T02:00:06.448Z","response_time":63,"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":["browser","camera","emscripten","html5","javascript","qr-code","qrcode","quick-response","video","webcam","zxing"],"created_at":"2024-07-30T18:02:02.093Z","updated_at":"2026-10-19T01:09:22.543Z","avatar_url":"https://github.com/schmich.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Libraries","Graphics and Media"],"sub_categories":["QR code","Image and Video","JavaScript"],"readme":"# ![Instascan](https://raw.githubusercontent.com/schmich/instascan/master/assets/qr.png) Instascan\nReal-time webcam-driven HTML5 QR code scanner. [Try the live demo](https://schmich.github.io/instascan/).\n\n## Installing\n\n*Note:* Chrome requires HTTPS when using the WebRTC API. Any pages using this library should be served over HTTPS.\n\n### NPM\n\n`npm install --save instascan`\n\n```javascript\nconst Instascan = require('instascan');\n```\n\n### Bower\n\nPending. [Drop a note](https://github.com/schmich/instascan/issues/31) if you need Bower support.\n\n### Minified\n\nCopy `instascan.min.js` from the [releases](https://github.com/schmich/instascan/releases) page and load with:\n\n```html\n\u003cscript type=\"text/javascript\" src=\"instascan.min.js\"\u003e\u003c/script\u003e\n```\n\n## Example\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eInstascan\u003c/title\u003e\n    \u003cscript type=\"text/javascript\" src=\"instascan.min.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cvideo id=\"preview\"\u003e\u003c/video\u003e\n    \u003cscript type=\"text/javascript\"\u003e\n      let scanner = new Instascan.Scanner({ video: document.getElementById('preview') });\n      scanner.addListener('scan', function (content) {\n        console.log(content);\n      });\n      Instascan.Camera.getCameras().then(function (cameras) {\n        if (cameras.length \u003e 0) {\n          scanner.start(cameras[0]);\n        } else {\n          console.error('No cameras found.');\n        }\n      }).catch(function (e) {\n        console.error(e);\n      });\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## API\n\n### let scanner = new Instascan.Scanner(opts)\n\nCreate a new scanner with options:\n\n```javascript\nlet opts = {\n  // Whether to scan continuously for QR codes. If false, use scanner.scan() to manually scan.\n  // If true, the scanner emits the \"scan\" event when a QR code is scanned. Default true.\n  continuous: true,\n  \n  // The HTML element to use for the camera's video preview. Must be a \u003cvideo\u003e element.\n  // When the camera is active, this element will have the \"active\" CSS class, otherwise,\n  // it will have the \"inactive\" class. By default, an invisible element will be created to\n  // host the video.\n  video: document.getElementById('preview'),\n  \n  // Whether to horizontally mirror the video preview. This is helpful when trying to\n  // scan a QR code with a user-facing camera. Default true.\n  mirror: true,\n  \n  // Whether to include the scanned image data as part of the scan result. See the \"scan\" event\n  // for image format details. Default false.\n  captureImage: false,\n  \n  // Only applies to continuous mode. Whether to actively scan when the tab is not active.\n  // When false, this reduces CPU usage when the tab is not active. Default true.\n  backgroundScan: true,\n  \n  // Only applies to continuous mode. The period, in milliseconds, before the same QR code\n  // will be recognized in succession. Default 5000 (5 seconds).\n  refractoryPeriod: 5000,\n  \n  // Only applies to continuous mode. The period, in rendered frames, between scans. A lower scan period\n  // increases CPU usage but makes scan response faster. Default 1 (i.e. analyze every frame).\n  scanPeriod: 1\n};\n```\n\n### scanner.start(camera)\n\n- Activate `camera` and start scanning using it as the source. Returns promise.\n- This must be called in order to use [`scanner.scan`](#let-result--scannerscan) or receive [`scan`](#scanneraddlistenerscan-callback) events.\n- `camera`: Instance of `Instascan.Camera` from [`Instascan.Camera.getCameras`](#instascancameragetcameras).\n- `.then(function () { ... })`: called when camera is active and scanning has started.\n- `.catch(function (err) { ... })`\n  - Called when an error occurs trying to initialize the camera for scanning.\n  - `err`: An `Instascan.MediaError` in the case of a known `getUserMedia` failure ([see error types](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Errors)).\n  \n### scanner.stop()\n\n- Stop scanning and deactivate the camera. Returns promise.\n- `.then(function () { ... })`: called when camera and scanning have stopped.\n\n### let result = scanner.scan()\n\n- Scan video immediately for a QR code.\n- QR codes recognized with this method are not emitted via the `scan` event.\n- If no QR code is detected, `result` is `null`.\n- `result.content`: Scanned content decoded from the QR code.\n- `result.image`: Undefined if [`scanner.captureImage`](#let-scanner--new-instascanscanneropts) is `false`, otherwise, see the [`scan`](#scanneraddlistenerscan-callback) event for format.\n\n### scanner.addListener('scan', callback)\n\n- Emitted when a QR code is scanned using the camera in continuous mode (see [`scanner.continuous`](#let-scanner--new-instascanscanneropts)).\n- `callback`: `function (content, image)`\n  - `content`: Scanned content decoded from the QR code.\n  - `image`: `null` if [`scanner.captureImage`](#let-scanner--new-instascanscanneropts) is `false`, otherwise, a base64-encoded [WebP](https://en.wikipedia.org/wiki/WebP)-compressed data URI of the camera frame used to decode the QR code.\n\n### scanner.addListener('active', callback)\n\n- Emitted when the scanner becomes active as the result of [`scanner.start`](#scannerstartcamera) or the tab gaining focus.\n- If `opts.video` element was specified, it will have the `active` CSS class.\n- `callback`: `function ()`\n\n### scanner.addListener('inactive', callback)\n\n- Emitted when the scanner becomes inactive as the result of [`scanner.stop`](#scannerstop) or the tab losing focus.\n- If `opts.video` element was specified, it will have the `inactive` CSS class.\n- `callback`: `function ()`\n\n### Instascan.Camera.getCameras()\n\n- Enumerate available video devices. Returns promise.\n- `.then(function (cameras) { ... })`\n  - Called when cameras are available.\n  - `cameras`: Array of `Instascan.Camera` instances available for use.\n- `.catch(function (err) { ... })`\n  - Called when an error occurs while getting cameras.\n  - `err`: An `Instascan.MediaError` in the case of a known `getUserMedia` failure ([see error types](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Errors)).\n\n### camera.id\n\n- Unique camera ID provided by the browser.\n- These IDs are stable and can be persisted across instances of your application (e.g. in localStorage).\n\n### camera.name\n\n- Camera name, including manufacturer and model\n- e.g. \"Microsoft LifeCam HD-3000\".\n\n## Compatibility\n\nInstascan works on non-iOS platforms in [any browser that supports the WebRTC/getUserMedia API](http://caniuse.com/#feat=stream), which currently includes Chome, Firefox, Opera, and Edge. IE and Safari are not supported.\n\nInstascan does not work on iOS since Apple does not yet support WebRTC in WebKit *and* forces other browser vendors (Chrome, Firefox, Opera) to use their implementation of WebKit. [Apple is actively working on WebRTC support in WebKit](https://bugs.webkit.org/show_bug.cgi?id=124288).\n\n## Performance\n\nMany factors affect how quickly and reliably Instascan can detect QR codes.\n\nIf you control creation of the QR code, consider the following:\n\n- A larger physical code is better. A 2\" square code is better than a 1\" square code.\n- Flat, smooth, matte surfaces are better than curved, rough, glossy surfaces.\n- Include a sufficient quiet zone, the white border surrounding QR code. The quiet zone should be at least four times the width of an individual element in your QR code.\n- A simpler code is better. You can use [this QR code generator](https://www.the-qrcode-generator.com/) to see how your input affects complexity.\n- For the same length, numeric content is simpler than ASCII content, which is simpler than Unicode content.\n- Shorter content is simpler. If you're encoding a URL, consider using a shortener such as [goo.gl](https://goo.gl/) or [bit.ly](https://bitly.com/).\n\nWhen scanning, consider the following:\n\n- QR code orientation doesn't matter.\n- Higher resolution video is better, but is more CPU intensive.\n- Direct, orthogonal scanning is better than scanning at an angle.\n- Blurry video greatly reduces scanner performance.\n- Auto-focus can cause lags in detection as the camera adjusts focus. Consider disabling it or using a fixed-focus camera with the subject positioned at the focal point.\n- Exposure adjustment on cameras can cause lags in detection. Consider disabling it or having a fixed white backdrop.\n\n## Example Setup\n\n- Purpose: To scan QR code stickers on paper cards and plastic bags.\n- Camera: [Microsoft LifeCam HD-3000](http://www.newegg.com/Product/Product.aspx?Item=9SIA4RE40S4991), 720p, fixed focus, around $30 USD.\n- Small support to ensure camera is focused on subject.\n- White paper backdrop to mitigate exposure adjustment.\n\n![Setup](https://raw.githubusercontent.com/schmich/instascan/master/assets/setup.jpg)\n\n## Credits\n\nPowered by the [Emscripten JavaScript build](https://github.com/kig/zxing-cpp-emscripten) of the [C++ port](https://github.com/glassechidna/zxing-cpp) of the [ZXing Java library](https://github.com/zxing/zxing).\n\n## License\n\nCopyright \u0026copy; 2016 Chris Schmich  \nMIT License. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschmich%2Finstascan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fschmich%2Finstascan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fschmich%2Finstascan/lists"}