{"id":17134760,"url":"https://github.com/kapouer/node-webkitgtk","last_synced_at":"2025-04-09T14:14:50.048Z","repository":{"id":20120268,"uuid":"23390135","full_name":"kapouer/node-webkitgtk","owner":"kapouer","description":"webkitgtk bindings for :rocket: Node.js","archived":false,"fork":false,"pushed_at":"2022-10-07T08:27:15.000Z","size":1244,"stargazers_count":189,"open_issues_count":26,"forks_count":13,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-02T12:11:16.395Z","etag":null,"topics":["browser","gtk","javascript","pdf","screenshot","webkit"],"latest_commit_sha":null,"homepage":"","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/kapouer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","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":"2014-08-27T13:13:48.000Z","updated_at":"2024-08-23T20:08:54.000Z","dependencies_parsed_at":"2023-01-11T20:43:31.682Z","dependency_job_id":null,"html_url":"https://github.com/kapouer/node-webkitgtk","commit_stats":null,"previous_names":[],"tags_count":186,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapouer%2Fnode-webkitgtk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapouer%2Fnode-webkitgtk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapouer%2Fnode-webkitgtk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kapouer%2Fnode-webkitgtk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kapouer","download_url":"https://codeload.github.com/kapouer/node-webkitgtk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054193,"owners_count":21039952,"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","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","gtk","javascript","pdf","screenshot","webkit"],"created_at":"2024-10-14T19:45:42.313Z","updated_at":"2025-04-09T14:14:50.022Z","avatar_url":"https://github.com/kapouer.png","language":"JavaScript","readme":"# node-webkitgtk\n\n:warning: deprecated - see [express-dom](https://github.com/kapouer/express-dom) version \u003e= 6 to prerender web pages using playwright.\n\nPilot webkitgtk from Node.js with a simple API.\n\nAlso offers a command-line REPL, able to display (or not) the\ncurrent window, output pdf or png, see `webkitgtk --help`,\nand several example calls in examples/repl.sh.\n\nFalls back to jsdom if the module cannot be compiled (with obvious\nlimitations like inability to render the DOM nor output png or pdf).\n\nTypically, [express-dom](https://github.com/kapouer/express-dom) can run\non webkitgtk's jsdom mode - developers can work on other platforms where\njsdom builds fine.\n\n*this module uses only system-installed, shared libraries*\nit doesn't embed static libraries, meaning it plugs very nicely into\nsystem-installed libraries.\n\n## Node.js compatibility\n\nNode.js LTS and Current.\n\n## usage\n\nThe API has two styles:\n\n- with callbacks, all methods return current instance\n- without callbacks, all methods return promise\n\nFor convenience, the returned promises have bound methods once, on, when.\n\nThese calls will output pdf/png version of fully loaded pages (see documentation\nbelow about idle event).\n\nPdf output from cli:\n\n```shell\nwebkitgtk --pdf test.pdf \\\n --paper 210x297 \\\n --margins 20,20,20,20 \\\n --unit mm \\\n http://google.fr\n```\n\nPng output from cli:\n\n```shell\nwebkitgtk --png test.png http://nasa.gov\n```\n\n```js\nvar WebKit = require('webkitgtk');\nvar fs = require('fs');\n\n// optional, if nothing is set, defaults to :0\nvar displayOpts = {\n  width: 1024,\n  height: 768,\n  display: \"99\"\n};\n\n\n// old-style creation\nvar view = new WebKit();\nview.init(displayOpts).then(function() {\n  view.load(uri, {\n    style: fs.readFileSync('css/png.css') // useful stylesheet for snapshots\n  })\n  view.when('load', function() {\n    return this.png('test.png');\n  });\n});\n\n// short-hand can init display and load\nWebKit.load(uri, {\n  display: displayOpts, // optional, defaults to :0\n  style: fs.readFileSync('css/png.css') // useful stylesheet for snapshots\n}).once('idle', function() {\n  this.png('test.png'); // this is always the created instance in listeners\n  // ...\n});\n```\n\nA facility for choosing/spawning a display using xvfb\n\n```js\n// this spawns xvfb instance\n// new-style creation\nWebKit(\"1024x768x16:99\", function(err, w) {\n  w.load(\"http://github.com\", function(err) {\n    w.png('test.png', function(err) {\n      // done\n    });\n  });\n});\n\n// this uses a pre-existing display\nWebKit(98, function(err, w) {\n  w.load(\"http://google.com\");\n});\n\n// use pre-existing display 0 by default\nWebkit(function(err, w) {\n  w.load(\"http://webkitgtk.org\", function(err) {\n    w.html(function(err, str) {\n      console.log(html);\n    });\n  });\n});\n\n```\n\nAsynchronous (life) event handlers\n\n```js\nWebKit\n.load(\"http://localhost/test\", {content: \"\u003chtml\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e\"})\n.when(\"ready\", function(cb) {\n  this.run(function(className, done) {\n    setTimeout(function() {\n      document.body.classList.add(className);\n      done();\n    }, 100);\n  }, 'testClass', cb);\n})\n.when(\"ready\", function(cb) {\n  setTimeout(cb, 100);\n})\n.when(\"idle\", function() {\n  // promise variant\n});\n```\n\nSee test/ for more examples.\n\n## use cases\n\nThis module is specifically designed to run 'headless'.\nPatches are welcome for UI uses, though.\n\n- snapshotting service (in combination with 'gm' module)\n\n- print to pdf service (in combination with 'gs' module)\n\n- static web page rendering\n\n- long-running web page as a service with websockets or webrtc\n  communications\n\n- gui widgets (since webkitgtk \u003e= 2.7.4, transparent windows are possible),\n  see [the github wiki of node-webkitgtk](https://github.com/kapouer/node-webkitgtk/wiki).\n\n## load(uri, opts, cb) options\n\n- [WebKitSettings](http://webkitgtk.org/reference/webkit2gtk/stable/WebKitSettings.html)\n  Some settings have different default values:\n  enable-plugins: FALSE\n  enable-html5-database: FALSE\n  enable-html5-local-storage: FALSE\n  enable-java: FALSE\n  enable-page-cache: FALSE\n  enable-offline-web-application-cache: FALSE\n  default-charset: \"utf-8\"\n  user-agent: backend-specific value\n\n- deprecated WebKitSettings aliases:\n  private: enable-private-browsing\n  images: auto-load-images\n  localAccess: allow-file-access-from-file-urls\n  ua: user-agent\n  charset: default-charset\n\n- cookies\n  string | [string], default none\n  note that as of webkitgtk 4.3.3 cookies are properly cleared and isolated between views.\n\n- width\n  number, 1024\n- height\n  number, 768\n  the viewport\n\n- allow\n  \"all\" or \"same-origin\" or \"none\" or a RegExp, default \"all\"\n  A short-hand filter that is run after all other filters.\n  Note that data:uri are discarded by \"none\" and allowed by \"same-origin\".\n\n- filters\n  An array of request filters that are run in browser, synchronously.\n  All filters are called one after another, and each filter can read-write the\n  following properties on `this`:\n   uri (string)\n   cancel (boolean)\n   ignore (boolean)\n  and has read-only access to\n   from (string, in case the uri was redirected from another uri)\n  In particular, a filter can revert the action of a previous filter.\n  The initial document loading request is not filtered.\n  A single filter is either a `function() {}`,\n  or an array `[function(arg0, ...) {}, arg0, ...]`, allowing passing\n  immutable stringyfiable arguments to the filter function.\n\n- filter\n  Convenient option to append one filter to the list in opts.filters.\n\n- navigation\n  boolean, default false\n  allow navigation within the webview (changing document.location).\n\n- dialogs\n  boolean, default false\n  allow display of dialogs.\n\n- content\n  string, default null\n  load this content with the given base uri.\n\n- script\n  buffer, string or {fn: function(..args) {}, args: [..]}, default null\n  insert script at the beginning of loaded document.\n  args length must match fn function arity.\n\n- scripts\n  same as script but an array of them, default []\n\n- style\n  string, default null\n  insert [user stylesheet](http://www.w3.org/TR/CSS21/cascade.html#cascading-order)\n\n- transparent\n  boolean, default false\n  webkitgtk \u003e= 2.7.4\n  let the background be transparent (or any color set by css on the document)\n\n- decorated\n  boolean, default true\n  show window decorations (title bar, scroll bars)\n\n- timeout\n  number, default 30000\n  timeout for load(), in milliseconds\n\n- stall\n  number, default 1000\n  requests not receiving data for `stall` milliseconds are not taken into\n  account for deciding `idle` events.\n\n- stallInterval\n  number, default 1000\n  wait that long before ignoring all setInterval tasks as idle condition.\n  Set to 0 to ignore all.\n\n- stallTimeout\n  number, default 100\n  wait that long before ignoring all setTimeout tasks with timeout \u003e 0 as\n  idle condition. Tasks with 0 timeout will not be ignored, though.\n  Set to 0 to ignore all.\n\n- stallFrame\n  number, default 1000\n  wait that long before ignoring requestAnimationFrames as idle condition.\n  Set to 0 to ignore all.\n\n- console\n  boolean, default false\n  Send `console` events (see below).\n  Default listener outputs everything and is disabled by registering a custom\n  listener.\n\n- runTimeout\n  number, default 10000\n  Async run() calls will timeout and call back after `runTimeout` ms.\n  Sync run() calls, or runev() calls, are not affected.\n  Can be disabled by setting this param to 0.\n\n## init(opts, cb) options\n\n`init(display)` can be called instead of passing an object.\n\n- display\n  number for port, or string, (WIDTHxHEIGHTxDEPTH):PORT, default env.DISPLAY\n  checks an X display or framebuffer is listening on that port\n  init(display)\n\n- width\n  number, 1024\n- height\n  number, 768\n  Framebuffer dimensions\n- depth\n  number, 32\n  Framebuffer pixel depth\n\n- offscreen\n  boolean, default true\n  By default, nothing is shown on display. Set to false to display a window.\n\n- resizing\n  boolean, default false\n  Set to true to allow window.moveTo/resizeTo (and moveBy/resizeBy) to be\n  handed over to the window manager (which might ignore the requests).\n  (New in version 4.8.0)\n\n- verbose\n  boolean, default false\n  log client errors and stalled requests, otherwise available as\n  DEBUG=webkitgtk:timeout,webkitgtk:error.\n\n- cacheDir\n  string, $user_cache_dir/node-webkitgtk\n  path to webkitgtk cache directory.\n  Changing cacheDir can fail silently if webkitgtk lib is already initialized.\n\n- cacheModel\n  string, defaults to browser.\n  none: disables cache completely\n  local: cache optimized for viewing local files\n  browser: the real deal\n\n- debug\n  boolean, default false\n  shows a real window with a web inspector.\n  As a commodity, *the inspector must be closed- to get the `idle` event fired.\n\n- cookiePolicy\n  string, \"always\", \"never\", any other string defaults to \"no third party\".\n\nIf width, height, depth options are given, an xvfb instance listening\ngiven display port will be spawned using `headless` module.\nWrapping the application with `xvfb-run` command line tool is a safe(r) alternative.\n\n## pdf() options\n\nIf you plan to author html pages for printing, i strongly suggest to set\nan html document width in pixels equal to the paper width at 144 dpi (example:\n1190px for iso_a4 portrait).\nAlso never forget that 1in = 2.54cm = 25.4mm = 72pt = 6pc.\nSee [Units](https://www.w3.org/Style/Examples/007/units.html)\n\n- orientation\n  landscape | portrait, default to portrait\n\n- paper (string)\n  typical values are iso_a3, iso_a4, iso_a5, iso_b5,\n  na_letter, na_executive, na_legal, see\n  [GTK paper size](https://developer.gnome.org/gtk3/stable/GtkPaperSize.html).\n\n- paper (object)\n  unit : string, mm|in|pt, default \"pt\"\n  width : number, default 0\n  height : number, default 0\n\n- margins (number)\n  sets all margins in \"pt\" units, default 0\n\n- margins (string)\n  sets all margins in given units, default 0 and \"pt\"\n\n- margins (object)\n  unit : string, mm|in|pt, default \"pt\"\n  left, top, right, bottom : number, default 0\n\n## events\n\nAll events are on the WebKit instance.\n\nThese are lifecycle events:\n\n- ready\n  same as document's DOMContentLoaded event\n\n- load\n  same as window's load event\n\n- idle\n  when all requests (xhr included), timeouts, intervals, animation requests,\n  are finished or timed out (see stall- options).\n\n- unload\n  same as window's unload event\n\nThese events happen once and in that order.\n\nA new busy event can happen after idle event: it tracks further activity\nafter idling state, caused by any of:\n\n- setTimeout is finished or cleared\n- setInterval is finished or cleared\n- xhr is finished or aborted\n- animationFrame is finished or cancelled\n- a websocket emits a message\n\nIt can be used to track updates done by XHR, or long timeouts executed after\npage load.\n\nRegistering a listener for an event that already happened immediately calls the\nnew listener.\n\nThese events can happen at any moment:\n\n- error\n  this is what is caught by window.onerror\n  listener(message, url, line, column)\n\n- request\n  listener(req) where req.uri, req.headers are read only.\n  The request has already been sent when that event is emitted.\n\n- response\n  listener(res)\n  res have read-only properties uri, mime, status, length, filename, headers.\n  res.data(function(err, buf)) fetches the response data.\n\n- data\n  listener(res), called as soon as the first chunk of data is received.\n  res have read-only properties uri, mime, status, length, filename, headers,\n  and clength - the length of the received chunk of data.\n\n- authenticate\n  listener(request) where request.host, request.port, request.realm are\n  read-only.\n  request.use(username, password) authenticates\n  request.ignore() ignores authentication\n  Both methods can be called later (asynchronously), but at least one of them\n  is supposed to be called if the signal is handled.\n\n- navigate\n  listener(url)\n  Called when document location changes (not when history state change).\n  Navigation is permitted or not using `navigation` option, not this event.\n\n- console (deprecated)\n  listener(level, ...) where level is 'log', 'error', 'warn' or 'info'.\n  Remaining arguments are the arguments of the corresponding calls to\n  console[level] inside the page.\n  Logging everything that comes out of web pages can be annoying, so this is\n  disabled by default.\n  This event is deprecated - use `console` load option to enable/disable\n  console output instead.\n\n- crash (since version 4.9.0)\n  When the underlying web view has crashed.\n  It's a good idea to destroy it and use a new one.\n\n## methods\n\n- new Webkit()\n  creates an unitialized instance upon which init() must be called.\n  WebKit is also an EventEmitter.\n\n- WebKit(opts?, cb)\n  Same as above.\n  If arguments are given, equals `new WebKit().init(opts, cb)`.\n\n- init(opts?, cb)\n  see parameters described above\n  *must be invoked before (pre)load*.\n  Callback receives (err, instance).\n\n- clearCache()\n  Clear cache of the current instance.\n  Busy on-disk resources won't be cleared, so it's safer to call on an unloaded view.\n  Other running instances sharing the same cache may not be immediately affected.\n\n- preload(uri, opts?, cb)\n  load uri into webview\n  initial scripts are not run, resources are not loaded.\n  These options are not effective: `cookies`, `script`, `allow`.\n  Callback receives (err, instance).\n\n- load(uri, opts?, cb)\n  load uri into webview\n  see parameters described above.\n  Callback receives (err, instance).\n\n- once(event, listener)\n  the standard synchronous EventEmitter interface\n\n- when(event, asyncListener*)\n  Allow queuing asynchronous jobs on an event and before next event.\n  The async listener can have a function length of zero, in which case\n  it is considered to be a thenable; and the method returns the promise.\n  If asyncListener is missing it returns the latest promise.\n  Using promises is the only way to catch errors from previous jobs.\n  Otherwise the callback-style API is assumed.\n\n- run(sync-script, param*, cb)\n  any synchronous script text or global function.\n  If it's a function, multiple parameters can be passed, as long as they are\n  serializable.\n\n- run(async-script, param*, cb)\n  async-script must be a function with callback as last argument,\n  whose arguments will be passed to cb, as long as they are stringifyable.\n\n- runev(async-script, param*, cb)\n  async-script must be a function, it receives an `emit` function as last\n  argument, which in turn acts as event emitter: each call emits the named event\n  on current instance, and can be listened using view.on(event, listener).\n  The listener receives additional arguments as long as they're stringifyable.\n  Can be used to listen recurring events.\n\n- png(writableStream or filename, cb)\n  takes a png snapshot of the whole document right now.\n  If invoked with a filename, save the stream to file.\n  Tip: use custom css to cut portions of the document.\n\n- html(cb)\n  get the whole document html, prepended with its doctype, right now.\n  Callback receives (err, str).\n\n- pdf(filepath, opts?, cb)\n  print page to file right now\n  see parameters described above.\n\n- reset(cb)\n  Stops loading if it was, unregister listeners, allows .load() to be run\n  sooner than when calling unload.\n\n- unload(cb)\n  Sets current view to an empty document and uri.\n  Emits 'unload' event.\n\n- destroy(cb)\n  does the reverse of init - frees webview and xvfb instance if any.\n  init() can be called again to recover a working instance.\n  destroy must be called after unload to avoid memory leaks.\n\n## properties\n\n- WebKit.navigator\n  static property, a copy of the currently installed engine.\n\n- uri\n  Read-only, get current uri of the web view.\n\n- readyState\n  Read-only: empty, \"opening\", \"loading\", \"interactive\", \"complete\"\n  Before the first call to .load(uri, cb) it is empty, and before cb is called it\n  is opening.\n\n## debugging\n\n`DEBUG=webkitgtk node myscript.js`\nto print all logs.\n\nIn a production environment, it could be useful to set the init option\nverbose = true\nor, equivalently, the environment variables\nDEBUG=webkitgtk:timeout,webkitgtk:error,webkitgtk:warn\n\nThis will keep the page running, output console to terminal, and open\na gtk window with inspector open:\n\n```js\nWebKit({debug: true, verbose: true}, function(err, w) {\n  w.load(url, {console: true});\n});\n```\n\nFor debugging of node-webkitgtk itself, please read ./DEBUG.\n\n## about plugins\n\nUpdate: webkit2gtk \u003e= 2.32 no longer loads those plugins\n\nIn webkit2gtk \u003e= 2.4.4, if there are plugins in `/usr/lib/mozilla/plugins`\nthey are initialized (but not necessarily enabled on the WebView),\nand that could impact first page load time greatly (seconds !) - especially if\nthere's a java plugin.\n\nWorkaround:\nuninstall the plugin, on my dev machine it was\n`/usr/lib/mozilla/plugins/libjavaplugin.so` installed by icedtea.\n\n## install\n\nLinux only.\n\nCompatible with webkitgtk (WebKit2) versions 2.8 and above.\n\nIt's usually a better idea to use latest stable webkit2gtk.\n\nThese libraries and their development files must be available in usual\nlocations.\n\n- webkit2gtk-3.0 (2.4.x), for node-webkitgtk 1.2.x\n- webkit2gtk-4.0 (\u003e= 2.8.x), for node-webkitgtk \u003e= 1.3.0\n- glib-2.0\n- gtk+-3.0\n- libsoup2.4\n\nAlso usual development tools are needed (pkg-config, gcc, and so on).\n\nOn debian/jessie, these packages will pull necessary dependencies:\n\n- nodejs\n- npm\n- libwebkit2gtk-3.0-dev (2.4.x), for node-webkitgtk 1.2.x\n- libwebkit2gtk-4.0-dev (\u003e= 2.8.x), for node-webkitgtk \u003e= 1.3.0\n\nOn fedora/21:\n\n- nodejs\n- npm\n- webkitgtk4-devel\n\nOn ubuntu/14:\ntry [the WebKit team ppa](https://launchpad.net/~webkit-team)\n\n## License\n\nMIT, see LICENSE file\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapouer%2Fnode-webkitgtk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkapouer%2Fnode-webkitgtk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkapouer%2Fnode-webkitgtk/lists"}