Chromic is a small Windows x64 version.dll for making Chrome portable.
It keeps only portable-profile support, two tab actions, configurable launch
commands, and optional browser-policy filtering.
Chromic is an independent, unofficial project. It is not affiliated with, endorsed by, sponsored by, or maintained by Google LLC or the Google Chrome team. Chrome and Google Chrome are trademarks of Google LLC.
- a portable user-data directory and cache directory;
- portable machine identity and encryption hooks for profile data created while Chromic is active;
- keeping the final tab open;
- closing a tab by double-clicking it;
- optional browser-policy filtering;
- additional Chromium command-line arguments;
- optional commands on browser startup and exit.
The default chromic.ini is intentionally limited to these settings:
[general]
ignore_policies=0
launch_on_exit=
launch_on_startup=
command_line=
data_dir=%app%\..\User Data
cache_dir=
[tabs]
keep_last_tab=1
double_click_close=1Open PowerShell in the repository root and run:
.\build.ps1That one command:
- creates
.local\chromic.keyif it does not exist; - reuses the same key on every later build;
- downloads the pinned portable LLVM-MinGW toolchain when needed;
- verifies the toolchain archive SHA-256;
- builds
out\version.dlland copiesout\chromic.ini.
The .local, .tools, build, and out directories are ignored by Git.
Back up .local\chromic.key somewhere safe. Losing it can make encrypted data
in an existing portable profile unreadable after rebuilding the DLL. Do not
publish the key.
An existing key is never overwritten. Running either command again simply uses it:
.\build.ps1
.\generate-key.ps1To use another key file, pass its path explicitly:
.\build.ps1 -PortableKeyFile .\.local\another.keyThe same path can be provided through CHROMIC_PORTABLE_KEY_FILE.
The build uses LLVM-MinGW 20260922 for Windows x64. The automatic download is llvm-mingw-20260922-ucrt-x86_64.zip. The archive is approximately 191 MB and occupies approximately 715 MB after extraction. Visual Studio and the Windows SDK are not required.
The expected archive SHA-256 is:
E3AD77D117A4BEA19A7A3B333341824D79A5A371004A10E25B8504E7B3047666
$toolchainSha256 in build.ps1 is this public archive checksum. It is not a
profile encryption key. Verify a manually downloaded archive with:
Get-FileHash .\llvm-mingw-20260922-ucrt-x86_64.zip -Algorithm SHA256To use an already extracted toolchain:
.\build.ps1 -ToolchainDir C:\Tools\llvm-mingw-20260922-ucrt-x86_64The production build uses size optimization, link-time optimization, dead-code elimination, and symbol stripping. The resulting self-contained DLL is approximately 258 KB and does not require separate LLVM C++ runtime DLLs.
Place version.dll and chromic.ini in the same directory as chrome.exe.
Start that chrome.exe normally. Chromic adds the configured portable
arguments and restarts the same executable once.
%app% is a Chromic placeholder. Chromic
obtains the full path of the loaded version.dll with GetModuleFileNameW,
removes the filename, and substitutes that directory for every %app% value.
Because version.dll, chromic.ini, and chrome.exe must be together, this is
also the application directory.
For this layout:
C:\PortableChrome\App\chrome.exe
C:\PortableChrome\App\version.dll
C:\PortableChrome\App\chromic.ini
the defaults resolve as follows:
%app%\..\User Data -> C:\PortableChrome\User Data
Setting data_dir=none or cache_dir=none disables the corresponding
automatically added argument. Normal Windows environment variables are also
expanded in configured paths and commands.
Missing or empty cache_dir also leaves Chrome's cache location unchanged.
Relative paths are resolved against the directory containing the DLL, never
the shortcut's working directory. The %app% placeholder cannot be overridden
by a Windows environment variable of the same name.
launch_on_startup and launch_on_exit execute their values through
cmd.exe. Separate multiple commands with ;. Leave the values empty if this
behavior is not needed.
Move the application directory and the entire User Data directory together,
including Local State. The destination must use a DLL built with the same
portable key. If two Chrome installations use this data, configure both to use
the same user-data root. Do not connect just a profile subdirectory to a
different user-data root. Prefer the same direct path for both launches.
On the removable installation, data_dir=%app%\..\User Data follows the
application when its drive letter changes. On an installed Chrome, configure
data_dir to point to that same removable directory. The removable installation
does not look up or depend on the installed browser's profiles.
Use a non-default user-data root on every computer. Chromium's App-Bound provider does not create new App-Bound keys when Chrome is using a non-default user-data directory. This does not convert previously App-Bound data. See the Chromium support check and key provider.
The DLL now cancels startup if it cannot install a required portability hook
or relaunch with the configured arguments. It does not edit Local State,
delete keys, migrate cookies, or repair extension registrations.
Create a new profile while Chromic is active whenever possible. Passwords, cookies, or tokens previously protected by ordinary Chrome with machine-bound Windows DPAPI may not become portable retroactively. Extensions, bookmarks, settings, and data written through Chromic are intended to survive moving the profile, but compatibility with future browser versions cannot be guaranteed.
To authenticate the portable master key without changing the profile, use PowerShell 7.4 or later:
.\check-profile.ps1 -UserDataDirectory '<path to the complete User Data directory>'Pass -PortableKeyFile if the DLL was built with a different key file. The
check rejects ordinary Windows-bound master keys and keys from another build.
It reports an existing App-Bound key separately; success authenticates only
the portable master key, not every database entry or Google session. No
plaintext keys or account data are printed.
Close Chrome completely before copying or unplugging the profile. Use matching Chrome versions when alternating installations. Google may require a new login even when local decryption works. Device-bound credentials such as Windows Hello are outside this DLL's portability support.
Run tests\run.ps1 with the existing LLVM-MinGW toolchain. It compiles a test
executable using a public test-only key and does not build or install the
production DLL. Tests exercise real API detours, failure reporting, AES-GCM
authentication without host DPAPI, and path/cache configuration. A browser
test on a second Windows account/computer is still required before describing
a particular Chrome release and profile as verified portable.
The contents of this directory must be the root of the published repository.
In particular, .github and build.ps1 must be directly in the repository
root.
Before the first automated release, create this repository secret:
Settings -> Secrets and variables -> Actions -> New repository secret
Name: CHROMIC_RELEASE_KEY
Generate a release key inside the ignored local directory:
.\generate-key.ps1 -OutputPath .\.local\release.keyCopy the 64 hexadecimal characters from .local\release.key into the secret.
Keep a secure backup and never commit the file. The workflow reads the secret,
builds the Windows x64 DLL, records SHA-256 checksums, creates a provenance
attestation, and publishes version.dll, chromic.ini, and
SHA256SUMS.txt.
All releases from one repository must keep the same CHROMIC_RELEASE_KEY.
Changing it prevents a new DLL from decrypting profile data written by older
release DLLs. Every user of that repository's release binaries therefore uses
the same key embedded in those DLLs. The key can be extracted from a DLL and
must not be treated as protection from somebody who already has the DLL and
profile.
On each push to main, commits after the latest valid vX.Y.Z or X.Y.Z tag
are evaluated as follows:
- if no valid version tag exists, the first release is always
v0.1.0; - a missing or malformed previous version also falls back to
v0.1.0; BREAKING CHANGE:,BREAKING CHANGES:, or a header such asfeat!:creates a major release;featcreates a minor release;fixandperfcreate a patch release;refactor,test,build,ci,style,docs,revert,chore, andwipdo not create a release by themselves;- unknown and non-conventional commit types do not create a release;
- the highest release level in the evaluated range wins;
- a breaking change before 1.0.0 creates 1.0.0;
- after the first release, no matching release commit means no new release;
- manual workflow runs use the same rules.
| Latest tag | Commits since tag | Result |
|---|---|---|
| none | any commits | v0.1.0 |
| malformed tags only | any commits | v0.1.0 |
v0.1.0 |
fix: preserve extensions |
v0.1.1 |
v0.4.2 |
feat!: change profile format |
v1.0.0 |
v1.3.0 |
perf: reduce tab lookup cost |
v1.3.1 |
v1.3.1 |
docs: update instructions |
no release |
The build prints the SHA-256 of version.dll. The binary can be inspected
with the included LLVM tools:
Get-FileHash .\out\version.dll -Algorithm SHA256
& .\.tools\llvm-mingw-20260922-ucrt-x86_64\bin\llvm-readobj.exe `
--coff-imports --coff-exports .\out\version.dllMatching hashes confirm identical output only when the source, toolchain, and portable key are identical. A matching hash does not prove the absence of a vulnerability or backdoor. Stronger verification requires source review and a clean independent rebuild.
version.dll runs inside browser processes with the browser's privileges. The
portable hook replaces machine-bound DPAPI output with AES-256-GCM using the
build key. This enables portability but weakens the machine binding of an
unmodified browser installation.
This software is provided as is, without warranty of any kind. Its authors and distributors are not liable for data loss, account loss, incompatibility, security incidents, or any other damage. Back up the profile and test new builds with disposable data first. Use Chromic entirely at your own risk.
Chromic is distributed under GPL-3.0-only. MinHook is distributed under its BSD license.