Building Chrome Extension for Dynamic Web TWAIN

Dynamic Web TWAIN has been widely used for developing web browser based document scanning apps. Is it possible to embed Dynamic Web TWAIN APIs into a Chrome app or extension? In this post, I want to share what I went through while building a Chrome extension.

Chrome App

When opening the introduction page of Chrome app, you may have noticed the top information:

Important: Chrome will be removing support for Chrome Apps on Windows, Mac, and Linux. Chrome OS will continue to support Chrome Apps. Additionally, Chrome and the Web Store will continue to support extensions on all platforms. Read the announcement and learn more about migrating your app.

Dynamic Web TWAIN supports Windows, Linux, and macOS, but not ChromeOS. Although the Chrome app is deprecated, we can still test it in developer mode.

The `hello world’ Chrome app contains manifest.json, window.html, icon.png and background.js. You can add app information and permissions to the manifest file. The background script is used to launch the window page.

Type in `chrome://extensions’ in the address bar. Enable developer mode and then load the unpacked extension. The app logo appears on chrome://apps.

chrome app install

If you are using Visual Studio Code, you can install the dwt extension:

vscode extension

Then quickly insert the code snippet to window.html:

vscode code snippet

Reload the Chrome app to check what will happen:

chrome app error

According to Content Security Policy (CSP), the following code is not allowed:

<script type="text/javascript" src=""> </script>

So I have to install Dynamic Web TWAIN and copy Resources folder into the project. Change the script files:

<script type="text/javascript" src="Resources/dynamsoft.webtwain.initiate.js"> </script>
<script type="text/javascript" src="Resources/dynamsoft.webtwain.config.js"> </script>

Because the SDK uses eval() which violates CSP, I need to use sandboxing to isolate the content. Add `sandbox’ to manifest.json:

"sandbox": {
        "pages": ["window.html"]

Everything looks good now. However, when running the app, nothing returned. Open developer tools, I found the WebSocket connection failed. The web browser based document scanning technology relies on the WebSocket communication between a local service and the web client. Chrome app only supports XMLHttpRequest .

To tackle this issue, use webview tag as the alternative. The web view tag allows you to embed external web content.

Create webview.html which points to the Dynamic Web TWAIN online demo:

<!DOCTYPE html>
  <meta charset="utf-8">
  <webview src="" style="width:1280px; height:960px" autosize="on" minwidth="960" minheight="480"></webview>

Click a button to open the window:

function createNewWindow(optionsDictionary) {
  optionsDictionary = optionsDictionary || {};

  optionsDictionary.resizable = true;
  if (isFocusedSupported) optionsDictionary.focused = true;

  optionsDictionary.hidden = false;

  var innerBounds =;
  innerBounds.left =
      (innerBounds.left + newWindowOffset) % (screen.width - innerBounds.width); = ( + newWindowOffset) %
                    (screen.height - innerBounds.height);
  optionsDictionary.innerBounds = {};
  optionsDictionary.innerBounds.left = 50; = 50;
  optionsDictionary.innerBounds.width = screen.width - 100;
  optionsDictionary.innerBounds.height = screen.height - 100;
      'webview.html', optionsDictionary, function(win) {; });

$('#viewer').onclick = function(e) {

Web TWAIN scanning in Chrome app:

chrome app webview

Chrome Extension

Instead of background script, Chrome extension uses a browser action to pop up the HTML page.

chrome extension popup

Modify manifest:

    "manifest_version": 2,

    "name": "Dynamic Web TWAIN",
    "short_name": "dwt",
    "description": "Web browser based document scanning using Dynamic Web TWAIN.",
    "version": "1.0",

    "browser_action": {
        "default_icon": "dwt-16px.png",
        "default_popup": "popup.html"
    "icons": {
        "128": "dwt-128px.png"

To access the online demo of Dynamic Web TWAIN, write code as follows:

$ = function(selector) {return document.querySelector(selector);}

$('#viewer').onclick = function(e) {"");

Finally, open developer dashboard to publish the package to Chrome Web Store.

chrome web store

Source Code