BlinkGTK for Windows — Getting started

Each figure carries the date it was measured. The package sizes and the
number of bundled documents are measured on the ZIP we ship (measured 2026-09-24).
Note: We do not state when the ZIP was built, because that changes every time
it is rebuilt. For the exact byte count and hash of each ZIP, see
<package name>.verify.json (size / sha256) and SHA256SUMS (hashes only),
published alongside the packages. Checks on Windows 11 Pro build 26200 started on
2026-09-17; the most recent was 2026-09-24 (the extract-and-run check of the package).

BlinkGTK, running on Windows. It follows the same versioning as the Linux build
(Chromium version plus BlinkGTK patch level).

The public API is nearly identical to the Linux build of the same version
(1.2.1-build3).
There are two differences:

How this is counted: an entry point counts as public API when it is both declared
in the public header and exported from the shared library (.so / .dll). By
that definition both Linux and Windows have 101. The two differences below
are differences within those 101.

How this was measured (both 2026-09-21): for Windows, the intersection of
102 public header declarations and the 112 DLL exports whose names start with
blink = 101. A check verifies
that the header we counted is the same one shipped in the devel ZIP. For Linux,
the same counting method applied to the unpacked release tarballs: 101 header
declarations intersected with the 136 .so exports whose names start with
blink_ = 101. The name filter only leaves out internal
symbols that the header does not declare, so it does not change the intersection.
Note: What "the same counting method" means: only the conditional-compilation handling is
mirrored — on Windows we drop what is inside #ifndef _WIN32, on Linux what is
inside #ifdef _WIN32, so that declarations invisible to that platform's users
are not counted.

Missing on Windows blink_web_view_attach_to_external_surface (Wayland-specific)
Extra on Windows blink_gtk_init_with_sandbox()

One more entry point sits outside those 101.
blink_gtk_sandbox_init() is not exported from the DLL; it is linked into your
executable through the static library blinkgtk_sandbox.lib (shipped in the
devel ZIP). You cannot call it on Linux (see below).

Note: The comparisons with Linux on this page are against Linux 1.2.2-build6
(Chromium 153), the latest release when we compared (2026-09-21 to 22).

Linux 1.2.3-build1 (Chromium 154) was released on 2026-09-24; we have not
compared against 1.2.3.
Nor have we checked how the things fixed in 1.2.3
(for example, disabling JavaScript, images and localStorage now takes effect)
behave in this Windows build (1.2.1-build3).

Note: The four entry points added in Linux 1.2.2 are not in this Windows build
(they are not in Linux 1.2.1 either):
blink_web_view_new_with_profile(), blink_gtk_set_gpu_mode(),
blink_gtk_get_profile_path() and blink_gtk_get_profile_source().

How this is counted: 1.2.2-build6 has 106 public APIs against 101 in
1.2.1-build3 — five additions. blink_gtk_init_with_sandbox() is the only one
of those that Windows also has, so four are missing (measured 2026-09-21).

Note: blink_web_view_new_with_profile() was the feature highlighted for
Linux 1.2.2-build6
(a separate profile and cache per view).
It is not available in this Windows build.

About the two sandbox entry points (measured 2026-09-21; exports were checked with nm -D for the Linux .so and dumpbin /exports for the Windows DLL):

Linux 1.2.1 Linux 1.2.2-build6 This Windows build
Declared in the header no yes (Since: (not released yet)) yes
blink_gtk_init_with_sandbox() in the shared library no yes yes
blink_gtk_sandbox_init() available no no yes (through the static library blinkgtk_sandbox.lib, shipped in the devel ZIP)

Note: The "yes" in the Linux 1.2.2-build6 column for
blink_gtk_init_with_sandbox() comes from measuring the shared library.

blink_gtk_sandbox_init() cannot be called on Linux yet. The upstream header
says it "lives only in the static library blinkgtk_sandbox, which the current
packages do not include. Linking against it will fail."
(Issue #141, which that header text cites, is a question we filed in the
upstream repository.) The same sentence is still in the 1.2.3-build1 header (the
note on blink_gtk_sandbox_init() in blink_gtk.h; checked 2026-09-24). In the
1.2.3 header, blink_gtk_init_with_sandbox() is marked Since: 1.2.2 and
described as provided by the shared library.
The Windows package ships that static library, so it works here.


What you get

portable ZIP Extract and run. GTK4 is bundled, so there is nothing else to install
devel ZIP For embedding: public API headers, import libraries, and the GTK4 development files

There is no installer (MSI) yet — only the design has been decided.


Getting it running

1. Extract

Put the ZIP anywhere. Administrator rights are not required.

2. A warning may appear the first time

These packages are not code-signed. Microsoft Defender SmartScreen may warn
you when you download the ZIP with a browser and run it. Follow the prompts to
run it anyway.

Signing can be added later, so the first release ships unsigned.

Note: We do not have a screenshot of this yet.
On our development machine we do not fetch the package through a browser, so it
never carries the Mark of the Web. That machine cannot reproduce the warning.
We will add the screenshot, with the exact button labels, once we have run
download-to-launch on a clean Windows install.

3. Run it

Run bin\blinkgtk_browser.exe.
Without an argument it opens https://google.com/ (this needs an Internet
connection). Pass a URL to open that page instead.

cd blinkgtk-1.2.1-build3-windows-x64\bin
blinkgtk_browser.exe
blinkgtk_browser.exe https://example.com/

blinkgtk_browser is a minimal sample that shows only what is needed to embed
BlinkGTK. A console window also opens and shows the program's log.


Requirements

OS Windows 10 (64-bit) or later
CPU x64 (32-bit is not supported)
Disk space ZIP about 577 MiB + about 1,583 MiB extracted. You need both while extracting — about 2.1 GiB in practice (measured 2026-09-24)
GTK4 Bundled. Do not install it separately
Visual C++ runtime DLLs bundled (no need to run the Redistributable installer)

Note: MiB here means 1,048,576 bytes. The GitHub Releases page uses the same
unit and labels it "MB", so the ZIP shows as 577 MB there (checked
2026-09-23 by comparing the API byte counts of a release in another public
repository with its Releases page). Tools that count in 1,000,000-byte units show 605 MB.
The bundled documents use the same unit — all six that print
sizes (INSTALLATION-ja.md, INSTALLATION-en.md,
building-with-blinkgtk-ja.md, portable-app-guide-ja.md, faq-ja.md,
linux-windows-differences-ja.md) state that MB means MiB (checked
mechanically, 2026-09-21).

Do not install GTK4 separately. Windows has two incompatible GTK4 ABIs
(gvsbuild = MSVC ABI, MSYS2 = MinGW ABI). Code built against a different ABI
will not link against the bundled GTK4.
(This is the general rule. We have not actually tried mixing them.)

Note: We verified this on Windows 11 Pro (build 26200). We have not tested
Windows 10.

Note: software is the only render path. Setting BLINKGTK_GPU_MODE to egl
or swiftshader still renders through software.

The variable itself is read. egl changes the reported path name to "P3".
What does not change is the rendering.

The EGL render path itself (blink_web_view_egl.cc, blink_wayland_surface.cc)
is not part of the Windows build: how the receiving surface gets composited is
undesigned
, and a DirectComposition-based shape is under consideration.
The entry points (blink_gtk_ensure_egl_recipient() and friends) remain in
blinkgtk.dll to keep the ABI
, but return 0 on Windows.


Differences from the Linux build

Linux Windows
Install RPM / DEB / tarball ZIP (MSI later)
GTK4 from the OS packages bundled
Rendering software / EGL software only (EGL is not built)
blink_web_view_attach_to_external_surface available not available (Wayland-specific)
Japanese vertical layout (default) column-grid snap is off by default No column-grid snap difference (line breaking may differ because of the version and other differences; see (2) below)
Same, with --enable-blink-features=CJKVerticalColumnFragmentation column-grid snap takes effect not present — line positions should differ (see below)

Note: Vertical Japanese layout is not guaranteed to match between the two
platforms. There are two separate reasons.

(1) Column-grid snap is not in this Windows build — but it is off by
default on Linux too.

The flag CJKVerticalColumnFragmentation is one BlinkGTK adds (it is not
a Chromium upstream feature). It has status: "experimental" in
runtime_enabled_features.json5, that is off by default, and the
product code never turns it on.

How this was counted (measured 2026-09-22 on both the 152 and 153 trees):
calls to the forcing setter SetCJKVerticalColumnFragmentation... across
the whole tree
zero. Enabling it on the command line
(--enable-blink-features) likewise never appears in product code (zero under
third_party/blinkgtk/); within the BlinkGTK tree, only the verification harness does it. BlinkGTK's own published
documentation says the same: the API appears only when you pass
--enable-blink-features=CJKVerticalColumnFragmentation
.

So with default settings this point does not change the layout.
A difference appears only with
--enable-blink-features=CJKVerticalColumnFragmentation: the Linux build then
snaps at 4 conditional sites, while the three corresponding files in this
Windows build have zero occurrences.

(2) Both the Chromium version and the line-breaking change differ (Windows 152,
Linux 1.2.2 at the time we compared: 153).
For line breaking, 152 lacks the upstream fix that
landed in 153 (CL 8264049, behind the on-by-default flag LineBreakerHanKerningEnd).
BlinkGTK's own line-breaking change (upstream #131) is not in the Windows (152)
build either.
Upstream measured (on 153 only, within its test pages and two
fonts) that with the upstream flag on, the #131 change moves no values, and with
the flag off the change does take effect (without it, the #131 symptom appears
when a span is involved). 152 has no such flag, so on
Windows (152) the missing change may also contribute to the difference

(not measured on 152).

Note: The difference in line positions has not been measured by comparing
rendered output on the two platforms.
What we checked is that the three
corresponding files in this Windows build contain no snap condition at all;
how much the rendering differs on screen is not measured.

The JS API that reports layout metrics is present on Windows, but the
values it returns are not guaranteed to match Linux.
See §2-b (the
vertical layout metrics API) of the bundled docs\environment-variables-ja.md.


If you are embedding it

The devel ZIP carries the public API headers and the import libraries.

Building also needs Visual Studio Build Tools 2022 and the Windows SDK.
(Not having to install anything else, including GTK4, applies only to running it.)
Your own compile needs /MD /DCOMPONENT_BUILD.

The GTK4 development files are bundled because the public header blink_gtk.h
does #include <gtk/gtk.h>.

Three things to know when you embed it (the first is Windows-specific).

  1. Once you include the header, do not also write your own forward
    declarations for the public API
    (Windows-specific). The header declares
    them with __declspec(dllimport), so a declaration without it in the same
    translation unit makes clang warn (-Winconsistent-dllimport if the header
    comes first, -Wdll-attribute-on-redeclaration if yours does). With warnings
    treated as errors (-Werror / /WX) the build stops (we have not checked
    how MSVC's cl.exe reports it). Use the header alone.

  2. Free a returned string the caller owns with g_free()
    blink_handoff_meta_serialize() is the example. The implementation
    allocates with g_strdup_printf(), so the contract is g_free().

    The example printed in the API reference uses free(). We have asked
    about this in #130
    and it is not settled yet. This does not mean free()
    breaks in the current configuration — on Windows blinkgtk.dll and
    glib-2.0-0.dll are both /MD and there is a single ucrtbase.dll in the
    process (measured 2026-09-15). We align it for the contract.

  3. blink_gtk_sandbox_init() is not exported from the DLL. It is linked
    into your executable through the static library blinkgtk_sandbox.lib,
    which the devel ZIP carries. On Linux this entry point cannot be called
    yet
    — upstream's packages do not ship the static library (issue #141 in
    the upstream repository, filed by us).


Reading the version

1.2.1-build3 is the same version number as BlinkGTK itself, tied to the
Chromium version and the BlinkGTK patch level.
This one is Chromium
152.0.7977.64.

You can ask the binary in your hands:

> blinkgtk_browser.exe --version
BlinkGTK 1.2.1-build3 (Chromium 152.0.7977.64)

Trust what your copy prints, not the number on this page.


Where the rest of the documentation is

The package carries its documentation in docs\: 13 documents in Japanese and
4 in English (PDF versions of each as well). Start at docs\00-index-en.md.

docs\INSTALLATION-en.md Installing it
docs\troubleshooting-en.md When it does not work
docs\api-windows-notes-en.md Windows-specific notes on the API

The environment-variable reference (docs\environment-variables-ja.md) is
Japanese only — there is no English edition yet.


Revision history

Date Change
2026-09-19 First version
2026-09-21 Added evidence for the public API counts (measured on both platforms). Noted that blink_gtk_init_with_sandbox() disagrees with the note in the header upstream ships. Stated that sizes are MiB
2026-09-22 Corrected the description of Japanese vertical layout. With default settings (flag off) column-grid snap takes effect on neither platform, so a difference appears only when the flag is passed. The line-breaking difference comes from the Chromium version (Windows 152, Linux 153); the causal claim written earlier has been withdrawn (Note: that withdrawal rested on 153 measurements only and went too far; corrected in the 2026-09-23 row)
2026-09-22 Removed the upstream site source line numbers from the body (that block is regenerated on every release). Moved the evidence paths and the points we are asking upstream to confirm into the note for the upstream project
2026-09-22 Matched each claim to the measurement that actually supports it. Removed the ZIP build date from the body (it changes on every rebuild). Moved the repository paths and the points we are asking upstream to confirm out of the body and into the note for the upstream project
2026-09-22 Backed the claim that nothing turns it on with the right measurement: zero calls to the forcing setter on both trees. The figure cited before belonged to a different claim
2026-09-22 Moved the notes for the upstream project into a separate cover note. They had been in an HTML comment, but the upstream site is generated with pandoc and pandoc passes HTML comments through (a comment in upstream's own version-history-ja.md:17 appears verbatim on the published page). The draft now contains no HTML comments. Aligned the measurement dates
2026-09-23 Corrected the measurement date of the public API counts to 2026-09-21, the date of the recorded evidence. Aligned the disk-space row with the date at the top (2026-09-22). Reworded history entries that would have announced unreported items on the published page
2026-09-23 Important: The statement that GitHub Releases shows decimal MB (577 MiB = 605 MB) was backwards. The Releases page uses 1,048,576-byte units, so the ZIP shows as 577 MB there. Checked against API byte counts
2026-09-23 Quoted the compiler message exactly, and referred to the environment-variables section by its number
2026-09-23 Removed quotation marks from phrases that were not verbatim (our own summaries, a reading of the table), matching the Japanese page. Corrected the date of the simple_browser header measurement to 2026-09-21, the date on record
2026-09-23 Moved the most recent Windows 11 check to 2026-09-23. Removed quotation marks from a translated program message, a self-quotation and a term definition
2026-09-23 Stated that the export counts cover only names starting with blink / blink_. Corrected what happens with your own forward declarations (clang warns; the build stops only with -Werror / /WX)
2026-09-23 Removed the total export counts (the two sides were not counted the same way). Narrowed the forward-declaration note to a header and your own declaration in the same translation unit (your own declaration alone gives no warning; checked with clang, not with cl.exe)
2026-09-23 Corrected the line-breaking note: upstream measured only 153 (with the upstream flag both on and off; with it on the change moves no values); on 152, which has no such flag, the missing #131 change may also contribute. The exact ZIP size is in verify.json; SHA256SUMS has hashes only. Size measurement date moved to 2026-09-23. Removed the total export counts from the history
2026-09-23 Stated the range of the upstream measurement (153 only, its test pages and two fonts; the symptom appears when a span is involved). Limited "only the verification harness" to the BlinkGTK tree. Removed emphasis that was not in the quoted header text
2026-09-23 The differences-from-Linux table said "No difference" for default vertical layout, contradicting note (2) below; narrowed it to column-grid snap. Softened the note heading from "does not match" to "is not guaranteed to match" (no side-by-side rendering comparison was made)
2026-09-23 The previous history row named the wrong table (it is the differences-from-Linux table, not the requirements table). The opening now says "number of bundled documents" instead of "file counts" (the page gives no file count)
2026-09-24 Updated for the switch of the shipped executable from simple_browser to blinkgtk_browser (same rule as BlinkGTK itself: simple_browser is a development demo and is not shipped). Important: The Defender exclusions we gave as the reason we cannot reproduce SmartScreen were not actually in place (measured 2026-09-24; C:\chromium was added to the exclusions the same day). The reason is the missing Mark of the Web, so the exclusion wording has been removed
2026-09-24 Applied upstream's document checks (2026-09-24): stated that the Linux comparisons are against 1.2.2-build6 (Chromium 153), the latest when we compared, and that we have not compared against 1.2.3-build1 (Chromium 154, released 2026-09-24); new_with_profile is now described as the 1.2.2-build6 highlight; checked that the quoted upstream header sentence is unchanged in 1.2.3 and said so; replaced emoji with words (Note: / Important:); measurement dates updated to 2026-09-24